! ! This file is part of SACAMOS, State of the Art CAble MOdels for Spice. ! It was developed by the University of Nottingham and the Netherlands Aerospace ! Centre (NLR) for ESA under contract number 4000112765/14/NL/HK. ! ! Copyright (C) 2016-2018 University of Nottingham ! ! SACAMOS is free software: you can redistribute it and/or modify it under the ! terms of the GNU General Public License as published by the Free Software ! Foundation, either version 3 of the License, or (at your option) any later ! version. ! ! SACAMOS is distributed in the hope that it will be useful, but ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ! for more details. ! ! A copy of the GNU General Public License version 3 can be found in the ! file GNU_GPL_v3 in the root or at . ! ! SACAMOS uses the EISPACK library (in /SRC/EISPACK). EISPACK is subject to ! the GNU Lesser General Public License. A copy of the GNU Lesser General Public ! License version can be found in the file GNU_LGPL in the root of EISPACK ! (/SRC/EISPACK ) or at . ! ! The University of Nottingham can be contacted at: ggiemr@nottingham.ac.uk ! ! ! File Contents: ! MODULE frequency_spec ! SUBROUTINE read_and_set_up_frequency_specification ! SUBROUTINE reset_frequency_specification ! SUBROUTINE set_up_frequency_specification ! SUBROUTINE deallocate_frequency_specification ! ! NAME ! frequency_spec ! ! AUTHORS ! Chris Smartt ! ! DESCRIPTION ! Module to deal with all aspects of frequency range specifications ! The module defines a struncture for a frequency range ! subroutine to read a frequency specification and set up the structure ! subroutine to reset the frequency_specification ! subroutine to set up the frequency_specification ! subroutine to deallocate the frequency_specification ! ! COMMENTS ! ! ! HISTORY ! ! started 22/08/2016 CJS ! Add some checks etc for robustness 15/12/2016 CJS ! ! MODULE frequency_spec USE type_specifications IMPLICIT NONE TYPE :: frequency_specification character(LEN=3):: freq_range_type ! frequency range type, 'log' or 'lin' real(dp) :: fmin ! minimum frequency real(dp) :: fmax ! maximum frequency integer :: n_frequencies ! number of frequencies real(dp),allocatable ::freq_list(:)! list of frequencies END TYPE frequency_specification CONTAINS ! NAME ! read_and_set_up_frequency_specification ! ! AUTHORS ! Chris Smartt ! ! DESCRIPTION ! Set up frequency range specifications based on information read from file ! ! COMMENTS ! ! ! HISTORY ! ! started 22/08/2016 CJS ! SUBROUTINE read_and_set_up_frequency_specification(freq_data,unit) USE general_module IMPLICIT NONE ! variables passed to subroutine TYPE(frequency_specification),intent(INOUT) :: freq_data integer,intent(IN) :: unit ! local variables real(dp) :: fstep ! frequency step real(dp) :: log_fmin ! log of minimum frequency real(dp) :: log_fmax ! log of maximum frequency real(dp) :: log_fstep ! log of frequency step real(dp) :: log_f ! log of frequency integer :: ierr ! START read(unit,'(A3)',IOSTAT=ierr)freq_data%freq_range_type if (ierr.NE.0) then run_status='ERROR reading .spice_model_spec file: '// & 'The frequency range type needs to be specified (log or lin)' CALL write_program_status() STOP 1 end if read(unit,*,IOSTAT=ierr)freq_data%fmin, & freq_data%fmax, & freq_data%n_frequencies if (ierr.NE.0) then run_status='ERROR: reading .spice_model_spec file: '// & 'The frequency range needs to be specified (fmin fmax n_frequenceis)' CALL write_program_status() STOP 1 end if ! Some checks that the specified frequency range is sensible if (freq_data%fmin.LT.0d0) then run_status='ERROR: read_and_set_up_frequency_specification. fmin < 0' CALL write_program_status() STOP 1 end if if (freq_data%fmax.LT.freq_data%fmin) then run_status='ERROR: read_and_set_up_frequency_specification. fmax < fmin' CALL write_program_status() STOP 1 end if if (freq_data%n_frequencies.LT.0d01) then run_status='ERROR: read_and_set_up_frequency_specification. number of frequencies < 1' CALL write_program_status() STOP 1 end if CALL set_up_frequency_specification(freq_data) RETURN END SUBROUTINE read_and_set_up_frequency_specification ! ! NAME ! reset_frequency_specification ! ! AUTHORS ! Chris Smartt ! ! DESCRIPTION ! reset frequency range specifications ! ! COMMENTS ! ! ! HISTORY ! ! started 15/12/2016 CJS ! SUBROUTINE reset_frequency_specification(freq_data) IMPLICIT NONE ! variables passed to subroutine TYPE(frequency_specification),intent(INOUT) :: freq_data ! local variables ! START freq_data%freq_range_type='lin' freq_data%fmin=0d0 freq_data%fmax=0d0 freq_data%n_frequencies=1 RETURN END SUBROUTINE reset_frequency_specification ! ! NAME ! set_up_frequency_specification ! ! AUTHORS ! Chris Smartt ! ! DESCRIPTION ! Set up frequency range specifications i.e. given the frequency range specification, ! allocate and set the frequency list array. ! ! COMMENTS ! ! ! HISTORY ! ! started 22/08/2016 CJS ! 16/09/2016 CJS process separated from read_and_set_up_frequency_specification ! SUBROUTINE set_up_frequency_specification(freq_data) USE general_module IMPLICIT NONE ! variables passed to subroutine TYPE(frequency_specification),intent(INOUT) :: freq_data ! local variables real(dp) :: fstep ! frequency step real(dp) :: log_fmin ! log of minimum frequency real(dp) :: log_fmax ! log of maximum frequency real(dp) :: log_fstep ! log of frequency step real(dp) :: log_f ! log of frequency integer :: floop ! frequency loop variable integer :: ierr ! START if (freq_data%freq_range_type.EQ.'log') then log_fmin=log10(freq_data%fmin) log_fmax=log10(freq_data%fmax) log_fstep=0d0 ! this is the value used if freq_data%n_frequencies=1 if (freq_data%n_frequencies.ne.1) then log_fstep=(log_fmax-log_fmin)/dble(freq_data%n_frequencies-1) end if else if (freq_data%freq_range_type.EQ.'lin') then fstep=0d0 ! this is the value used if freq_data%n_frequencies=1 if (freq_data%n_frequencies.ne.1) then fstep=(freq_data%fmax-freq_data%fmin)/dble(freq_data%n_frequencies-1) end if else run_status='ERROR in set_up_frequency_specification: frequency range type should be log or lin' CALL write_program_status() STOP 1 end if if ( ALLOCATED(freq_data%freq_list) ) CALL deallocate_frequency_specification(freq_data) ALLOCATE(freq_data%freq_list(1:freq_data%n_frequencies)) do floop=1,freq_data%n_frequencies if (freq_data%freq_range_type.EQ.'log') then log_f=log_fmin+(floop-1)*log_fstep freq_data%freq_list(floop)=10d0**(log_f) else if (freq_data%freq_range_type.EQ.'lin') then freq_data%freq_list(floop)=freq_data%fmin+(floop-1)*fstep end if end do ! next frequency END SUBROUTINE set_up_frequency_specification ! NAME ! deallocate_frequency_specification ! ! AUTHORS ! Chris Smartt ! ! DESCRIPTION ! deallocate the frequency range specification ! ! COMMENTS ! ! ! HISTORY ! ! started 22/08/2016 CJS ! SUBROUTINE deallocate_frequency_specification(freq_data) IMPLICIT NONE ! variables passed to subroutine TYPE(frequency_specification),intent(INOUT) :: freq_data ! START if (ALLOCATED(freq_data%freq_list)) DEALLOCATE(freq_data%freq_list) END SUBROUTINE deallocate_frequency_specification END MODULE frequency_spec