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