EFTCAMB  Reference documentation for version 3.0
11_EFTCAMB_stability.f90
Go to the documentation of this file.
1 !----------------------------------------------------------------------------------------
2 !
3 ! This file is part of EFTCAMB.
4 !
5 ! Copyright (C) 2013-2016 by the EFTCAMB authors
6 !
7 ! The EFTCAMB code is free software;
8 ! You can use it, redistribute it, and/or modify it under the terms
9 ! of the GNU General Public License as published by the Free Software Foundation;
10 ! either version 3 of the License, or (at your option) any later version.
11 ! The full text of the license can be found in the file eftcamb/LICENSE at
12 ! the top level of the EFTCAMB distribution.
13 !
14 !----------------------------------------------------------------------------------------
15 
18 
19 
20 !----------------------------------------------------------------------------------------
22 
24 
26 
27  use precision
28  use eft_def
29  use eftcamb_cache
33  use eftcamb_main
34 
35  implicit none
36 
37  private
38 
40 
41  ! storage for some utility values that needs to be stored for the stability check.
42  real(dl), save :: pasta1 = 0._dl
43  real(dl), save :: pastat = 0._dl
44 
45 contains
46 
47  ! ---------------------------------------------------------------------------------------------
50  subroutine eftcamb_stability_check( success, input_EFTCAMB, params_cache, astart, aend, k_max )
51 
52  implicit none
53 
54  logical , intent(out) :: success
55  class(eftcamb) , intent(in) :: input_EFTCAMB
56  type(eftcamb_parameter_cache), intent(inout) :: params_cache
57  real(dl) , intent(in) :: astart
58  real(dl) , intent(in) :: aend
59  real(dl) , intent(inout) :: k_max
60 
61  ! parameters of the stability sampler:
62  integer , parameter :: indMax = 10000 ! Number of points sampled.
63  real(dl), parameter :: LogSamplingScale = -10._dl ! Where to start with the log sampling
64 
65  real(dl) :: Atest, y
66  integer :: ind
67 
68  ! 0) initial feedback:
69  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) then
70  write(*,'(a)') '***************************************************************'
71  write(*,'(a)') ' EFTCAMB: checking stability of the theory'
72  end if
73  if ( input_eftcamb%EFTCAMB_feedback_level > 2 ) then
74  write(*,'(a)')
75  end if
76 
77  ! 1) stability code:
78  success = .true.
79 
80  ! - linear sampling:
82  do ind=1, indmax
83  atest = astart + REAL(ind-1)*(aend-astart)/REAL(indmax-1)
84  success = eftteststability( atest, k_max, input_eftcamb, params_cache )
85  if ( .not. success ) then
86  if ( input_eftcamb%EFTCAMB_feedback_level > 2 ) then
87  write(*,*)
88  write(*,'(a,E14.4)') ' Instability detected at a =', atest
89  end if
90  return
91  end if
92  end do
93 
94  ! - log sampling close to astart:
96  do ind=1, indmax
97  y = logsamplingscale + REAL(ind-1)*(0._dl-logsamplingscale)/REAL(indmax-1)
98  atest = astart +(aend-astart)*10._dl**y
99  success = eftteststability( atest, k_max, input_eftcamb, params_cache )
100  if ( .not. success ) then
101  if ( input_eftcamb%EFTCAMB_feedback_level > 2 ) then
102  write(*,*)
103  write(*,'(a,E14.4)') ' Instability detected at a =', atest
104  end if
105  return
106  end if
107  end do
108 
109  ! - log sampling close to aend:
110  call eftstability_cleanup()
111  do ind=1, indmax
112  atest = aend +(astart-aend)*10._dl**y
113  success = eftteststability( atest, k_max, input_eftcamb, params_cache )
114  if ( .not. success ) then
115  if ( input_eftcamb%EFTCAMB_feedback_level > 2 ) then
116  write(*,*)
117  write(*,'(a,E14.4)') ' Instability detected at a =', atest
118  end if
119  return
120  end if
121  end do
122 
123  ! 2) final feedback:
124  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) then
125  write(*,'(a)') ' EFTCAMB: theory stable'
126  end if
127 
128  end subroutine eftcamb_stability_check
129 
130  ! ---------------------------------------------------------------------------------------------
132  function eftteststability( a, k_max, input_EFTCAMB, params_cache )
134  implicit none
135 
136  real(dl) , intent(in) :: a
137  real(dl) , intent(inout) :: k_max
138  class(eftcamb) , intent(in) :: input_EFTCAMB
139  type(eftcamb_parameter_cache), intent(inout) :: params_cache
140  logical :: EFTTestStability
141 
142  ! Definitions of variables:
143  type(eftcamb_timestep_cache ) :: eft_cache
144  logical :: EFT_HaveNan_parameter, EFT_HaveNan_timestep
145  real(dl) :: EFT_instability_rate, tempk, temp1, temp2, temp3, temp4, temp5
146  integer :: ind_max, ind
147 
148  ! Stability check initialization
149  eftteststability = .true.
150  ! reset the time-step cache:
151  call eft_cache%initialize()
152  ! fill it:
153  call eftstabilitycomputation( a, input_eftcamb%model, params_cache, eft_cache )
154  ! protect against k_max too small:
155  if ( k_max < 0.1_dl ) k_max = 0.1_dl
156 
157  ! check stability of the theory:
158 
159  ! 1) everything inside the parameter cache should not be a NaN:
160  call params_cache%is_nan( eft_havenan_parameter )
161  if ( eft_havenan_parameter ) then
162  eftteststability = .false.
163  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Model has Nan in the parameter cache'
164  return
165  end if
166  ! 2) everything inside the time-step cache should not be a NaN:
167  call eft_cache%is_nan( eft_havenan_timestep )
168  if ( eft_havenan_timestep ) then
169  eftteststability = .false.
170  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Model has Nan in the timestep cache'
171  return
172  end if
173  ! 3) enforce mathematical stability:
174  if ( input_eftcamb%EFT_mathematical_stability ) then
175 
176  ! 1- the A coefficient should not change sign in time and in k, i.e. it shall not be zero.
177  ! This is the strongest stability constraint since violating it would violate the mathematical
178  ! consistency of the pi field equation.
179  ! The first condition is A1/=0. Implemented by detecting sign changes in A1.
180  if ( eft_cache%EFTpiA1*pasta1 < 0._dl ) then
181  eftteststability = .false.
182  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Mathematical instability: A is zero in time'
183  end if
184  pasta1 = eft_cache%EFTpiA1
185  ! The second one is the condition on k.
186  if ( (eft_cache%EFTpiA1 > 0 .and. eft_cache%EFTpiA1 + k_max**2*eft_cache%EFTpiA2 < 0) .or. &
187  &(eft_cache%EFTpiA1 < 0 .and. eft_cache%EFTpiA1 + k_max**2*eft_cache%EFTpiA2 > 0) ) then
188  eftteststability = .false.
189  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Mathematical instability: A is zero in k'
190  end if
191 
192  ! 2- the AT coefficient should not change sign in time, i.e. it shall not be zero.
193  ! This is the second strongest stability constraint since violating it would
194  ! violate the mathematical consistency of the tensor perturbation equation.
195  ! Implemented by detecting sign changes in AT.
196  if ( eft_cache%EFTAT*pastat < 0._dl ) then
197  eftteststability = .false.
198  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Mathematical instability: AT is zero in time'
199  end if
200  pastat = eft_cache%EFTAT
201 
202  ! 3- we do not want (fast) growing exponential modes.
203  ! This condition prevents the pi field from growing exponentially and destroying everything.
204  ! Even though this condition is neither completely related to physics nor mathematics,
205  ! violating it would completely mess up cosmological observables.
206 
207  ! This is the maximum allowed rate of instability. Units shall be Mpc^-1.
208  eft_instability_rate = 0._dl
209 
210  ! This condition needs to be tested in k. Sample in k.
211  ind_max = 10
212 
213  do ind = 1, ind_max
214  ! kmode to test. Linear sampling. Should suffice... (??)
215  tempk = 0._dl + REAL(ind-1)*(k_max)/REAL(ind_max-1)
216  ! vaule that discriminates between different cases:
217  temp1 = (eft_cache%EFTpiB1 +eft_cache%EFTpiB2*tempk**2)
218  temp2 = (eft_cache%EFTpiA1 +eft_cache%EFTpiA2*tempk**2)
219  temp3 = temp1**2 -4._dl*temp2*(eft_cache%EFTpiC +eft_cache%EFTpiD1*tempk**2 + eft_cache%EFTpiD2*tempk**4)
220 
221  ! case 1:
222  if ( temp3 > 0._dl .and. temp2 /= 0._dl ) then
223  temp4 = +0.5_dl*(-temp1 +sqrt(temp3))/temp2
224  temp5 = +0.5_dl*(-temp1 -sqrt(temp3))/temp2
225  if ( temp4>eft_instability_rate .or. temp5>eft_instability_rate ) then
226  eftteststability = .false.
227  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) then
228  write(*,'(a,E11.4)') ' Mathematical instability: growing exponential at k =', tempk
229  write(*,'(a,E11.4,E11.4)') ' Rate of instability: ', temp4, temp5
230  end if
231  exit
232  end if
233  ! case 2:
234  else if ( temp2 /= 0._dl ) then
235  temp4 = -0.5_dl*temp1/temp2
236  if ( temp4>eft_instability_rate ) then
237  eftteststability = .false.
238  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) then
239  write(*,'(a,E11.4)') ' Mathematical instability: growing exponential at k =', tempk
240  write(*,'(a,E11.4,E11.4)') ' Rate of instability: ', temp4
241  end if
242  exit
243  end if
244  end if
245 
246  end do
247 
248  end if
249  ! 4) enforce model specific priors:
250  if ( input_eftcamb%EFT_additional_priors ) then
251  eftteststability = input_eftcamb%model%additional_model_stability( a, params_cache, eft_cache )
252  if ( .not. eftteststability ) then
253  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a)') ' Model specific stability criteria are not met'
254  end if
255  end if
256  ! 5) enforce physical viability:
257  if ( input_eftcamb%EFT_physical_stability ) then
258 
259  ! the present conditions extend up to Horndeski. Enforce that:
260  if ( (eft_cache%EFTGamma6V /= 0._dl) .or. &
261  & ( (eft_cache%EFTGamma3V + eft_cache%EFTGamma4V) /= 0._dl) ) then
262  write(*,'(a)') ' EFTCAMB WARNING: stability for model beyond GLPV has not been worked out.'
263  write(*,'(a)') ' It will be added in a future release.'
264  write(*,'(a)') ' If you want to run this model disable EFT_physical_stability.'
265  eftteststability = .false.
266  return
267  end if
268 
269  ! 1- Positive gravitational constant:
270  if ( 1._dl +eft_cache%EFTOmegaV <= 0 ) then
271  eftteststability = .false.
272  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a,E11.4)') ' Physical instability: negative gravitational constant = ', 1._dl +eft_cache%EFTOmegaV
273  end if
274 
275  ! 2- Ghost condition:
276  if ( eft_cache%EFT_kinetic < 0._dl ) then
277  eftteststability = .false.
278  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a,E11.4)') ' Physical instability: ghost instability. Kinetic term = ', eft_cache%EFT_kinetic
279  end if
280 
281  ! 3- Gradient instability:
282  if ( eft_cache%EFT_gradient < 0._dl ) then
283  eftteststability = .false.
284  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a,E11.4)') ' Physical instability: gradient instability. Gradient term = ', eft_cache%EFT_gradient
285  end if
286 
287  ! 4- No tensor ghosts:
288  if ( eft_cache%EFTAT < 0 ) then
289  eftteststability = .false.
290  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a,E11.4)') ' Physical instability: tensor ghost instability. Tensor kinetic term = ', eft_cache%EFTAT
291  end if
292 
293  ! 5- No tensor gradient:
294  if ( eft_cache%EFTDT < 0 ) then
295  eftteststability = .false.
296  if ( input_eftcamb%EFTCAMB_feedback_level > 1 ) write(*,'(a,E11.4)') ' Physical instability: tensor gradient instability. Tensor gradient term = ', eft_cache%EFTDT
297  end if
298 
299  end if
300 
301  end function eftteststability
302 
303  ! ---------------------------------------------------------------------------------------------
306  subroutine eftstability_cleanup()
308  implicit none
309 
310  pasta1 = 0._dl
311  pastat = 0._dl
312 
313  end subroutine eftstability_cleanup
314 
315  ! ---------------------------------------------------------------------------------------------
317  subroutine eftstabilitycomputation( a, input_model, params_cache, eft_cache )
319  implicit none
320 
321  real(dl), intent(in) :: a
322  class(eftcamb_model) , intent(in) :: input_model
323  type(eftcamb_parameter_cache), intent(inout) :: params_cache
324  type(eftcamb_timestep_cache ), intent(inout) :: eft_cache
325 
326  ! Definitions of variables:
327  real(dl) :: grhonu, gpinu, grhormass_t, grhonudot, gpinudot
328  integer :: nu_i, ind, ind_max
329 
330  ! start filling the cache:
331  eft_cache%a = a
332  ! compute background densities of different species
333  eft_cache%grhob_t = params_cache%grhob/a ! 8\pi G_N \rho_b a^2: baryons background density
334  eft_cache%grhoc_t = params_cache%grhoc/a ! 8\pi G_N \rho_{cdm} a^2: cold dark matter background density
335  eft_cache%grhor_t = params_cache%grhornomass/a/a ! 8\pi G_N \rho_{\nu} a^2: massless neutrinos background density
336  eft_cache%grhog_t = params_cache%grhog/a/a ! 8\pi G_N \rho_{\gamma} a^2: radiation background density
337  ! Massive neutrinos terms:
338  if ( params_cache%Num_Nu_Massive /= 0 ) then
339  do nu_i = 1, params_cache%Nu_mass_eigenstates
340  grhonu = 0._dl
341  gpinu = 0._dl
342  grhormass_t = params_cache%grhormass(nu_i)/a**2
343  call params_cache%Nu_background(a*params_cache%nu_masses(nu_i), grhonu, gpinu )
344  eft_cache%grhonu_tot = eft_cache%grhonu_tot +grhormass_t*grhonu
345  eft_cache%gpinu_tot = eft_cache%gpinu_tot +grhormass_t*gpinu
346  end do
347  end if
348  ! assemble total densities and pressure:
349  eft_cache%grhom_t = eft_cache%grhob_t +eft_cache%grhoc_t +eft_cache%grhor_t +eft_cache%grhog_t +eft_cache%grhonu_tot
350  eft_cache%gpresm_t = (+eft_cache%grhor_t +eft_cache%grhog_t)/3._dl +eft_cache%gpinu_tot
351  ! compute the other things:
352  select type ( model_temp => input_model )
353  ! compute the background and the background EFT functions.
354  class is ( eftcamb_full_model )
355  ! background for full models. Here the expansion history is computed from the
356  ! EFT functions. Hence compute them first and then compute the expansion history.
357  call input_model%compute_background_EFT_functions( a, params_cache , eft_cache )
358  call input_model%compute_adotoa( a, params_cache , eft_cache )
359  class is ( eftcamb_designer_model )
360  ! background for designer models. Here the expansion history is parametrized
361  ! and does not depend on the EFT functions. Hence compute first the expansion history
362  ! and then the EFT functions.
363  call input_model%compute_adotoa( a, params_cache , eft_cache )
364  end select
365  ! compute massive neutrinos stuff:
366  ! Massive neutrinos mod:
367  if ( params_cache%Num_Nu_Massive /= 0 ) then
368  do nu_i = 1, params_cache%Nu_mass_eigenstates
369  grhonu = 0._dl
370  gpinu = 0._dl
371  grhonudot = 0._dl
372  gpinudot = 0._dl
373  grhormass_t = params_cache%grhormass(nu_i)/a**2
374  call params_cache%Nu_background( a*params_cache%nu_masses(nu_i), grhonu, gpinu )
375  eft_cache%grhonu_tot = eft_cache%grhonu_tot + grhormass_t*grhonu
376  eft_cache%gpinu_tot = eft_cache%gpinu_tot + grhormass_t*gpinu
377  eft_cache%grhonudot_tot = eft_cache%grhonudot_tot + grhormass_t*( params_cache%Nu_drho(a*params_cache%nu_masses(nu_i) ,eft_cache%adotoa, grhonu)&
378  & -4._dl*eft_cache%adotoa*grhonu)
379  eft_cache%gpinudot_tot = eft_cache%gpinudot_tot + grhormass_t*( params_cache%Nu_pidot(a*params_cache%nu_masses(nu_i),eft_cache%adotoa, gpinu )&
380  & -4._dl*eft_cache%adotoa*gpinu)
381  end do
382  end if
383  ! compute pressure dot:
384  eft_cache%gpresdotm_t = -4._dl*eft_cache%adotoa*( eft_cache%grhog_t +eft_cache%grhor_t )/3._dl +eft_cache%gpinudot_tot
385  ! compute remaining quantities related to H:
386  call input_model%compute_H_derivs( a, params_cache , eft_cache )
387  ! compute backgrond EFT functions if model is designer:
388  select type ( model_temp => input_model )
389  class is ( eftcamb_designer_model )
390  call input_model%compute_background_EFT_functions( a, params_cache , eft_cache )
391  end select
392  ! compute all other background stuff:
393  call input_model%compute_rhoQPQ( a, params_cache , eft_cache )
394  ! compute second order EFT functions:
395  call input_model%compute_secondorder_EFT_functions( a, params_cache , eft_cache )
396  ! Compute pi field equations factors:
397  call input_model%compute_pi_factors( a, params_cache , eft_cache )
398  ! Compute coefficients for the tensor propagation equation:
399  call input_model%compute_tensor_factors( a, params_cache , eft_cache )
400  ! Compute kinetic and gradient terms:
401  call input_model%compute_stability_factors( a, params_cache , eft_cache )
402 
403  end subroutine eftstabilitycomputation
404 
405  !----------------------------------------------------------------------------------------
406 
407 end module eftcamb_stability
408 
409 !----------------------------------------------------------------------------------------
This module contains the definition of the EFTCAMB caches. These are used to store parameters that ca...
This module contains the abstract definition of all the places where EFTCAMB interacts with CAMB...
subroutine, public eftstabilitycomputation(a, input_model, params_cache, eft_cache)
Subroutine that fills the caches to check the stability of the theory.
This module contains the stability detection algorithm of EFTCAMB.
subroutine, public eftstability_cleanup()
Subroutine that restores the values stored in the module to the default. Needed for successive calls...
This module contains the abstract definition of all the places where EFTCAMB interacts with CAMB in c...
This module contains the abstract definition of all the places where EFTCAMB interacts with CAMB in c...
This module contains the definitions of all the EFTCAMB compile time flags.
Definition: 01_EFT_def.f90:25
logical function, public eftteststability(a, k_max, input_EFTCAMB, params_cache)
Function that fills the caches to check the stability of the theory.
This module contains the general EFTCAMB driver. We have a type that encapsulate all EFTCAMB paramete...
subroutine, public eftcamb_stability_check(success, input_EFTCAMB, params_cache, astart, aend, k_max)
Subroutine that tests the stability of a theory in a time range. To ensure best time coverage scans w...