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