subroutine signal_init(me, sim, input_cfg, key, x)
class(signal_t), intent(inout) :: me
type(simulation_t), target, intent(inout) :: sim
type(input_t), intent(in) :: input_cfg
character(*), intent(in) :: key
real(dp), optional, intent(in) :: x(:)
logical :: explicit
type(input_t) :: cfg
integer :: len_int,i,j,repeat_idx,order
real(dp) :: delta
real(dp), allocatable :: x_in(:),y_out(:,:)
character(:), allocatable :: event
character(:), allocatable :: init_str
type(str_ptr), allocatable :: keys(:)
! if(.not. input_cfg%has_key(key)) ! TODO by Jacek????
me%sim => sim
me%x = [0._dp]
if (present(x)) me%x = x
me%time = [-huge(0.0_dp), huge(0.0_dp)]
me%gain = spread([0._dp], 1, size(me%x))
me%offset = spread([0._dp], 1, size(me%x))
if (.not.input_cfg%has_key(key)) return
me%offset = spread([input_cfg%dbl(key,ieee_value(delta, ieee_quiet_nan))], &
1, size(me%x))
if(.not.is_nan(me%offset(1,1))) return
me%offset(:,1) = input_cfg%dbl1d(key,me%offset(:,1))
if(.not.is_nan(me%offset(1,1))) return
cfg = input_cfg%dict(key)
init_str=cfg%str('external','')
do i = 1, size(lib_handles)
me%init_signal_ext_ptr = GetProcAddress(lib_handles(i),init_str // c_null_char)
if (c_associated(me%init_signal_ext_ptr)) then
call c_f_procpointer(me%init_signal_ext_ptr, me%init_signal_ext)
exit
endif
enddo
if(associated(me%init_signal_ext)) then
! serialization
keys = cfg%keys1d()
me%cfg_str = ''
do i = 1, size(keys)
me%cfg_str = me%cfg_str // keys(i)%p // c_null_char // cfg%str(keys(i)%p) // c_null_char
end do
return
endif
repeat_idx = cfg%int('repeat',0)
order = cfg%int('order',0)
event = cfg%str('event','no')
if(cfg%has_key('time')) then
me%time = cfg%dbl1d('time')
if (present(x)) then
me%offset = cfg%dbl2d('value')
else
me%offset = reshape(cfg%dbl1d('value'),[1,size(me%time)])
endif
else
allocate(y_out(size(x),1))
call interpolate_vector(cfg%dbl1d('x'),cfg%dbl1d('value'),x,y_out(:,1))
me%offset = y_out
return
endif
if(cfg%has_key('x').and.cfg%has_key('time')) then
x_in = cfg%dbl1d('x')
allocate(y_out(size(me%x),size(me%offset,2)))
do i = 1, size(me%offset,2)
call interpolate_vector(x_in,me%offset(:,i),me%x,y_out(:,i))
enddo
me%offset = y_out
endif
! Handling repeated time series
if(repeat_idx>0) then
do while(me%time(size(me%time))<=me%sim%t_final)
len_int = size(me%time)
delta = me%time(len_int) + me%time(repeat_idx)
me%time = [me%time, me%time( repeat_idx:len_int) + delta]
me%offset = reshape([me%offset, me%offset(:,repeat_idx:len_int)], &
[size(me%x),size(me%time)])
enddo
endif
len_int = size(me%time)
me%time = [me%time, huge(0._dp)]
me%gain = spread(me%gain(:,1),2,len_int)
! Handling the order of interpolation
if(order == 1) then
do j = 1,size(me%x)
me%gain(j,1:len_int-1) = [((me%offset(j,i+1) - &
me%offset(j,i))/(me%time(i+1) - me%time(i)), i=1, len_int-1)]
me%gain(j,len_int) = me%gain(j,len_int-1)
me%offset(j,:) = me%offset(j,:) - (me%gain(j,:) * me%time(1:len_int))
enddo
endif
! Adding events to list
if (event == 'explicit') then; explicit = .true.
elseif (event == 'implicit') then; explicit = .false.
else; return
endif
call merge_events(me%sim%events_time, me%sim%events_expl, me%time, explicit)
end subroutine signal_init