Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
constants_and_conversions.F90
Go to the documentation of this file.
1!> @file
2!! Contains a single module, @ref constants_and_conversions, which contains useful
3!! physical constants and basic conversion utilities
4
5!> This module contains physical constants and convenience functions aimed at
6!! performing unit conversions. The functions included in this module perform
7!! conversions between various temperature and distance units.
9
10 use iso_c_binding, only : c_short, c_int, c_long, c_float, c_double, c_bool, &
11 c_long_long
12 implicit none
13
14 !
15 integer (c_int), parameter :: datatype_int = 0
16 integer (c_int), parameter :: datatype_float = 1
17 integer (c_int), parameter :: datatype_real = 1
18 integer (c_int), parameter :: datatype_double = 2
19 integer (c_int), parameter :: datatype_short = 3
20 integer (c_int), parameter :: datatype_na = -9999
21
22 ! [ common mathematical constants ]
23 public :: pi, twopi, halfpi
24 real (c_double), parameter :: pi = 4.0_c_double*atan(1.0_c_double)
25 real (c_double), parameter :: twopi = pi * 2.0_c_double
26 real (c_double), parameter :: halfpi = pi / 2.0_c_double
27
28 ! [ trig conversion factors ]
30 real (c_double), parameter :: degrees_to_radians = twopi / 360.0_c_double
31 real (c_double), parameter :: radians_to_degrees = 360.0_c_double / twopi
32
33 ! [ common 'magic' numbers and logicals ]
34 public :: true, false
36 public :: rfreezing, dfreezing, near_zero
37 public :: rzero
38 logical (c_bool), parameter :: true = .true._c_bool
39 logical (c_bool), parameter :: false = .false._c_bool
40
41 real (c_float), parameter :: near_zero = epsilon(1.0_c_float)
42 real (c_float), parameter :: rbigval = huge(0.0_c_float)
43 real (c_double), parameter :: dbigval = huge(0.0_c_double)
44 integer(c_int), parameter :: ibigval = huge(0_c_int)
45 real (c_float), parameter :: rtinyval = -(huge(0.0_c_float) - 1.0)
46 real (c_double), parameter :: dtinyval = -(huge(0.0_c_double) - 1.0)
47 real (c_float), parameter :: ftinyval = -(huge(0.0_c_float) - 1.0)
48 integer(c_int), parameter :: itinyval = -(huge(0_c_int) - 1)
49 real (c_float), parameter :: rfreezing = 32.0_c_float
50 real (c_float), parameter :: ffreezing = 32.0_c_float
51 real (c_double), parameter :: dfreezing = 32.0_c_double
52 integer (c_int), parameter :: izero = 0_c_int
53 real (c_float), parameter :: fzero = 0.0_c_float
54 real (c_float), parameter :: rzero = 0.0_c_float
55 real (c_double), parameter :: dzero = 0.0_c_double
56
57 ! [ evil global variables ]
58 character (len=1) :: os_native_path_delimiter
59 integer (c_int) :: random_start = 0
60
61 ! [ select conversion factors ]
62 real (c_double), parameter, public :: c_per_f = 5.0_c_double / 9.0_c_double
63 real (c_double), parameter, public :: f_per_c = 9.0_c_double / 5.0_c_double
64 real (c_double), parameter, public :: m_per_foot = 0.3048_c_double
65 real (c_double), parameter, public :: mm_per_in = 25.4_c_double
66 real (c_double), parameter, public :: freezing_point_of_water_kelvin = 273.15_c_double
67 real (c_double), parameter, public :: freezing_point_of_water_fahrenheit = 32.0_c_double
68
71 character (len=:), allocatable :: output_directory_name
72 character (len=:), allocatable :: output_prefix_name
73 character (len=:), allocatable :: data_directory_name
74 character (len=:), allocatable :: lookup_table_directory_name
75
77 character (len=:), allocatable :: sproj4_string
78 integer (c_int) :: inumcols
79 integer (c_int) :: inumrows
80 real (c_double) :: fx_ll, fy_ll
81 real (c_double) :: fx_ur, fy_ur
82 real (c_double) :: fgridcellsize
83 end type bounds_t
84
85 type (bounds_t), public :: bnds
86
87 public :: operator(.approxequal.)
88 interface operator(.approxequal.)
89 module procedure approx_equal_float_float
90 module procedure approx_equal_double_double
91 module procedure approx_equal_float_double
92 end interface operator(.approxequal.)
93
94
95
96 !> establish generic interfaces to single and double precision functions
97 public :: c_to_f
98 interface c_to_f
99 module procedure ctof_sgl_fn
100 module procedure ctof_dbl_fn
101 end interface c_to_f
102
103 public f_to_c
104 interface f_to_c
105 module procedure ftoc_sgl_fn
106 module procedure ftoc_dbl_fn
107 end interface f_to_c
108
109 public :: f_to_k
110 interface f_to_k
111 module procedure ftok_sgl_fn
112 module procedure ftok_dbl_fn
113 end interface f_to_k
114
115 public :: c_to_k
116 interface c_to_k
117 module procedure ctok_sgl_fn
118 module procedure ctok_dbl_fn
119 end interface c_to_k
120
121 public :: deg_to_rad
122 interface deg_to_rad
123 module procedure deg_to_rad_sgl_fn
124 module procedure deg_to_rad_dbl_fn
125 end interface deg_to_rad
126
127 public :: rad_to_deg
128 interface rad_to_deg
129 module procedure rad_to_deg_sgl_fn
130 module procedure rad_to_deg_dbl_fn
131 end interface rad_to_deg
132
133 public :: asfloat
134 interface asfloat
135 module procedure char2real
136 module procedure short2real
137 module procedure int2real
138 module procedure dbl2real
139 module procedure bool2real
140 end interface asfloat
141
142 public :: asdouble
143 interface asdouble
144 module procedure char2dbl
145 module procedure short2dbl
146 module procedure int2dbl
147 module procedure real2dbl
148 module procedure bool2dbl
149 end interface asdouble
150
151 public asint
152 interface asint
153 module procedure short2int
154 module procedure char2int
155 module procedure real2int
156 module procedure dbl2int
157 module procedure bool2int
158 end interface asint
159
160 public aslogical
161 interface aslogical
162 module procedure short2logical
163 module procedure int2logical
164 module procedure real2logical
165 module procedure dbl2logical
166 module procedure char2logical
167 end interface aslogical
168
169 public :: mm_to_in
170 interface mm_to_in
171 module procedure mm_to_inches_sgl_fn
172 module procedure mm_to_inches_dbl_fn
173 end interface mm_to_in
174
175 public :: in_to_mm
176 interface in_to_mm
177 module procedure inches_to_mm_sgl_fn
178 module procedure inches_to_mm_dbl_fn
179 end interface in_to_mm
180
181 public :: clip
182 interface clip
183 module procedure enforce_bounds_int_fn
184 module procedure enforce_bounds_sgl_fn
185 module procedure enforce_bounds_dbl_fn
186 end interface clip
187
189 public :: c_to_fortran_string
190 public :: fortran_to_c_string
191 public :: is_numeric
192
193 real (c_float), parameter :: tolerance_float = 1.0e-6_c_float
194 real (c_double), parameter :: tolerance_double = 1.0e-9_c_double
195
196contains
197
198 function fix_pathname( input_pathname ) result( output_pathname )
199
200 character (len=*), intent(in) :: input_pathname
201 character (len=len_trim(input_pathname)) :: output_pathname
202
203 ! [ LOCALS ]
204 integer (c_int) :: indx, jndx
205
206 do indx=1,len_trim(input_pathname)
207
208 jndx = min( indx+1, len_trim(input_pathname) )
209 ! allow for escaping of spaces in pathnames
210 if ( ( (input_pathname(indx:indx) == '/') &
211 .or. (input_pathname(indx:indx) == '\') ) &
212 .and. (input_pathname(jndx:jndx) /= ' ' ) ) then
213
214 output_pathname(indx:indx) = os_native_path_delimiter
215
216 else
217
218 output_pathname(indx:indx) = input_pathname(indx:indx)
219
220 endif
221
222 enddo
223
224 end function fix_pathname
225
226
227 elemental function approx_equal_float_float(fValue1, fValue2) result(lBool)
228
229 real (c_float), intent(in) :: fvalue1
230 real (c_float), intent(in) :: fvalue2
231 logical (c_bool) :: lbool
232
233 if ( abs( fvalue1 - fvalue2 ) < tolerance_float ) then
234 lbool = true
235 else
236 lbool = false
237 endif
238
239 end function approx_equal_float_float
240
241
242
243
244 elemental function approx_equal_float_double(fValue1, fValue2) result(lBool)
245
246 real (c_float), intent(in) :: fvalue1
247 real (c_double), intent(in) :: fvalue2
248 logical (c_bool) :: lbool
249
250 if ( abs( fvalue1 - real(fvalue2, c_float) ) < tolerance_float ) then
251 lbool = true
252 else
253 lbool = false
254 endif
255
256 end function approx_equal_float_double
257
258
259
260
261
262 elemental function approx_equal_double_double(fValue1, fValue2) result(lBool)
263
264 real (c_double), intent(in) :: fvalue1
265 real (c_double), intent(in) :: fvalue2
266 logical (c_bool) :: lbool
267
268 if ( abs( fvalue1 - fvalue2 ) < tolerance_double ) then
269 lbool = true
270 else
271 lbool = false
272 endif
273
274 end function approx_equal_double_double
275
276!--------------------------------------------------------------------------
277
278 !> Determine if string contains numeric values.
279 !! @param[in] degrees String value.
280 !! @retval is_numeric True if any numeric values are present in the string.
281
282 impure elemental function is_numeric( value )
283
284 character (len=*), intent(in) :: value
285 logical (c_bool) :: is_numeric
286
287 ! [ LOCALS ]
288 character (len=256) :: sbuf
289
290 sbuf = keepnumeric( value )
291
292 if ( len_trim( sbuf ) == 0 ) then
294 else
296 endif
297
298 end function is_numeric
299
300!--------------------------------------------------------------------------
301
302 !> Convert degrees to radians.
303 !! @param[in] degrees Angle in degrees.
304 !! @retval radians Angle in radians.
305
306 elemental function deg_to_rad_sgl_fn( degrees ) result( radians )
307
308 real (c_float), intent(in) :: degrees
309 real (c_float) :: radians
310
311 radians = real(degrees * degrees_to_radians, c_float)
312
313 end function deg_to_rad_sgl_fn
314
315
316!--------------------------------------------------------------------------------------------------
317
318 !> Convert degrees to radians.
319 !! @param[in] degrees Angle in degrees.
320 !! @retval radians Angle in radians.
321
322 elemental function deg_to_rad_dbl_fn(degrees) result(radians)
323
324 real (c_double), intent(in) :: degrees
325 real (c_double) :: radians
326
327 radians = degrees * degrees_to_radians
328
329 end function deg_to_rad_dbl_fn
330
331
332!--------------------------------------------------------------------------------------------------
333
334 !> Convert radians to degrees.
335 !! @param[in] radians Angle in radians.
336 !! @retval degrees Angle in degrees.
337
338 elemental function rad_to_deg_sgl_fn(radians) result(degrees)
339
340 real (c_float), intent(in) :: radians
341 real (c_float) :: degrees
342
343 degrees = real(radians * radians_to_degrees, c_float)
344
345 end function rad_to_deg_sgl_fn
346
347!--------------------------------------------------------------------------------------------------
348
349 !> Convert radians to degrees.
350 !! @param[in] radians Angle in radians.
351 !! @retval degrees Angle in degrees.
352
353 elemental function rad_to_deg_dbl_fn(radians) result(degrees)
354
355 real (c_double), intent(in) :: radians
356 real (c_double) :: degrees
357
358 degrees = radians * radians_to_degrees
359
360 end function rad_to_deg_dbl_fn
361
362
363!--------------------------------------------------------------------------------------------------
364
365 !> Convert degrees Fahrenheit to degrees Celsius.
366 !! @param[in] degrees_F Temperature in degrees Fahrenheit.
367 !! @retval degrees_C Temperature in degrees Celcius.
368
369 elemental function ftoc_sgl_fn(degrees_F) result(degrees_C)
370
371 real (c_float),intent(in) :: degrees_f
372 real (c_float) :: degrees_c
373
374 degrees_c = real((degrees_f - rfreezing) * c_per_f, c_float)
375
376 end function ftoc_sgl_fn
377
378
379!--------------------------------------------------------------------------------------------------
380
381 !> Convert degrees Fahrenheit to degrees Celsius.
382 !! @param[in] degrees_F Temperature in degrees Fahrenheit.
383 !! @retval degrees_C Temperature in degrees Celcius.
384
385 elemental function ftoc_dbl_fn( degrees_F ) result( degrees_C )
386
387 real (c_double),intent(in) :: degrees_f
388 real (c_double) :: degrees_c
389
390 degrees_c = ( degrees_f - dfreezing ) * c_per_f
391
392 end function ftoc_dbl_fn
393
394
395!--------------------------------------------------------------------------------------------------
396
397 !> Convert degrees Celsius to degrees Fahrenheit.
398 !! @param[in] degrees_C Temperature in degrees Celsius.
399 !! @retval degrees_F Temperature in degrees Fahrenheit.
400
401 elemental function ctof_sgl_fn( degrees_C ) result( degrees_F )
402
403 real (c_float),intent(in) :: degrees_c
404 real (c_float) :: degrees_f
405
406 degrees_f = real(degrees_c * f_per_c + dfreezing, c_float)
407
408 end function ctof_sgl_fn
409
410
411!--------------------------------------------------------------------------------------------------
412
413 !> Convert degrees Celsius to degrees Fahrenheit.
414 !! @param[in] degrees_C Temperature in degrees Celsius.
415 !! @retval degrees_F Temperature in degree
416
417 elemental function ctof_dbl_fn( degrees_C ) result( degrees_F )
418
419 real (c_double),intent(in) :: degrees_c
420 real (c_double) :: degrees_f
421
422 degrees_f = degrees_c * f_per_c + dfreezing
423
424 end function ctof_dbl_fn
425
426
427!--------------------------------------------------------------------------------------------------
428
429 !> Convert degrees Fahrenheit to Kelvins.
430 !! @param[in] degrees_F Temperature in degrees Fahrenheit.
431 !! @retval degrees_K Temperature in Kelvins.
432
433 elemental function ftok_sgl_fn( degrees_F ) result( degrees_K )
434
435 real (c_float),intent(in) :: degrees_f
436 real (c_float) :: degrees_k
437
438 degrees_k = real((degrees_f - dfreezing) * c_per_f + 273.15_c_double, c_float)
439
440 end function ftok_sgl_fn
441
442
443!--------------------------------------------------------------------------------------------------
444
445 !> Convert degrees Fahrenheit to Kelvins.
446 !! @param[in] degrees_F Temperature in degrees Fahrenheit.
447 !! @retval degrees_K Temperature in Kelvins.
448
449 elemental function ftok_dbl_fn( degrees_F ) result( degrees_K )
450
451 real (c_double),intent(in) :: degrees_f
452 real (c_double) :: degrees_k
453
454 degrees_k = (degrees_f - dfreezing) * c_per_f + 273.15_c_double
455
456 end function ftok_dbl_fn
457
458
459!--------------------------------------------------------------------------------------------------
460
461 !> Convert degrees Celsius to Kelvins.
462 !! @param[in] degrees_C Temperature in degrees Celcius.
463 !! @retval degrees_K Temperature in Kelvins.
464
465 elemental function ctok_sgl_fn( degrees_C ) result( degrees_K )
466
467 real (c_float), intent(in) :: degrees_c
468 real (c_float) :: degrees_k
469
470 degrees_k = real(degrees_c + 273.15_c_double, c_float)
471
472 end function ctok_sgl_fn
473
474
475!--------------------------------------------------------------------------------------------------
476
477 !> Convert degrees Fahrenheit to Kelvins.
478 !! @param[in] degrees_C Temperature in degrees Celsius.
479 !! @retval degrees_K Temperature in Kelvins.
480
481 elemental function ctok_dbl_fn( degrees_C ) result( degrees_K )
482
483 real (c_double), intent(in) :: degrees_c
484 real (c_double) :: degrees_k
485
486 degrees_k = degrees_c + 273.15_c_double
487
488 end function ctok_dbl_fn
489
490!--------------------------------------------------------------------------------------------------
491
492 !> Convert inches to mm.
493 !! @param[in] inches Value in inches.
494 !! @retval mm Value in millimeters.
495
496 elemental function inches_to_mm_sgl_fn( inches ) result( mm )
497
498 real (c_float),intent(in) :: inches
499 real (c_float) :: mm
500
501 mm = real(inches * 25.4_c_double, c_float)
502
503 end function inches_to_mm_sgl_fn
504
505!--------------------------------------------------------------------------------------------------
506
507 !> Convert inches to mm.
508 !! @param[in] inches Value in inches.
509 !! @retval mm Value in millimeters.
510
511 elemental function inches_to_mm_dbl_fn( inches ) result( mm )
512
513 real (c_double),intent(in) :: inches
514 real (c_double) :: mm
515
516 mm = inches * 25.4_c_double
517
518 end function inches_to_mm_dbl_fn
519
520!--------------------------------------------------------------------------------------------------
521
522 !> Convert millimeters to inches.
523 !! @param[in] mm Value in millimeters.
524 !! @retval inches Value in inches.
525
526 elemental function mm_to_inches_sgl_fn(mm) result(inches)
527
528 real (c_float),intent(in) :: mm
529 real (c_float) :: inches
530
531 inches = real(mm / 25.4_c_double, c_float)
532
533 end function mm_to_inches_sgl_fn
534
535!--------------------------------------------------------------------------------------------------
536
537 !> Convert millimeters to inches.
538 !! @param[in] mm Value in millimeters.
539 !! @retval inches Value in inches.
540
541 elemental function mm_to_inches_dbl_fn( mm ) result( inches )
542
543 real (c_double),intent(in) :: mm
544 real (c_double) :: inches
545
546 inches = mm / 25.4_c_double
547
548 end function mm_to_inches_dbl_fn
549
550!--------------------------------------------------------------------------------------------------
551
552 !> Convert a short integer to a logical value
553
554 elemental function short2logical(iShortVal) result(lValue)
555
556 integer (c_short), intent(in) :: ishortval
557 logical (c_bool) :: lvalue
558
559 if ( ishortval == 0 ) then
560 lvalue = false
561 else
562 lvalue = true
563 endif
564
565 end function short2logical
566
567!--------------------------------------------------------------------------------------------------
568
569 !> Convert an integer to a logical value
570
571 elemental function int2logical(iValue) result(lValue)
572
573 integer (c_int), intent(in) :: ivalue
574 logical (c_bool) :: lvalue
575
576 if ( ivalue == 0 ) then
577 lvalue = false
578 else
579 lvalue = true
580 endif
581
582 end function int2logical
583
584!--------------------------------------------------------------------------------------------------
585
586 !> Convert a real to a logical value
587
588 elemental function real2logical(rValue) result(lValue)
589
590 real (c_float), intent(in) :: rvalue
591 logical (c_bool) :: lvalue
592
593 ! [ LOCALS ]
594 real (c_float), parameter :: fminresolution = 2.0 * spacing(1.0_c_float)
595
596 if ( rvalue > -fminresolution .and. rvalue < fminresolution ) then
597 lvalue = false
598 else
599 lvalue = true
600 endif
601
602 end function real2logical
603
604!--------------------------------------------------------------------------------------------------
605
606 !> Convert a double to a logical value
607
608 elemental function dbl2logical(rValue) result(lValue)
609
610 real (c_double), intent(in) :: rvalue
611 logical (c_bool) :: lvalue
612
613 ! [ LOCALS ]
614 real (c_double), parameter :: dminresolution = 2.0 * spacing(1.0_c_float)
615
616 if ( rvalue > -dminresolution .and. rvalue < dminresolution ) then
617 lvalue = false
618 else
619 lvalue = true
620 endif
621
622 end function dbl2logical
623
624!--------------------------------------------------------------------------------------------------
625
626 !> Convert a character string to a logical value
627
628 elemental function char2logical(sValue) result(lValue)
629
630 character (len=*), intent(in) :: svalue
631 logical (c_bool) :: lvalue
632
633 select case ( svalue )
634
635 case ( "TRUE", "True", "true", "T", "YES", "Yes", "yes", "1" )
636
637 lvalue = true
638
639 case default
640
641 lvalue = false
642
643 end select
644
645 end function char2logical
646
647!--------------------------------------------------------------------------------------------------
648
649 !> Convert a short integer to an integer
650
651 elemental function short2int(iShortVal) result(iValue)
652
653 integer (c_short), intent(in) :: ishortval
654 integer (c_int) :: ivalue
655
656 ivalue = int( ishortval, c_int )
657
658 end function short2int
659
660!--------------------------------------------------------------------------------------------------
661
662 !> Convert a character value into a integer
663
664 impure elemental function char2int(sValue) result(iValue)
665
666 character (len=*), intent(in) :: svalue
667 integer (c_int) :: ivalue
668
669 ! [ LOCALS ]
670 integer (c_int) :: istat
671 character (len=:), allocatable :: stempval
672 real (c_float) :: rvalue
673
674 stempval = keepnumeric(svalue)
675
676 ! if the cleaned up string appears to be a real value,
677 ! attempt to read as real and convert to int
678 if ( scan(stempval, ".") /= 0 ) then
679
680 read(unit=stempval, fmt=*, iostat=istat) rvalue
681
682 if (istat == 0) ivalue = int(rvalue, c_int)
683
684 else
685
686 read(unit=stempval, fmt=*, iostat=istat) ivalue
687
688 endif
689
690 if (istat /= 0) ivalue = itinyval
691
692 end function char2int
693
694!--------------------------------------------------------------------------------------------------
695
696!> Convert a real value into a integer
697
698elemental function real2int(rValue) result(iValue)
699
700 real (c_float), intent(in) :: rvalue
701 integer (c_int) :: ivalue
702
703 ivalue = int(rvalue, c_int)
704
705end function real2int
706
707!--------------------------------------------------------------------------------------------------
708
709!> Convert a double-precision value to an integer
710
711elemental function dbl2int(rValue) result(iValue)
712
713 real (c_double), intent(in) :: rvalue
714 integer (c_int) :: ivalue
715
716 ivalue = int(rvalue, c_int)
717
718end function dbl2int
719
720!--------------------------------------------------------------------------------------------------
721
722!> Convert a boolean value into a int
723elemental pure function bool2int(lValue) result(iValue)
724 logical (c_bool), intent(in) :: lvalue
725 integer (c_int) :: ivalue
726
727 if (lvalue) then
728 ivalue = 1_c_int
729 else
730 ivalue = 0_c_int
731 end if
732
733end function bool2int
734
735!> Convert a character value into a real
736
737elemental function char2real(sValue) result(rValue)
738
739 character (len=*), intent(in) :: svalue
740 real (c_float) :: rvalue
741
742 ! [ LOCALS ]
743 integer (c_int) :: istat
744
745 read(unit=svalue, fmt=*, iostat=istat) rvalue
746
747 if (istat /= 0) rvalue = rtinyval
748
749end function char2real
750
751!--------------------------------------------------------------------------------------------------
752
753!> Convert a short int value into a real
754
755elemental function short2real(iValue) result(rValue)
756
757 integer (c_short), intent(in) :: ivalue
758 real (c_float) :: rvalue
759
760 rvalue = real(ivalue, c_float)
761
762end function short2real
763
764!--------------------------------------------------------------------------------------------------
765
766!> Convert an int value into a real
767
768elemental function int2real(iValue) result(rValue)
769
770 integer (c_int), intent(in) :: ivalue
771 real (c_float) :: rvalue
772
773 rvalue = real(ivalue, c_float)
774
775end function int2real
776
777!--------------------------------------------------------------------------------------------------
778
779!> Convert a dbl value into a real
780
781elemental function dbl2real(dpValue) result(rValue)
782
783 real (c_double), intent(in) :: dpvalue
784 real (c_float) :: rvalue
785
786 rvalue = real(dpvalue, c_float)
787
788end function dbl2real
789
790!--------------------------------------------------------------------------------------------------
791
792!> Convert a boolean value into a real
793elemental pure function bool2real(lValue) result(rValue)
794 logical (c_bool), intent(in) :: lvalue
795 real (c_float) :: rvalue
796
797 if (lvalue) then
798 rvalue = 1.0_c_float
799 else
800 rvalue = 0.0_c_float
801 end if
802
803end function bool2real
804
805!--------------------------------------------------------------------------------------------------
806
807!> Convert a character value into a double
808
809elemental function char2dbl(sValue) result(dValue)
810
811 character (len=*), intent(in) :: svalue
812 real (c_double) :: dvalue
813
814 ! [ LOCALS ]
815 integer (c_int) :: istat
816
817 read(unit=svalue, fmt=*, iostat=istat) dvalue
818
819 if (istat /= 0) dvalue = dtinyval
820
821end function char2dbl
822
823!--------------------------------------------------------------------------------------------------
824
825!> Convert a short int value into a double
826
827elemental function short2dbl(iValue) result(dValue)
828
829 integer (c_short), intent(in) :: ivalue
830 real (c_double) :: dvalue
831
832 dvalue = real(ivalue, c_double)
833
834end function short2dbl
835
836!--------------------------------------------------------------------------------------------------
837
838!> Convert an int value into a double
839
840elemental function int2dbl(iValue) result(dValue)
841
842 integer (c_int), intent(in) :: ivalue
843 real (c_double) :: dvalue
844
845 dvalue = real(ivalue, c_double)
846
847end function int2dbl
848
849!--------------------------------------------------------------------------------------------------
850
851!> Convert a real value into a double
852
853elemental function real2dbl(fValue) result(dValue)
854
855 real (c_float), intent(in) :: fvalue
856 real (c_double) :: dvalue
857
858 dvalue = real(fvalue, c_double)
859
860end function real2dbl
861
862!--------------------------------------------------------------------------------------------------
863
864!> Convert a boolean value into a double
865elemental pure function bool2dbl(lValue) result(dValue)
866 logical (c_bool), intent(in) :: lvalue
867 real (c_double) :: dvalue
868
869 if (lvalue) then
870 dvalue = 1.0_c_double
871 else
872 dvalue = 0.0_c_double
873 end if
874
875end function bool2dbl
876
877!--------------------------------------------------------------------------------------------------
878
879function char_ptr_to_fortran_string( cpCharacterPtr ) result(sText)
880
881 use iso_c_binding
882 implicit none
883
884 type(c_ptr) :: cpcharacterptr
885 character(len=256) :: stext
886 character (c_char), pointer, dimension(:) :: fptr
887 integer (c_int) :: icount
888
889 stext = repeat(" ", 256)
890
891 call c_f_pointer(cpcharacterptr, fptr, [256])
892 icount = 0
893 do
894 icount = icount + 1
895 if( index(string=fptr(icount), substring=c_null_char ) /= 0) exit
896 stext(icount:icount) = fptr(icount)
897
898 enddo
899
901
902!--------------------------------------------------------------------------------------------------
903
904elemental function c_to_fortran_string( cCharacterString ) result(sText)
905
906 use iso_c_binding
907 implicit none
908
909 character (len=*), intent(in) :: ccharacterstring
910 character(len=len(cCharacterString) - 1) :: stext
911 integer (c_int) :: iindex
912
913 stext = ""
914
915 iindex = index( string=ccharacterstring, substring=c_null_char )
916
917 if(iindex == 0) then
918
919 stext = trim(adjustl(ccharacterstring))
920
921 else
922
923 stext = ccharacterstring(1:iindex-1)
924
925 endif
926
927end function c_to_fortran_string
928
929!--------------------------------------------------------------------------------------------------
930
931elemental function fortran_to_c_string( sText ) result(cCharacterString)
932
933 use iso_c_binding
934 implicit none
935
936 character (len=*), intent(in) :: stext
937 character(len=256) :: ccharacterstring
938 integer (c_int) :: iindex
939
940 iindex = index(string=stext, substring=c_null_char)
941
942 if (iindex == 0) then
943 ccharacterstring = trim(stext)//c_null_char
944 else
945 ccharacterstring = stext(1:iindex)
946 endif
947
948end function fortran_to_c_string
949
950 !> Strip everything except numeric characters from a text string.
951 !!
952 !! Keep only the numeric characters in a text string.
953 !! @param[in] sTextIn
954 impure elemental function keepnumeric(sText1) result(sText)
955
956 ! ARGUMENTS
957 character (len=*), intent(in) :: stext1
958 character (len=len(sText1)) :: stext
959
960 ! LOCALS
961 character (len=512) :: stemp
962 character (len=512) :: sbuf
963 integer (c_int) :: ir ! Index in sRecord
964 integer (c_int) :: iindex1, iindex2
965 character (len=:), allocatable :: stargetcharacters_l
966
967 ! TargetCharacter omits the period ("."): do not want a real value returned
968 ! as a funky integer (e.g. string "3.141" returned as integer 3141 )
969 stargetcharacters_l = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM" &
970 //"!@#$%^&*()_+-={}[]|\:;'<,>?/~`'"//'"'
971
972 ! eliminate any leading spaces
973 stemp = adjustl(stext1)
974 sbuf = ""
975 iindex2 = 0
976
977 do iindex1 = 1,len_trim(stext1)
978
979 ir = scan(stemp(iindex1:iindex1), stargetcharacters_l)
980
981 if(ir==0) then
982 iindex2 = iindex2 + 1
983 sbuf(iindex2:iindex2) = stemp(iindex1:iindex1)
984 end if
985
986 enddo
987
988 stext = trim(sbuf)
989
990 end function keepnumeric
991
992 elemental function enforce_bounds_int_fn(value, minval, maxval) result(retval)
993
994 integer (c_int), intent(in) :: value
995 integer (c_int), intent(in) :: minval
996 integer (c_int), intent(in) :: maxval
997 integer (c_int) :: retval
998
999 retval = min( max( value, minval ), maxval)
1000
1001 end function enforce_bounds_int_fn
1002
1003 elemental function enforce_bounds_sgl_fn(value, minval, maxval) result(retval)
1004
1005 real (c_float), intent(in) :: value
1006 real (c_float), intent(in) :: minval
1007 real (c_float), intent(in) :: maxval
1008 real (c_float) :: retval
1009
1010 retval = min( max( value, minval ), maxval)
1011
1012 end function enforce_bounds_sgl_fn
1013
1014 elemental function enforce_bounds_dbl_fn(value, minval, maxval) result(retval)
1015
1016 real (c_double), intent(in) :: value
1017 real (c_double), intent(in) :: minval
1018 real (c_double), intent(in) :: maxval
1019 real (c_double) :: retval
1020
1021 retval = min( max( value, minval ), maxval)
1022
1023 end function enforce_bounds_dbl_fn
1024
This module contains physical constants and convenience functions aimed at performing unit conversion...
character(len=len_trim(input_pathname)) function fix_pathname(input_pathname)
elemental real(c_float) function inches_to_mm_sgl_fn(inches)
Convert inches to mm.
elemental logical(c_bool) function real2logical(rvalue)
Convert a real to a logical value.
real(c_double), parameter, public dbigval
logical(c_bool), parameter, public true
elemental integer(c_int) function dbl2int(rvalue)
Convert a double-precision value to an integer.
elemental character(len=256) function, public fortran_to_c_string(stext)
real(c_double), parameter, public f_per_c
elemental real(c_float) function deg_to_rad_sgl_fn(degrees)
Convert degrees to radians.
elemental real(c_double) function enforce_bounds_dbl_fn(value, minval, maxval)
real(c_double), parameter tolerance_double
elemental integer(c_int) function real2int(rvalue)
Convert a real value into a integer.
elemental real(c_double) function ftok_dbl_fn(degrees_f)
Convert degrees Fahrenheit to Kelvins.
elemental real(c_float) function ctok_sgl_fn(degrees_c)
Convert degrees Celsius to Kelvins.
elemental real(c_float) function int2real(ivalue)
Convert an int value into a real.
elemental logical(c_bool) function dbl2logical(rvalue)
Convert a double to a logical value.
character(len=:), allocatable, public output_prefix_name
elemental real(c_double) function ctok_dbl_fn(degrees_c)
Convert degrees Fahrenheit to Kelvins.
impure elemental character(len=len(stext1)) function keepnumeric(stext1)
Strip everything except numeric characters from a text string.
elemental real(c_double) function ctof_dbl_fn(degrees_c)
Convert degrees Celsius to degrees Fahrenheit.
real(c_float), parameter, public rtinyval
impure elemental integer(c_int) function char2int(svalue)
Convert a character value into a integer.
elemental logical(c_bool) function approx_equal_float_double(fvalue1, fvalue2)
real(c_double), parameter, public mm_per_in
elemental real(c_double) function ftoc_dbl_fn(degrees_f)
Convert degrees Fahrenheit to degrees Celsius.
real(c_float), parameter tolerance_float
real(c_double), parameter, public twopi
real(c_float), parameter, public rfreezing
elemental real(c_double) function real2dbl(fvalue)
Convert a real value into a double.
real(c_float), parameter, public rzero
real(c_float), parameter, public near_zero
real(c_double), parameter, public dfreezing
real(c_double), parameter, public dtinyval
character(len=:), allocatable, public lookup_table_directory_name
elemental real(c_float) function ftoc_sgl_fn(degrees_f)
Convert degrees Fahrenheit to degrees Celsius.
integer(c_int), parameter datatype_short
integer(c_int), parameter datatype_real
logical(c_bool), parameter, public false
elemental logical(c_bool) function approx_equal_float_float(fvalue1, fvalue2)
real(c_double), parameter, public freezing_point_of_water_kelvin
elemental real(c_double) function rad_to_deg_dbl_fn(radians)
Convert radians to degrees.
elemental real(c_float) function rad_to_deg_sgl_fn(radians)
Convert radians to degrees.
real(c_double), parameter, public freezing_point_of_water_fahrenheit
real(c_double), parameter, public m_per_foot
integer(c_int), parameter datatype_float
real(c_double), parameter, public pi
elemental logical(c_bool) function approx_equal_double_double(fvalue1, fvalue2)
elemental real(c_float) function ftok_sgl_fn(degrees_f)
Convert degrees Fahrenheit to Kelvins.
elemental real(c_float) function enforce_bounds_sgl_fn(value, minval, maxval)
real(c_double), parameter, public c_per_f
elemental real(c_float) function char2real(svalue)
Convert a character value into a real.
elemental integer(c_int) function short2int(ishortval)
Convert a short integer to an integer.
elemental real(c_double) function inches_to_mm_dbl_fn(inches)
Convert inches to mm.
elemental real(c_double) function mm_to_inches_dbl_fn(mm)
Convert millimeters to inches.
elemental logical(c_bool) function int2logical(ivalue)
Convert an integer to a logical value.
real(c_double), parameter, public degrees_to_radians
elemental real(c_double) function deg_to_rad_dbl_fn(degrees)
Convert degrees to radians.
real(c_float), parameter, public rbigval
elemental real(c_double) function short2dbl(ivalue)
Convert a short int value into a double.
elemental logical(c_bool) function short2logical(ishortval)
Convert a short integer to a logical value.
character(len=:), allocatable, public output_directory_name
elemental character(len=len(ccharacterstring) - 1) function, public c_to_fortran_string(ccharacterstring)
elemental real(c_float) function ctof_sgl_fn(degrees_c)
Convert degrees Celsius to degrees Fahrenheit.
impure elemental logical(c_bool) function, public is_numeric(value)
Determine if string contains numeric values.
elemental logical(c_bool) function char2logical(svalue)
Convert a character string to a logical value.
elemental integer(c_int) function enforce_bounds_int_fn(value, minval, maxval)
character(len=:), allocatable, public data_directory_name
elemental real(c_double) function int2dbl(ivalue)
Convert an int value into a double.
integer(c_int), parameter, public itinyval
elemental pure integer(c_int) function bool2int(lvalue)
Convert a boolean value into a int.
elemental real(c_double) function char2dbl(svalue)
Convert a character value into a double.
integer(c_int), parameter datatype_int
integer(c_int), parameter datatype_na
elemental real(c_float) function mm_to_inches_sgl_fn(mm)
Convert millimeters to inches.
character(len=256) function, public char_ptr_to_fortran_string(cpcharacterptr)
elemental real(c_float) function short2real(ivalue)
Convert a short int value into a real.
real(c_double), parameter, public radians_to_degrees
elemental pure real(c_float) function bool2real(lvalue)
Convert a boolean value into a real.
integer(c_int), parameter datatype_double
elemental pure real(c_double) function bool2dbl(lvalue)
Convert a boolean value into a double.
integer(c_int), parameter, public ibigval
real(c_double), parameter, public halfpi
elemental real(c_float) function dbl2real(dpvalue)
Convert a dbl value into a real.
establish generic interfaces to single and double precision functions