(git:9ca3469)
Loading...
Searching...
No Matches
cp_units.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief unit conversion facility
10!>
11!> Units are complex, this module does not try to be very smart, for
12!> example SI prefixes are not supported automatically, and
13!> which kinds are really basic can change depending on the system of
14!> units chosen, and equivalences are not always catched.
15!>
16!> This is thought as a simple conversion facility for the input and output.
17!> If you need something more you are probably better off using the
18!> physcon module directly.
19!> \note
20!> One design choice was not to use dynamically allocated elements to
21!> reduce the possibility of leaks.
22!> Needs to be extended (for example charge, dipole,...)
23!> I just added the units and kinds that I needed.
24!> Used by the parser
25!> Should keep an unsorted/uncompressed version for nicer labels?
26!> \par History
27!> 01.2005 created [fawzi]
28!> \author fawzi
29! **************************************************************************************************
31
33 USE kinds, ONLY: dp
34 USE mathconstants, ONLY: radians,&
35 twopi
36 USE physcon, ONLY: &
39 USE string_utilities, ONLY: compress,&
40 s2a,&
42#include "../base/base_uses.f90"
43
44 IMPLICIT NONE
45 PRIVATE
46
47 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
48 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_units'
49
50 INTEGER, PARAMETER, PUBLIC :: cp_ukind_none = 0, &
51 cp_ukind_energy = 1, &
52 cp_ukind_length = 2, &
54 cp_ukind_angle = 4, &
56 cp_ukind_time = 6, &
57 cp_ukind_mass = 7, &
58 cp_ukind_undef = 8, &
60 cp_ukind_force = 10, &
61 cp_ukind_efield = 11, &
62 cp_ukind_max = 11
63
64 ! General
65 INTEGER, PARAMETER, PUBLIC :: cp_units_none = 100, &
66 cp_units_au = 101
67 ! Mass
68 INTEGER, PARAMETER, PUBLIC :: cp_units_m_e = 110, &
69 cp_units_amu = 111, &
70 cp_units_kg = 112
71 ! Energy
72 INTEGER, PARAMETER, PUBLIC :: cp_units_hartree = 130, &
73 cp_units_wavenum = 131, &
74 cp_units_joule = 132, &
75 cp_units_kcalmol = 133, &
76 cp_units_ry = 134, &
77 cp_units_ev = 135, &
78 cp_units_kjmol = 136, &
79 cp_units_jmol = 137, &
80 cp_units_kev = 138
81
82 ! Length
83 INTEGER, PARAMETER, PUBLIC :: cp_units_bohr = 140, &
84 cp_units_angstrom = 141, &
85 cp_units_m = 142, &
86 cp_units_pm = 143, &
87 cp_units_nm = 144
88
89 ! Temperature
90 INTEGER, PARAMETER, PUBLIC :: cp_units_k = 150
91
92 ! Pressure
93 INTEGER, PARAMETER, PUBLIC :: cp_units_bar = 161
94 INTEGER, PARAMETER, PUBLIC :: cp_units_atm = 162
95 INTEGER, PARAMETER, PUBLIC :: cp_units_kbar = 163
96 INTEGER, PARAMETER, PUBLIC :: cp_units_pa = 164
97 INTEGER, PARAMETER, PUBLIC :: cp_units_mpa = 165
98 INTEGER, PARAMETER, PUBLIC :: cp_units_gpa = 166
99
100 ! Angles
101 INTEGER, PARAMETER, PUBLIC :: cp_units_rad = 170, &
102 cp_units_deg = 171
103
104 ! Time
105 INTEGER, PARAMETER, PUBLIC :: cp_units_fs = 180, &
106 cp_units_s = 181, &
107 cp_units_wn = 182, &
108 cp_units_ps = 183
109
110 ! Potential
111 INTEGER, PARAMETER, PUBLIC :: cp_units_volt = 190
112
113 ! Force
114 INTEGER, PARAMETER, PUBLIC :: cp_units_newton = 200, &
115 cp_units_mnewton = 201
116
117 ! Electric Field
118 INTEGER, PARAMETER, PUBLIC :: cp_units_volt_per_m = 202, &
119 cp_units_volt_per_nm = 203, &
121
122 INTEGER, PARAMETER, PUBLIC :: cp_unit_max_kinds = 8, cp_unit_basic_desc_length = 15, &
124
126 PUBLIC :: cp_unit_create, cp_unit_release, &
130
131! **************************************************************************************************
132!> \brief stores a unit
133!> \param kind the kind of unit (energy, length,...)
134!> \param unit the actual unit (Joule, eV,...)
135!> \author fawzi
136! **************************************************************************************************
138 INTEGER :: n_kinds = -1
139 INTEGER, DIMENSION(cp_unit_max_kinds):: kind_id = -1, unit_id = -1, power = -1
140 END TYPE cp_unit_type
141
142! **************************************************************************************************
143!> \brief represent a pointer to a unit (to build arrays of pointers)
144!> \param unit the pointer to the unit
145!> \author fawzi
146! **************************************************************************************************
147 TYPE cp_unit_p_type
148 TYPE(cp_unit_type), POINTER :: unit => null()
149 END TYPE cp_unit_p_type
150
151! **************************************************************************************************
152!> \brief stores the default units to be used
153!> \author fawzi
154! **************************************************************************************************
156 TYPE(cp_unit_p_type), DIMENSION(cp_ukind_max) :: units = cp_unit_p_type()
157 END TYPE cp_unit_set_type
158
159CONTAINS
160
161! **************************************************************************************************
162!> \brief creates a unit parsing a string
163!> \param unit the unit to initialize
164!> \param string the string containing the description of the unit
165!> \author fawzi
166! **************************************************************************************************
167 SUBROUTINE cp_unit_create(unit, string)
168 TYPE(cp_unit_type), INTENT(OUT) :: unit
169 CHARACTER(len=*), INTENT(in) :: string
170
171 CHARACTER(LEN=40) :: formatstr
172 CHARACTER(LEN=cp_unit_desc_length) :: desc
173 CHARACTER(LEN=LEN(string)) :: unit_string
174 INTEGER :: i_high, i_low, i_unit, len_string, &
175 next_power
176 INTEGER, DIMENSION(cp_unit_max_kinds) :: kind_id, power, unit_id
177
178 unit_id = cp_units_none
179 kind_id = cp_ukind_none
180 power = 0
181 i_low = 1
182 i_high = 1
183 len_string = len(string)
184 i_unit = 0
185 next_power = 1
186 DO WHILE (i_low < len_string)
187 IF (string(i_low:i_low) /= ' ') EXIT
188 i_low = i_low + 1
189 END DO
190 i_high = i_low
191 DO WHILE (i_high <= len_string)
192 IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
193 string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
194 i_high = i_high + 1
195 END DO
196 DO
197 IF (i_high <= i_low .OR. i_low > len_string) EXIT
198 i_unit = i_unit + 1
199 IF (i_unit > cp_unit_max_kinds) THEN
200 cpabort("Maximum number of combined units exceeded")
201 EXIT
202 END IF
203 ! read unit
204 unit_string = string(i_low:i_high - 1)
205 CALL uppercase(unit_string)
206 SELECT CASE (trim(unit_string))
207 CASE ("INTERNAL_CP2K")
208 unit_id(i_unit) = cp_units_none
209 kind_id(i_unit) = cp_ukind_undef
210 CASE ("HARTREE")
211 unit_id(i_unit) = cp_units_hartree
212 kind_id(i_unit) = cp_ukind_energy
213 CASE ("AU_E")
214 unit_id(i_unit) = cp_units_au
215 kind_id(i_unit) = cp_ukind_energy
216 CASE ("WAVENUMBER_E")
217 unit_id(i_unit) = cp_units_wavenum
218 kind_id(i_unit) = cp_ukind_energy
219 CASE ("JOULE", "J")
220 unit_id(i_unit) = cp_units_joule
221 kind_id(i_unit) = cp_ukind_energy
222 CASE ("KCALMOL")
223 unit_id(i_unit) = cp_units_kcalmol
224 kind_id(i_unit) = cp_ukind_energy
225 CASE ("KJMOL")
226 unit_id(i_unit) = cp_units_kjmol
227 kind_id(i_unit) = cp_ukind_energy
228 CASE ("JMOL")
229 unit_id(i_unit) = cp_units_jmol
230 kind_id(i_unit) = cp_ukind_energy
231 CASE ("RY")
232 unit_id(i_unit) = cp_units_ry
233 kind_id(i_unit) = cp_ukind_energy
234 CASE ("EV")
235 unit_id(i_unit) = cp_units_ev
236 kind_id(i_unit) = cp_ukind_energy
237 CASE ("KEV")
238 unit_id(i_unit) = cp_units_kev
239 kind_id(i_unit) = cp_ukind_energy
240 CASE ("K_E")
241 unit_id(i_unit) = cp_units_k
242 kind_id(i_unit) = cp_ukind_energy
243 CASE ("ENERGY")
244 unit_id(i_unit) = cp_units_none
245 kind_id(i_unit) = cp_ukind_energy
246 CASE ("AU_L")
247 unit_id(i_unit) = cp_units_au
248 kind_id(i_unit) = cp_ukind_length
249 CASE ("BOHR")
250 unit_id(i_unit) = cp_units_bohr
251 kind_id(i_unit) = cp_ukind_length
252 CASE ("M")
253 unit_id(i_unit) = cp_units_m
254 kind_id(i_unit) = cp_ukind_length
255 CASE ("PM")
256 unit_id(i_unit) = cp_units_pm
257 kind_id(i_unit) = cp_ukind_length
258 CASE ("NM")
259 unit_id(i_unit) = cp_units_nm
260 kind_id(i_unit) = cp_ukind_length
261 CASE ("ANGSTROM")
262 unit_id(i_unit) = cp_units_angstrom
263 kind_id(i_unit) = cp_ukind_length
264 CASE ("LENGTH")
265 unit_id(i_unit) = cp_units_none
266 kind_id(i_unit) = cp_ukind_length
267 CASE ("K", "K_TEMP")
268 unit_id(i_unit) = cp_units_k
269 kind_id(i_unit) = cp_ukind_temperature
270 CASE ("AU_TEMP")
271 unit_id(i_unit) = cp_units_au
272 kind_id(i_unit) = cp_ukind_temperature
273 CASE ("TEMPERATURE")
274 unit_id(i_unit) = cp_units_none
275 kind_id(i_unit) = cp_ukind_temperature
276 CASE ("ATM")
277 unit_id(i_unit) = cp_units_atm
278 kind_id(i_unit) = cp_ukind_pressure
279 CASE ("BAR")
280 unit_id(i_unit) = cp_units_bar
281 kind_id(i_unit) = cp_ukind_pressure
282 CASE ("KBAR")
283 unit_id(i_unit) = cp_units_kbar
284 kind_id(i_unit) = cp_ukind_pressure
285 CASE ("PA")
286 unit_id(i_unit) = cp_units_pa
287 kind_id(i_unit) = cp_ukind_pressure
288 CASE ("MPA")
289 unit_id(i_unit) = cp_units_mpa
290 kind_id(i_unit) = cp_ukind_pressure
291 CASE ("GPA")
292 unit_id(i_unit) = cp_units_gpa
293 kind_id(i_unit) = cp_ukind_pressure
294 CASE ("AU_P")
295 unit_id(i_unit) = cp_units_au
296 kind_id(i_unit) = cp_ukind_pressure
297 CASE ("PRESSURE")
298 unit_id(i_unit) = cp_units_none
299 kind_id(i_unit) = cp_ukind_pressure
300 CASE ("RAD")
301 unit_id(i_unit) = cp_units_rad
302 kind_id(i_unit) = cp_ukind_angle
303 CASE ("DEG")
304 unit_id(i_unit) = cp_units_deg
305 kind_id(i_unit) = cp_ukind_angle
306 CASE ("ANGLE")
307 unit_id(i_unit) = cp_units_none
308 kind_id(i_unit) = cp_ukind_angle
309 CASE ("S")
310 unit_id(i_unit) = cp_units_s
311 kind_id(i_unit) = cp_ukind_time
312 CASE ("FS")
313 unit_id(i_unit) = cp_units_fs
314 kind_id(i_unit) = cp_ukind_time
315 CASE ("PS")
316 unit_id(i_unit) = cp_units_ps
317 kind_id(i_unit) = cp_ukind_time
318 CASE ("WAVENUMBER_T")
319 unit_id(i_unit) = cp_units_wn
320 kind_id(i_unit) = cp_ukind_time
321 CASE ("AU_T")
322 unit_id(i_unit) = cp_units_au
323 kind_id(i_unit) = cp_ukind_time
324 CASE ("TIME")
325 unit_id(i_unit) = cp_units_none
326 kind_id(i_unit) = cp_ukind_time
327 CASE ("KG")
328 unit_id(i_unit) = cp_units_kg
329 kind_id(i_unit) = cp_ukind_mass
330 CASE ("AMU")
331 unit_id(i_unit) = cp_units_amu
332 kind_id(i_unit) = cp_ukind_mass
333 CASE ("M_E")
334 unit_id(i_unit) = cp_units_m_e
335 kind_id(i_unit) = cp_ukind_mass
336 CASE ("AU_M")
337 unit_id(i_unit) = cp_units_au
338 kind_id(i_unit) = cp_ukind_mass
339 CASE ("MASS")
340 unit_id(i_unit) = cp_units_none
341 kind_id(i_unit) = cp_ukind_mass
342 CASE ("VOLT")
343 unit_id(i_unit) = cp_units_volt
344 kind_id(i_unit) = cp_ukind_potential
345 CASE ("AU_POT")
346 unit_id(i_unit) = cp_units_au
347 kind_id(i_unit) = cp_ukind_potential
348 CASE ("POTENTIAL")
349 unit_id(i_unit) = cp_units_none
350 kind_id(i_unit) = cp_ukind_potential
351 CASE ("N", "NEWTON")
352 unit_id(i_unit) = cp_units_newton
353 kind_id(i_unit) = cp_ukind_force
354 CASE ("MN", "MNEWTON")
355 unit_id(i_unit) = cp_units_mnewton
356 kind_id(i_unit) = cp_ukind_force
357 CASE ("AU_F")
358 unit_id(i_unit) = cp_units_au
359 kind_id(i_unit) = cp_ukind_force
360 CASE ("FORCE")
361 unit_id(i_unit) = cp_units_none
362 kind_id(i_unit) = cp_ukind_force
363 CASE ("VM-1", "VOLT_PER_M")
364 unit_id(i_unit) = cp_units_volt_per_m
365 kind_id(i_unit) = cp_ukind_efield
366 CASE ("VNM-1", "VOLT_PER_NM")
367 unit_id(i_unit) = cp_units_volt_per_nm
368 kind_id(i_unit) = cp_ukind_efield
369 CASE ("VA-1", "VOLT_PER_ANGSTROM")
370 unit_id(i_unit) = cp_units_volt_per_angstrom
371 kind_id(i_unit) = cp_ukind_efield
372 CASE ("AU_EFIELD")
373 unit_id(i_unit) = cp_units_au
374 kind_id(i_unit) = cp_ukind_efield
375 CASE ("EFIELD")
376 unit_id(i_unit) = cp_units_none
377 kind_id(i_unit) = cp_ukind_efield
378 CASE ("AU")
379 CALL cp_abort(__location__, &
380 "au unit without specifying its kind not accepted, use "// &
381 "(au_e, au_f, au_t, au_temp, au_l, au_m, au_p, au_pot, "// &
382 "au_efield)")
383 CASE default
384 cpabort("Unknown unit: "//string(i_low:i_high - 1))
385 END SELECT
386 power(i_unit) = next_power
387 ! parse op
388 i_low = i_high
389 DO WHILE (i_low <= len_string)
390 IF (string(i_low:i_low) /= ' ') EXIT
391 i_low = i_low + 1
392 END DO
393 i_high = i_low
394 DO WHILE (i_high <= len_string)
395 IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
396 string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
397 i_high = i_high + 1
398 END DO
399 IF (i_high < i_low .OR. i_low > len_string) EXIT
400
401 IF (i_high <= len_string) THEN
402 IF (string(i_low:i_high) == '^') THEN
403 i_low = i_high + 1
404 DO WHILE (i_low <= len_string)
405 IF (string(i_low:i_low) /= ' ') EXIT
406 i_low = i_low + 1
407 END DO
408 i_high = i_low
409 DO WHILE (i_high <= len_string)
410 SELECT CASE (string(i_high:i_high))
411 CASE ('+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
412 i_high = i_high + 1
413 CASE default
414 EXIT
415 END SELECT
416 END DO
417 IF (i_high <= i_low .OR. i_low > len_string) THEN
418 cpabort("an integer number is expected after a '^'")
419 EXIT
420 END IF
421 formatstr = "(i"//cp_to_string(i_high - i_low + 1)//")"
422 READ (string(i_low:i_high - 1), formatstr) &
423 next_power
424 power(i_unit) = power(i_unit)*next_power
425 ! next op
426 i_low = i_high
427 DO WHILE (i_low < len_string)
428 IF (string(i_low:i_low) /= ' ') EXIT
429 i_low = i_low + 1
430 END DO
431 i_high = i_low
432 DO WHILE (i_high <= len_string)
433 IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
434 string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
435 i_high = i_high + 1
436 END DO
437 END IF
438 END IF
439 IF (i_low > len_string) EXIT
440 next_power = 1
441 IF (i_high <= len_string) THEN
442 IF (string(i_low:i_high) == "*" .OR. string(i_low:i_high) == '/') THEN
443 IF (string(i_low:i_high) == '/') next_power = -1
444 i_low = i_high + 1
445 DO WHILE (i_low <= len_string)
446 IF (string(i_low:i_low) /= ' ') EXIT
447 i_low = i_low + 1
448 END DO
449 i_high = i_low
450 DO WHILE (i_high <= len_string)
451 IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
452 string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
453 i_high = i_high + 1
454 END DO
455 END IF
456 END IF
457 END DO
458 CALL cp_unit_create2(unit, kind_id=kind_id, unit_id=unit_id, &
459 power=power)
460 desc = cp_unit_desc(unit)
461 END SUBROUTINE cp_unit_create
462
463! **************************************************************************************************
464!> \brief creates and initializes the given unit of mesure (performs some error
465!> check)
466!> \param unit the unit descriptor to be initialized
467!> \param kind_id the kind of unit (length,energy,...), use the constants
468!> cp_ukind_*
469!> \param unit_id the actual unit (use constants cp_units_*)
470!> \param power ...
471!> \author fawzi
472! **************************************************************************************************
473 SUBROUTINE cp_unit_create2(unit, kind_id, unit_id, power)
474 TYPE(cp_unit_type), INTENT(OUT) :: unit
475 INTEGER, DIMENSION(:), INTENT(in) :: kind_id, unit_id
476 INTEGER, DIMENSION(:), INTENT(in), OPTIONAL :: power
477
478 INTEGER :: i, j, max_kind, max_pos
479 LOGICAL :: repeat
480
481 cpassert(SIZE(kind_id) <= cp_unit_max_kinds)
482 cpassert(SIZE(unit_id) <= cp_unit_max_kinds)
483 unit%kind_id(1:SIZE(kind_id)) = kind_id
484 unit%kind_id(SIZE(kind_id) + 1:) = cp_ukind_none
485 unit%unit_id(1:SIZE(unit_id)) = unit_id
486 unit%unit_id(SIZE(unit_id):) = cp_units_none
487 IF (PRESENT(power)) THEN
488 unit%power(1:SIZE(power)) = power
489 unit%power(SIZE(power) + 1:) = 0
490 DO i = 1, SIZE(unit%power)
491 IF (unit%power(i) == 0) THEN
492 unit%kind_id(i) = cp_ukind_none
493 unit%unit_id(i) = cp_units_none
494 END IF
495 END DO
496 ELSE
497 DO i = 1, SIZE(unit%power)
498 IF (unit%unit_id(i) /= 0) THEN
499 unit%power(i) = 1
500 ELSE
501 unit%power(i) = 0
502 END IF
503 END DO
504 END IF
505
506 ! remove unnecessary units
507 ! reorder & compress
508 unit%n_kinds = 0
509 DO i = 1, SIZE(unit%kind_id)
510 ! find max and compress in the rest
511 DO
512 max_kind = unit%kind_id(i)
513 max_pos = i
514 repeat = .false.
515 DO j = i + 1, SIZE(unit%kind_id)
516 IF (unit%kind_id(j) >= max_kind) THEN
517 IF (unit%kind_id(j) /= 0 .AND. unit%kind_id(j) == max_kind .AND. &
518 unit%unit_id(j) == unit%unit_id(max_pos)) THEN
519 unit%power(max_pos) = unit%power(max_pos) + unit%power(j)
520 unit%kind_id(j) = cp_ukind_none
521 unit%unit_id(j) = cp_units_none
522 unit%power(j) = 0
523 IF (unit%power(max_pos) == 0) THEN
524 unit%kind_id(max_pos) = cp_ukind_none
525 unit%unit_id(max_pos) = cp_units_none
526 unit%power(max_pos) = 0
527 repeat = .true.
528 EXIT
529 END IF
530 ELSE IF (unit%kind_id(j) > max_kind .OR. &
531 (unit%kind_id(j) == max_kind .AND. &
532 unit%unit_id(j) > unit%unit_id(max_pos))) THEN
533 max_kind = unit%kind_id(j)
534 max_pos = j
535 END IF
536 END IF
537 END DO
538 IF (.NOT. repeat) EXIT
539 END DO
540 IF (max_kind /= 0) unit%n_kinds = unit%n_kinds + 1
541 ! put the max at pos i
542 IF (max_pos /= i) THEN
543 unit%kind_id(max_pos) = unit%kind_id(i)
544 unit%kind_id(i) = max_kind
545 max_kind = unit%unit_id(max_pos)
546 unit%unit_id(max_pos) = unit%unit_id(i)
547 unit%unit_id(i) = max_kind
548 max_kind = unit%power(max_pos)
549 unit%power(max_pos) = unit%power(i)
550 unit%power(i) = max_kind
551 END IF
552 ! check unit
553 CALL cp_basic_unit_check(basic_kind=unit%kind_id(i), &
554 basic_unit=unit%unit_id(i))
555 END DO
556 END SUBROUTINE cp_unit_create2
557
558! **************************************************************************************************
559!> \brief releases the given unit
560!> \param unit the unit to release
561!> \author fawzi
562!> \note
563!> at the moment not needed, there for completeness
564! **************************************************************************************************
565 ELEMENTAL SUBROUTINE cp_unit_release(unit)
566 TYPE(cp_unit_type), INTENT(IN) :: unit
567
568 mark_used(unit)
569
570 END SUBROUTINE cp_unit_release
571
572! **************************************************************************************************
573!> \brief controls that the kind and contains meaningful information
574!> \param basic_kind the kind of the unit
575!> \param basic_unit the unit to check
576!> \author fawzi
577! **************************************************************************************************
578 SUBROUTINE cp_basic_unit_check(basic_kind, basic_unit)
579 INTEGER, INTENT(in) :: basic_kind, basic_unit
580
581 SELECT CASE (basic_kind)
582 CASE (cp_ukind_undef)
583 SELECT CASE (basic_unit)
584 CASE (cp_units_none)
585 CASE default
586 cpabort("unknown undef unit:"//trim(cp_to_string(basic_unit)))
587 END SELECT
588 CASE (cp_ukind_energy)
589 SELECT CASE (basic_unit)
593 CASE default
594 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
595 END SELECT
596 CASE (cp_ukind_length)
597 SELECT CASE (basic_unit)
600 CASE default
601 cpabort("unknown length unit:"//trim(cp_to_string(basic_unit)))
602 END SELECT
604 SELECT CASE (basic_unit)
606 CASE default
607 cpabort("unknown temperature unit:"//trim(cp_to_string(basic_unit)))
608 END SELECT
609 CASE (cp_ukind_pressure)
610 SELECT CASE (basic_unit)
612 CASE default
613 cpabort("unknown pressure unit:"//trim(cp_to_string(basic_unit)))
614 END SELECT
615 CASE (cp_ukind_angle)
616 SELECT CASE (basic_unit)
618 CASE default
619 cpabort("unknown angle unit:"//trim(cp_to_string(basic_unit)))
620 END SELECT
621 CASE (cp_ukind_time)
622 SELECT CASE (basic_unit)
624 CASE default
625 cpabort("unknown time unit:"//trim(cp_to_string(basic_unit)))
626 END SELECT
627 CASE (cp_ukind_mass)
628 SELECT CASE (basic_unit)
630 CASE default
631 cpabort("unknown mass unit:"//trim(cp_to_string(basic_unit)))
632 END SELECT
633 CASE (cp_ukind_potential)
634 SELECT CASE (basic_unit)
636 CASE default
637 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
638 END SELECT
639 CASE (cp_ukind_force)
640 SELECT CASE (basic_unit)
642 CASE default
643 cpabort("unknown force unit:"//trim(cp_to_string(basic_unit)))
644 END SELECT
645 CASE (cp_ukind_efield)
646 SELECT CASE (basic_unit)
649 CASE default
650 cpabort("unknown electric field unit:"//trim(cp_to_string(basic_unit)))
651 END SELECT
652 CASE (cp_ukind_none)
653 IF (basic_unit /= cp_units_none) &
654 CALL cp_abort(__location__, &
655 "if the kind of the unit is none also unit must be undefined,not:" &
656 //trim(cp_to_string(basic_unit)))
657 CASE default
658 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
659 END SELECT
660 END SUBROUTINE cp_basic_unit_check
661
662! **************************************************************************************************
663!> \brief converts a value to the internal cp2k units
664!> \param value the value to convert
665!> \param basic_kind the kind of the unit of the value
666!> \param basic_unit the unit of the value
667!> \param power the power of the unit (defaults to 1)
668!> \return ...
669!> \author fawzi
670! **************************************************************************************************
671 FUNCTION cp_basic_unit_to_cp2k(value, basic_kind, basic_unit, power) RESULT(res)
672 REAL(kind=dp), INTENT(in) :: value
673 INTEGER, INTENT(in) :: basic_kind, basic_unit
674 INTEGER, INTENT(in), OPTIONAL :: power
675 REAL(kind=dp) :: res
676
677 INTEGER :: my_power
678
679 my_power = 1
680 IF (PRESENT(power)) my_power = power
681 IF (basic_unit == cp_units_none .AND. basic_kind /= cp_ukind_undef) THEN
682 IF (basic_kind /= cp_units_none) &
683 CALL cp_abort(__location__, &
684 "unit not yet fully specified, unit of kind "// &
685 trim(cp_to_string(basic_unit)))
686 END IF
687 SELECT CASE (basic_kind)
688 CASE (cp_ukind_undef)
689 SELECT CASE (basic_unit)
690 CASE (cp_units_none)
691 res = value
692 CASE default
693 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
694 END SELECT
695 CASE (cp_ukind_energy)
696 SELECT CASE (basic_unit)
698 res = value
699 CASE (cp_units_wavenum)
700 res = wavenumbers**(-my_power)*value
701 CASE (cp_units_joule)
702 res = joule**(-my_power)*value
703 CASE (cp_units_kcalmol)
704 res = kcalmol**(-my_power)*value
705 CASE (cp_units_kjmol)
706 res = kjmol**(-my_power)*value
707 CASE (cp_units_jmol)
708 res = (kjmol*1.0e+3_dp)**(-my_power)*value
709 CASE (cp_units_ry)
710 res = 0.5_dp**my_power*value
711 CASE (cp_units_ev)
712 res = evolt**(-my_power)*value
713 CASE (cp_units_kev)
714 res = (1.0e-3_dp*evolt)**(-my_power)*value
715 CASE (cp_units_k)
716 res = kelvin**(-my_power)*value
717 CASE default
718 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
719 END SELECT
720 CASE (cp_ukind_length)
721 SELECT CASE (basic_unit)
723 res = value
724 CASE (cp_units_m)
725 res = value*(1.0e10_dp*bohr)**my_power
726 CASE (cp_units_pm)
727 res = value*(0.01_dp*bohr)**my_power
728 CASE (cp_units_nm)
729 res = value*(10.0_dp*bohr)**my_power
730 CASE (cp_units_angstrom)
731 res = value*bohr**my_power
732 CASE default
733 cpabort("unknown length unit:"//trim(cp_to_string(basic_unit)))
734 END SELECT
736 SELECT CASE (basic_unit)
737 CASE (cp_units_k)
738 res = kelvin**(-my_power)*value
739 CASE (cp_units_au)
740 res = value
741 CASE default
742 cpabort("unknown temperature unit:"//trim(cp_to_string(basic_unit)))
743 END SELECT
744 CASE (cp_ukind_pressure)
745 SELECT CASE (basic_unit)
746 CASE (cp_units_bar)
747 res = bar**(-my_power)*value
748 CASE (cp_units_atm)
749 res = atm**(-my_power)*value
750 CASE (cp_units_kbar)
751 res = (1.0e-3_dp*bar)**(-my_power)*value
752 CASE (cp_units_pa)
753 res = pascal**(-my_power)*value
754 CASE (cp_units_mpa)
755 res = (1.0e-6_dp*pascal)**(-my_power)*value
756 CASE (cp_units_gpa)
757 res = (1.0e-9_dp*pascal)**(-my_power)*value
758 CASE (cp_units_au)
759 res = value
760 CASE default
761 cpabort("unknown pressure unit:"//trim(cp_to_string(basic_unit)))
762 END SELECT
763 CASE (cp_ukind_angle)
764 SELECT CASE (basic_unit)
765 CASE (cp_units_rad)
766 res = value
767 CASE (cp_units_deg)
768 res = value*(radians)**my_power
769 CASE default
770 cpabort("unknown angle unit:"//trim(cp_to_string(basic_unit)))
771 END SELECT
772 CASE (cp_ukind_time)
773 SELECT CASE (basic_unit)
774 CASE (cp_units_s)
775 res = value*seconds**(-my_power)
776 CASE (cp_units_fs)
777 res = value*femtoseconds**(-my_power)
778 CASE (cp_units_ps)
779 res = value*picoseconds**(-my_power)
780 CASE (cp_units_au)
781 res = value
782 CASE (cp_units_wn)
783 res = (twopi*wavenumbers)**(my_power)/value
784 CASE default
785 cpabort("unknown time unit:"//trim(cp_to_string(basic_unit)))
786 END SELECT
787 CASE (cp_ukind_mass)
788 SELECT CASE (basic_unit)
789 CASE (cp_units_kg)
790 res = e_mass**my_power*value
791 CASE (cp_units_amu)
792 res = massunit**my_power*value
794 res = value
795 CASE default
796 cpabort("unknown mass unit:"//trim(cp_to_string(basic_unit)))
797 END SELECT
798 CASE (cp_ukind_potential)
799 SELECT CASE (basic_unit)
800 CASE (cp_units_volt)
801 res = evolt**(-my_power)*value
802 CASE (cp_units_au)
803 res = value
804 CASE default
805 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
806 END SELECT
807 CASE (cp_ukind_force)
808 SELECT CASE (basic_unit)
809 CASE (cp_units_newton)
810 res = value*newton**(-my_power)
811 CASE (cp_units_mnewton)
812 res = value*(1.0e+3*newton)**(-my_power)
813 CASE (cp_units_au)
814 res = value
815 CASE default
816 cpabort("unknown force unit:"//trim(cp_to_string(basic_unit)))
817 END SELECT
818 CASE (cp_ukind_efield)
819 SELECT CASE (basic_unit)
821 res = (1.0e+10_dp*evolt*bohr)**(-my_power)*value
823 res = (10.0_dp*evolt*bohr)**(-my_power)*value
825 res = (evolt*bohr)**(-my_power)*value
826 CASE (cp_units_au)
827 res = value
828 CASE default
829 cpabort("unknown electric field unit:"//trim(cp_to_string(basic_unit)))
830 END SELECT
831 CASE (cp_ukind_none)
832 CALL cp_abort(__location__, &
833 "if the kind of the unit is none also unit must be undefined,not:" &
834 //trim(cp_to_string(basic_unit)))
835 CASE default
836 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
837 END SELECT
838 END FUNCTION cp_basic_unit_to_cp2k
839
840! **************************************************************************************************
841!> \brief returns the label of the current basic unit
842!> \param basic_kind the kind of the unit of the value
843!> \param basic_unit the unit of the value
844!> \param power the power of the unit (defaults to 1)
845!> \param accept_undefined ...
846!> \return ...
847!> \author fawzi
848! **************************************************************************************************
849 FUNCTION cp_basic_unit_desc(basic_kind, basic_unit, power, accept_undefined) &
850 result(res)
851 INTEGER, INTENT(in) :: basic_kind, basic_unit
852 INTEGER, INTENT(in), OPTIONAL :: power
853 LOGICAL, INTENT(in), OPTIONAL :: accept_undefined
854 CHARACTER(len=cp_unit_basic_desc_length) :: res
855
856 INTEGER :: a, my_power
857 LOGICAL :: my_accept_undefined
858
859 my_power = 1
860 res = ""
861 my_accept_undefined = .false.
862 IF (accept_undefined) my_accept_undefined = accept_undefined
863 IF (PRESENT(power)) my_power = power
864 IF (basic_unit == cp_units_none) THEN
865 IF (.NOT. my_accept_undefined .AND. basic_kind == cp_units_none) &
866 CALL cp_abort(__location__, "unit not yet fully specified, unit of kind "// &
867 trim(cp_to_string(basic_kind)))
868 END IF
869 SELECT CASE (basic_kind)
870 CASE (cp_ukind_undef)
871 SELECT CASE (basic_unit)
872 CASE (cp_units_none)
873 res = "internal_cp2k"
874 CASE DEFAULT
875 CALL cp_abort(__location__, &
876 "unit not yet fully specified, unit of kind "// &
877 trim(res))
878 END SELECT
879 CASE (cp_ukind_energy)
880 SELECT CASE (basic_unit)
882 res = "hartree"
883 CASE (cp_units_wavenum)
884 res = "wavenumber_e"
885 CASE (cp_units_joule)
886 res = "joule"
887 CASE (cp_units_kcalmol)
888 res = "kcalmol"
889 CASE (cp_units_kjmol)
890 res = "kjmol"
891 CASE (cp_units_jmol)
892 res = "jmol"
893 CASE (cp_units_ry)
894 res = "Ry"
895 CASE (cp_units_ev)
896 res = "eV"
897 CASE (cp_units_kev)
898 res = "keV"
899 CASE (cp_units_k)
900 res = "K_e"
901 CASE (cp_units_none)
902 res = "energy"
903 IF (.NOT. my_accept_undefined) &
904 CALL cp_abort(__location__, &
905 "unit not yet fully specified, unit of kind "// &
906 trim(res))
907 CASE default
908 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
909 END SELECT
910 CASE (cp_ukind_length)
911 SELECT CASE (basic_unit)
913 res = "bohr"
914 CASE (cp_units_m)
915 res = "m"
916 CASE (cp_units_pm)
917 res = "pm"
918 CASE (cp_units_nm)
919 res = "nm"
920 CASE (cp_units_angstrom)
921 res = "angstrom"
922 CASE default
923 res = "length"
924 cpabort("unknown length unit:"//trim(cp_to_string(basic_unit)))
925 END SELECT
927 SELECT CASE (basic_unit)
928 CASE (cp_units_k)
929 res = "K"
930 CASE (cp_units_au)
931 res = "au_temp"
932 CASE (cp_units_none)
933 res = "temperature"
934 IF (.NOT. my_accept_undefined) &
935 CALL cp_abort(__location__, &
936 "unit not yet fully specified, unit of kind "// &
937 trim(res))
938 CASE default
939 cpabort("unknown temperature unit:"//trim(cp_to_string(basic_unit)))
940 END SELECT
941 CASE (cp_ukind_pressure)
942 SELECT CASE (basic_unit)
943 CASE (cp_units_bar)
944 res = "bar"
945 CASE (cp_units_atm)
946 res = "atm"
947 CASE (cp_units_kbar)
948 res = "kbar"
949 CASE (cp_units_pa)
950 res = "Pa"
951 CASE (cp_units_mpa)
952 res = "MPa"
953 CASE (cp_units_gpa)
954 res = "GPa"
955 CASE (cp_units_au)
956 res = "au_p"
957 CASE (cp_units_none)
958 res = "pressure"
959 IF (.NOT. my_accept_undefined) &
960 CALL cp_abort(__location__, &
961 "unit not yet fully specified, unit of kind "// &
962 trim(res))
963 CASE default
964 cpabort("unknown pressure unit:"//trim(cp_to_string(basic_unit)))
965 END SELECT
966 CASE (cp_ukind_angle)
967 SELECT CASE (basic_unit)
968 CASE (cp_units_rad)
969 res = "rad"
970 CASE (cp_units_deg)
971 res = "deg"
972 CASE (cp_units_none)
973 res = "angle"
974 IF (.NOT. my_accept_undefined) &
975 CALL cp_abort(__location__, &
976 "unit not yet fully specified, unit of kind "// &
977 trim(res))
978 CASE default
979 cpabort("unknown angle unit:"//trim(cp_to_string(basic_unit)))
980 END SELECT
981 CASE (cp_ukind_time)
982 SELECT CASE (basic_unit)
983 CASE (cp_units_s)
984 res = "s"
985 CASE (cp_units_fs)
986 res = "fs"
987 CASE (cp_units_ps)
988 res = "ps"
989 CASE (cp_units_au)
990 res = "au_t"
991 CASE (cp_units_wn)
992 res = "wavenumber_t"
993 CASE (cp_units_none)
994 res = "time"
995 IF (.NOT. my_accept_undefined) &
996 CALL cp_abort(__location__, &
997 "unit not yet fully specified, unit of kind "// &
998 trim(res))
999 CASE default
1000 cpabort("unknown time unit:"//trim(cp_to_string(basic_unit)))
1001 END SELECT
1002 CASE (cp_ukind_mass)
1003 SELECT CASE (basic_unit)
1004 CASE (cp_units_kg)
1005 res = "kg"
1006 CASE (cp_units_amu)
1007 res = "amu"
1009 res = "m_e"
1010 CASE (cp_units_none)
1011 res = "mass"
1012 IF (.NOT. my_accept_undefined) &
1013 CALL cp_abort(__location__, &
1014 "unit not yet fully specified, unit of kind "// &
1015 trim(res))
1016 CASE default
1017 cpabort("unknown mass unit:"//trim(cp_to_string(basic_unit)))
1018 END SELECT
1019 CASE (cp_ukind_potential)
1020 SELECT CASE (basic_unit)
1021 CASE (cp_units_volt)
1022 res = "volt"
1023 CASE (cp_units_au)
1024 res = "au_pot"
1025 CASE (cp_units_none)
1026 res = "potential"
1027 IF (.NOT. my_accept_undefined) &
1028 CALL cp_abort(__location__, &
1029 "unit not yet fully specified, unit of kind "// &
1030 trim(res))
1031 CASE default
1032 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
1033 END SELECT
1034 CASE (cp_ukind_force)
1035 SELECT CASE (basic_unit)
1036 CASE (cp_units_newton)
1037 res = "N"
1038 CASE (cp_units_mnewton)
1039 res = "mN"
1040 CASE (cp_units_au)
1041 res = "au_f"
1042 CASE (cp_units_none)
1043 res = "force"
1044 IF (.NOT. my_accept_undefined) &
1045 CALL cp_abort(__location__, &
1046 "unit not yet fully specified, unit of kind "// &
1047 trim(res))
1048 CASE default
1049 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
1050 END SELECT
1051 CASE (cp_ukind_efield)
1052 SELECT CASE (basic_unit)
1053 CASE (cp_units_volt_per_m)
1054 res = "Vm-1"
1056 res = "Vnm-1"
1058 res = "Vangstrom-1"
1059 CASE (cp_units_au)
1060 res = "au_efield"
1061 CASE (cp_units_none)
1062 res = "electric field"
1063 IF (.NOT. my_accept_undefined) &
1064 CALL cp_abort(__location__, &
1065 "unit not yet fully specified, unit of kind "// &
1066 trim(res))
1067 CASE default
1068 cpabort("unknown efield unit:"//trim(cp_to_string(basic_unit)))
1069 END SELECT
1070 CASE (cp_ukind_none)
1071 CALL cp_abort(__location__, &
1072 "if the kind of the unit is none also unit must be undefined,not:" &
1073 //trim(cp_to_string(basic_unit)))
1074 CASE default
1075 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
1076 END SELECT
1077 IF (my_power /= 1) THEN
1078 a = len_trim(res)
1079 cpassert(len(res) - a >= 3)
1080 WRITE (res(a + 1:), "('^',i3)") my_power
1081 CALL compress(res, .true.)
1082 END IF
1083 END FUNCTION cp_basic_unit_desc
1084
1085! **************************************************************************************************
1086!> \brief returns the "name" of the given unit
1087!> \param unit the unit to describe
1088!> \param defaults defaults for the undefined units, optional
1089!> \param accept_undefined if defaults is not present or is not associated
1090!> whether undefined units should be accepted (defaults to false)
1091!> \return ...
1092!> \author fawzi
1093! **************************************************************************************************
1094 FUNCTION cp_unit_desc(unit, defaults, accept_undefined) &
1095 result(res)
1096 TYPE(cp_unit_type), INTENT(IN) :: unit
1097 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1098 LOGICAL, INTENT(in), OPTIONAL :: accept_undefined
1099 CHARACTER(len=cp_unit_desc_length) :: res
1100
1101 INTEGER :: i, my_unit, pos
1102 LOGICAL :: check, has_defaults, my_accept_undefined
1103
1104 res = ""
1105 pos = 1
1106 my_accept_undefined = .false.
1107 IF (PRESENT(accept_undefined)) my_accept_undefined = accept_undefined
1108 DO i = 1, unit%n_kinds
1109 cpassert(unit%kind_id(i) /= 0)
1110 cpassert(pos < len(res))
1111 my_unit = unit%unit_id(i)
1112 has_defaults = .false.
1113 IF (PRESENT(defaults)) has_defaults = ASSOCIATED(defaults%units(1)%unit)
1114 IF (my_unit == 0) THEN
1115 IF (has_defaults) THEN
1116 my_unit = defaults%units(unit%kind_id(i))%unit%unit_id(1)
1117 ELSE
1118 check = my_accept_undefined .OR. unit%kind_id(i) /= 0
1119 cpassert(check)
1120 END IF
1121 END IF
1122 IF (i > 1) THEN
1123 res(pos:pos) = "*"
1124 pos = pos + 1
1125 END IF
1126 res(pos:) = trim(cp_basic_unit_desc(basic_kind=unit%kind_id(i), &
1127 basic_unit=my_unit, accept_undefined=my_accept_undefined, &
1128 power=unit%power(i)))
1129 pos = len_trim(res) + 1
1130 END DO
1131
1132 END FUNCTION cp_unit_desc
1133
1134! **************************************************************************************************
1135!> \brief transform a value to the internal cp2k units
1136!> \param value the value to convert
1137!> \param unit the unit of the result
1138!> \param defaults the defaults unit for those that are left free
1139!> (cp_units_none)
1140!> \param power the power of the unit (defaults to 1)
1141!> \return ...
1142!> \author fawzi
1143! **************************************************************************************************
1144 FUNCTION cp_unit_to_cp2k1(value, unit, defaults, power) RESULT(res)
1145 REAL(kind=dp), INTENT(in) :: value
1146 TYPE(cp_unit_type), INTENT(IN) :: unit
1147 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1148 INTEGER, INTENT(in), OPTIONAL :: power
1149 REAL(kind=dp) :: res
1150
1151 INTEGER :: i_unit, my_basic_unit, my_power
1152
1153 my_power = 1
1154 IF (PRESENT(power)) my_power = power
1155 res = value
1156 DO i_unit = 1, unit%n_kinds
1157 cpassert(unit%kind_id(i_unit) > 0)
1158 my_basic_unit = unit%unit_id(i_unit)
1159 IF (my_basic_unit == 0 .AND. unit%kind_id(i_unit) /= cp_ukind_undef) THEN
1160 cpassert(PRESENT(defaults))
1161 cpassert(ASSOCIATED(defaults%units(unit%kind_id(i_unit))%unit))
1162 my_basic_unit = defaults%units(unit%kind_id(i_unit))%unit%unit_id(1)
1163 END IF
1164 res = cp_basic_unit_to_cp2k(value=res, basic_unit=my_basic_unit, &
1165 basic_kind=unit%kind_id(i_unit), &
1166 power=my_power*unit%power(i_unit))
1167 END DO
1168 END FUNCTION cp_unit_to_cp2k1
1169
1170! **************************************************************************************************
1171!> \brief converts from the internal cp2k units to the given unit
1172!> \param value the value to convert
1173!> \param unit the unit of the result
1174!> \param defaults the defaults unit for those that are left free
1175!> (cp_units_none)
1176!> \param power the power of the unit (defaults to 1)
1177!> \return ...
1178!> \author fawzi
1179! **************************************************************************************************
1180 FUNCTION cp_unit_from_cp2k1(value, unit, defaults, power) RESULT(res)
1181 REAL(kind=dp), INTENT(in) :: value
1182 TYPE(cp_unit_type), INTENT(IN) :: unit
1183 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1184 INTEGER, INTENT(in), OPTIONAL :: power
1185 REAL(kind=dp) :: res
1186
1187 INTEGER :: my_power
1188
1189 my_power = 1
1190 IF (PRESENT(power)) my_power = power
1191 IF (PRESENT(defaults)) THEN
1192 res = cp_unit_to_cp2k1(value=value, unit=unit, defaults=defaults, &
1193 power=-my_power)
1194 ELSE
1195 res = cp_unit_to_cp2k1(value=value, unit=unit, power=-my_power)
1196 END IF
1197 END FUNCTION cp_unit_from_cp2k1
1198
1199! **************************************************************************************************
1200!> \brief converts to the internal cp2k units to the given unit
1201!> \param value the value to convert
1202!> \param unit_str the unit of the result as string
1203!> \param defaults the defaults unit for those that are left free
1204!> (cp_units_none)
1205!> \param power the power of the unit (defaults to 1)
1206!> \return ...
1207!> \author fawzi
1208! **************************************************************************************************
1209 FUNCTION cp_unit_to_cp2k(value, unit_str, defaults, power) RESULT(res)
1210 REAL(kind=dp), INTENT(in) :: value
1211 CHARACTER(len=*), INTENT(in) :: unit_str
1212 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1213 INTEGER, INTENT(in), OPTIONAL :: power
1214 REAL(kind=dp) :: res
1215
1216 TYPE(cp_unit_type) :: my_unit
1217
1218 CALL cp_unit_create(my_unit, unit_str)
1219 IF (PRESENT(defaults)) THEN
1220 res = cp_unit_to_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1221 power=power)
1222 ELSE
1223 res = cp_unit_to_cp2k1(value=value, unit=my_unit, power=power)
1224 END IF
1225 CALL cp_unit_release(my_unit)
1226 END FUNCTION cp_unit_to_cp2k
1227
1228! **************************************************************************************************
1229!> \brief converts from the internal cp2k units to the given unit
1230!> \param value the value to convert
1231!> \param unit_str the unit of the result as string
1232!> \param defaults the defaults unit for those that are left free
1233!> (cp_units_none)
1234!> \param power the power of the unit (defaults to 1)
1235!> \return ...
1236!> \author fawzi
1237! **************************************************************************************************
1238 FUNCTION cp_unit_from_cp2k(value, unit_str, defaults, power) RESULT(res)
1239 REAL(kind=dp), INTENT(in) :: value
1240 CHARACTER(len=*), INTENT(in) :: unit_str
1241 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1242 INTEGER, INTENT(in), OPTIONAL :: power
1243 REAL(kind=dp) :: res
1244
1245 TYPE(cp_unit_type) :: my_unit
1246
1247 CALL cp_unit_create(my_unit, unit_str)
1248 IF (PRESENT(defaults)) THEN
1249 res = cp_unit_from_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1250 power=power)
1251 ELSE
1252 res = cp_unit_from_cp2k1(value=value, unit=my_unit, power=power)
1253 END IF
1254 CALL cp_unit_release(my_unit)
1255 END FUNCTION cp_unit_from_cp2k
1256
1257! **************************************************************************************************
1258!> \brief returs true if the two units are compatible
1259!> \param ref_unit ...
1260!> \param unit ...
1261!> \return ...
1262!> \author Teodoro Laino [tlaino] - 11.2007 - University of Zurich
1263! **************************************************************************************************
1264 FUNCTION cp_unit_compatible(ref_unit, unit) RESULT(res)
1265 TYPE(cp_unit_type), INTENT(IN) :: ref_unit, unit
1266 LOGICAL :: res
1267
1268 INTEGER :: i
1269
1270 res = .true.
1271 DO i = 1, SIZE(ref_unit%kind_id)
1272 IF (ref_unit%kind_id(i) == unit%kind_id(i)) cycle
1273 IF ((ref_unit%kind_id(1) == cp_ukind_undef) .AND. (all(ref_unit%kind_id(2:) == cp_ukind_none))) cycle
1274 res = .false.
1275 EXIT
1276 END DO
1277
1278 END FUNCTION cp_unit_compatible
1279
1280! **************************************************************************************************
1281!> \brief initializes the given unit set
1282!> \param unit_set the set to initialize
1283!> \param name the name of the set, used for the dafault initialization of
1284!> the various units
1285!> \author fawzi
1286! **************************************************************************************************
1287 SUBROUTINE cp_unit_set_create(unit_set, name)
1288 TYPE(cp_unit_set_type), INTENT(OUT) :: unit_set
1289 CHARACTER(len=*), INTENT(in) :: name
1290
1291 CHARACTER(len=cp_unit_desc_length) :: my_name
1292 INTEGER :: i
1293
1294 my_name = name
1295 CALL uppercase(my_name)
1296
1297 DO i = 1, cp_ukind_max
1298 NULLIFY (unit_set%units(i)%unit)
1299 ALLOCATE (unit_set%units(i)%unit)
1300 END DO
1301 DO i = 1, cp_ukind_max
1302 SELECT CASE (name)
1303 CASE ('ATOM', 'ATOMIC', 'INTERNAL', 'CP2K')
1304 IF (i == cp_ukind_angle) THEN
1305 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1306 unit_id=[cp_units_rad], power=[1])
1307 ELSE
1308 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1309 unit_id=[cp_units_au], power=[1])
1310 END IF
1311 CASE ('OUTPUT')
1312 SELECT CASE (i)
1313 CASE (cp_ukind_undef)
1314 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_none], &
1315 power=[1])
1316 CASE (cp_ukind_energy)
1317 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_hartree], &
1318 power=[1])
1319 CASE (cp_ukind_length)
1320 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_angstrom], &
1321 power=[1])
1323 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_k], &
1324 power=[1])
1325 CASE (cp_ukind_angle)
1326 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_deg], &
1327 power=[1])
1328 CASE (cp_ukind_pressure)
1329 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_bar], &
1330 power=[1])
1331 CASE (cp_ukind_time)
1332 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_fs], &
1333 power=[1])
1334 CASE (cp_ukind_mass)
1335 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_amu], &
1336 power=[1])
1337 CASE (cp_ukind_potential)
1338 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_volt], &
1339 power=[1])
1340 CASE (cp_ukind_force)
1341 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_newton], &
1342 power=[1])
1343 CASE (cp_ukind_efield)
1344 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_volt_per_m], &
1345 power=[1])
1346 CASE default
1347 cpabort("unhandled unit type "//trim(cp_to_string(i)))
1348 EXIT
1349 END SELECT
1350 CASE default
1351 cpabort('unknown parameter set name '//trim(name))
1352 END SELECT
1353 END DO
1354 END SUBROUTINE cp_unit_set_create
1355
1356! **************************************************************************************************
1357!> \brief releases the given unit set
1358!> \param unit_set the unit set to release
1359!> \author fawzi
1360! **************************************************************************************************
1361 SUBROUTINE cp_unit_set_release(unit_set)
1362 TYPE(cp_unit_set_type), INTENT(INOUT) :: unit_set
1363
1364 INTEGER :: i
1365
1366 DO i = 1, SIZE(unit_set%units)
1367 CALL cp_unit_release(unit_set%units(i)%unit)
1368 DEALLOCATE (unit_set%units(i)%unit)
1369 END DO
1370
1371 END SUBROUTINE cp_unit_set_release
1372
1373! **************************************************************************************************
1374!> \brief Exports all available units as XML.
1375!> \param iw ...
1376!> \author Ole Schuett
1377! **************************************************************************************************
1378 SUBROUTINE export_units_as_xml(iw)
1379 INTEGER, INTENT(IN) :: iw
1380
1381 CALL format_units_as_xml("energy", s2a("hartree", "wavenumber_e", "joule", "kcalmol", &
1382 "kjmol", "Ry", "eV", "keV", "K_e"), iw)
1383 CALL format_units_as_xml("length", s2a("bohr", "m", "pm", "nm", "angstrom"), iw)
1384 CALL format_units_as_xml("temperature", s2a("K", "au_temp"), iw)
1385 CALL format_units_as_xml("pressure", s2a("bar", "atm", "kbar", "Pa", "MPa", "GPa", "au_p"), iw)
1386 CALL format_units_as_xml("angle", s2a("rad", "deg"), iw)
1387 CALL format_units_as_xml("time", s2a("s", "fs", "ps", "au_t", "wavenumber_t"), iw)
1388 CALL format_units_as_xml("mass", s2a("kg", "amu", "m_e"), iw)
1389 CALL format_units_as_xml("potential", s2a("volt", "au_pot"), iw)
1390 CALL format_units_as_xml("force", s2a("N", "Newton", "mN", "mNewton", "au_f"), iw)
1391 CALL format_units_as_xml("efield", s2a("Vm-1", "Vnm-1", "VA-1", "volt_per_m", "volt_per_nm", &
1392 "volt_per_angstrom", "au_efield"), iw)
1393
1394 END SUBROUTINE export_units_as_xml
1395
1396! **************************************************************************************************
1397!> \brief Format units as xml.
1398!> \param unit_kind ...
1399!> \param units_set ...
1400!> \param iw ...
1401!> \author Ole Schuett
1402! **************************************************************************************************
1403 SUBROUTINE format_units_as_xml(unit_kind, units_set, iw)
1404 CHARACTER(LEN=*), INTENT(IN) :: unit_kind
1405 CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: units_set
1406 INTEGER, INTENT(IN) :: iw
1407
1408 INTEGER :: i
1409
1410 WRITE (iw, fmt='(T2,A)') '<UNIT_KIND name="'//trim(unit_kind)//'">'
1411 DO i = 1, SIZE(units_set)
1412 WRITE (iw, fmt='(T3,A)') '<UNIT>'//trim(units_set(i))//'</UNIT>'
1413 END DO
1414 WRITE (iw, fmt='(T3,A)') '<UNIT>'//trim(unit_kind)//'</UNIT>' ! internal unit
1415 WRITE (iw, fmt='(T2,A)') '</UNIT_KIND>'
1416 END SUBROUTINE format_units_as_xml
1417
1418END MODULE cp_units
various routines to log and control the output. The idea is that decisions about where to log should ...
unit conversion facility
Definition cp_units.F:30
integer, parameter, public cp_units_wavenum
Definition cp_units.F:72
integer, parameter, public cp_ukind_none
Definition cp_units.F:50
integer, parameter, public cp_units_fs
Definition cp_units.F:105
integer, parameter, public cp_units_kev
Definition cp_units.F:72
integer, parameter, public cp_units_m
Definition cp_units.F:83
integer, parameter, public cp_units_k
Definition cp_units.F:90
integer, parameter, public cp_ukind_potential
Definition cp_units.F:50
integer, parameter, public cp_units_mpa
Definition cp_units.F:97
integer, parameter, public cp_units_volt_per_angstrom
Definition cp_units.F:118
integer, parameter, public cp_ukind_undef
Definition cp_units.F:50
integer, parameter, public cp_units_none
Definition cp_units.F:65
integer, parameter, public cp_units_angstrom
Definition cp_units.F:83
integer, parameter, public cp_units_volt
Definition cp_units.F:111
character(len=cp_unit_desc_length) function, public cp_unit_desc(unit, defaults, accept_undefined)
returns the "name" of the given unit
Definition cp_units.F:1096
real(kind=dp) function, public cp_unit_to_cp2k1(value, unit, defaults, power)
transform a value to the internal cp2k units
Definition cp_units.F:1145
integer, parameter, public cp_units_au
Definition cp_units.F:65
integer, parameter, public cp_ukind_length
Definition cp_units.F:50
integer, parameter, public cp_ukind_temperature
Definition cp_units.F:50
real(kind=dp) function, public cp_unit_from_cp2k1(value, unit, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1181
integer, parameter, public cp_units_hartree
Definition cp_units.F:72
integer, parameter, public cp_units_nm
Definition cp_units.F:83
integer, parameter, public cp_units_bar
Definition cp_units.F:93
integer, parameter, public cp_units_amu
Definition cp_units.F:68
integer, parameter, public cp_ukind_time
Definition cp_units.F:50
integer, parameter, public cp_ukind_energy
Definition cp_units.F:50
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1239
subroutine, public cp_unit_create(unit, string)
creates a unit parsing a string
Definition cp_units.F:168
integer, parameter, public cp_ukind_efield
Definition cp_units.F:50
integer, parameter, public cp_ukind_force
Definition cp_units.F:50
integer, parameter, public cp_unit_desc_length
Definition cp_units.F:122
integer, parameter, public cp_units_kbar
Definition cp_units.F:95
integer, parameter, public cp_units_newton
Definition cp_units.F:114
integer, parameter, public cp_units_ps
Definition cp_units.F:105
integer, parameter, public cp_units_ev
Definition cp_units.F:72
integer, parameter, public cp_ukind_max
Definition cp_units.F:50
integer, parameter, public cp_units_mnewton
Definition cp_units.F:114
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
Definition cp_units.F:1210
integer, parameter, public cp_units_atm
Definition cp_units.F:94
integer, parameter, public cp_units_deg
Definition cp_units.F:101
subroutine, public cp_unit_set_release(unit_set)
releases the given unit set
Definition cp_units.F:1362
integer, parameter, public cp_units_ry
Definition cp_units.F:72
integer, parameter, public cp_units_kcalmol
Definition cp_units.F:72
integer, parameter, public cp_units_rad
Definition cp_units.F:101
integer, parameter, public cp_units_pa
Definition cp_units.F:96
integer, parameter, public cp_units_jmol
Definition cp_units.F:72
integer, parameter, public cp_units_joule
Definition cp_units.F:72
integer, parameter, public cp_unit_basic_desc_length
Definition cp_units.F:122
subroutine, public cp_unit_set_create(unit_set, name)
initializes the given unit set
Definition cp_units.F:1288
integer, parameter, public cp_units_volt_per_m
Definition cp_units.F:118
integer, parameter, public cp_units_gpa
Definition cp_units.F:98
integer, parameter, public cp_units_bohr
Definition cp_units.F:83
subroutine, public export_units_as_xml(iw)
Exports all available units as XML.
Definition cp_units.F:1379
integer, parameter, public cp_units_volt_per_nm
Definition cp_units.F:118
integer, parameter, public cp_units_kjmol
Definition cp_units.F:72
integer, parameter, public cp_units_wn
Definition cp_units.F:105
integer, parameter, public cp_units_m_e
Definition cp_units.F:68
integer, parameter, public cp_units_pm
Definition cp_units.F:83
integer, parameter, public cp_units_kg
Definition cp_units.F:68
integer, parameter, public cp_ukind_mass
Definition cp_units.F:50
logical function, public cp_unit_compatible(ref_unit, unit)
returs true if the two units are compatible
Definition cp_units.F:1265
elemental subroutine, public cp_unit_release(unit)
releases the given unit
Definition cp_units.F:566
integer, parameter, public cp_ukind_angle
Definition cp_units.F:50
integer, parameter, public cp_units_s
Definition cp_units.F:105
integer, parameter, public cp_unit_max_kinds
Definition cp_units.F:122
integer, parameter, public cp_ukind_pressure
Definition cp_units.F:50
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public radians
real(kind=dp), parameter, public twopi
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public kcalmol
Definition physcon.F:171
real(kind=dp), parameter, public femtoseconds
Definition physcon.F:153
real(kind=dp), parameter, public atm
Definition physcon.F:180
real(kind=dp), parameter, public joule
Definition physcon.F:159
real(kind=dp), parameter, public kelvin
Definition physcon.F:165
real(kind=dp), parameter, public newton
Definition physcon.F:162
real(kind=dp), parameter, public seconds
Definition physcon.F:150
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public e_mass
Definition physcon.F:109
real(kind=dp), parameter, public picoseconds
Definition physcon.F:156
real(kind=dp), parameter, public wavenumbers
Definition physcon.F:192
real(kind=dp), parameter, public bar
Definition physcon.F:177
real(kind=dp), parameter, public massunit
Definition physcon.F:141
real(kind=dp), parameter, public kjmol
Definition physcon.F:168
real(kind=dp), parameter, public pascal
Definition physcon.F:174
real(kind=dp), parameter, public bohr
Definition physcon.F:147
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
stores the default units to be used
Definition cp_units.F:155
stores a unit
Definition cp_units.F:137