MODULE moduleTable TYPE:: table1D REAL(8):: xMin, xMax REAL(8):: fMin, fMax REAL(8), ALLOCATABLE, DIMENSION(:):: x, f, k CONTAINS PROCEDURE, PASS:: init => initTable1D PROCEDURE, PASS:: get => getValueTable1D PROCEDURE, PASS:: convert => convertUnits END TYPE table1D CONTAINS SUBROUTINE initTable1D(self, tableFile) USE moduleErrors IMPLICIT NONE CLASS(table1D), INTENT(inout):: self CHARACTER(:), ALLOCATABLE, INTENT(IN):: tableFile CHARACTER(100):: dummy INTEGER:: amount INTEGER:: i INTEGER:: stat INTEGER:: id = 20 OPEN(id, file = tableFile) amount = 0 DO READ(id, '(A)', iostat = stat) dummy !If EOF or error, exit file IF (stat /= 0) EXIT !Skip comment IF (INDEX(dummy,'#') /= 0) CYCLE !Add row amount = amount + 1 END DO IF (amount == 0) CALL criticalError('Table ' // tableFile // ' is empty', 'initTable1D') IF (amount == 1) CALL criticalError('Table ' // tableFile // ' has only one row', 'initTable1D') !Go bback to initial point REWIND(id) !Allocate table arrays ALLOCATE(self%x(1:amount), self%f(1:amount), self%k(1:amount)) self%x = 0.D0 self%f = 0.D0 self%k = 0.D0 i = 0 DO READ(id, '(A)', iostat = stat) dummy !TODO: Make this a function IF (INDEX(dummy,'#') /= 0) CYCLE IF (stat /= 0) EXIT !Add data !TODO: substitute with extracting information from dummy BACKSPACE(id) i = i + 1 READ(id, *) self%x(i), self%f(i) END DO CLOSE(id) self%xMin = self%x(1) self%xMax = self%x(amount) self%fMin = self%f(1) self%fMax = self%f(amount) DO i = 1, amount - 1 self%k(i) = (self%f(i+1) - self%f(i))/(self%x(i+1) - self%x(i)) END DO END SUBROUTINE initTable1D FUNCTION getValueTable1D(self, x) RESULT(f) IMPLICIT NONE CLASS(table1D), INTENT(in):: self REAL(8):: x REAL(8):: f REAL(8):: deltaX INTEGER:: i IF (x <= self%xMin) THEN f = self%fMin ELSEIF (x >= self%xMax) THEN f = self%fMax ELSE i = MINLOC(ABS(x - self%x), 1) deltaX = x - self%x(i) IF (deltaX < 0 ) THEN i = i - 1 deltaX = x - self%x(i) END IF f = self%f(i) + self%k(i)*deltaX END IF END FUNCTION getValueTable1D SUBROUTINE convertUnits(self, data_x, data_f) IMPLICIT NONE CLASS(table1D), INTENT(inout):: self REAL(8):: data_x, data_f self%x = self%x * data_x self%xMin = self%xMin * data_x self%xMax = self%xMax * data_x self%f = self%f * data_f self%fMin = self%fMin * data_f self%fMax = self%fMax * data_f self%k = self%k * data_f / data_x END SUBROUTINE convertUnits END MODULE moduleTable