(git:a145afa)
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) THEN
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 END IF
658 CASE default
659 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
660 END SELECT
661 END SUBROUTINE cp_basic_unit_check
662
663! **************************************************************************************************
664!> \brief converts a value to the internal cp2k units
665!> \param value the value to convert
666!> \param basic_kind the kind of the unit of the value
667!> \param basic_unit the unit of the value
668!> \param power the power of the unit (defaults to 1)
669!> \return ...
670!> \author fawzi
671! **************************************************************************************************
672 FUNCTION cp_basic_unit_to_cp2k(value, basic_kind, basic_unit, power) RESULT(res)
673 REAL(kind=dp), INTENT(in) :: value
674 INTEGER, INTENT(in) :: basic_kind, basic_unit
675 INTEGER, INTENT(in), OPTIONAL :: power
676 REAL(kind=dp) :: res
677
678 INTEGER :: my_power
679
680 my_power = 1
681 IF (PRESENT(power)) my_power = power
682 IF (basic_unit == cp_units_none .AND. basic_kind /= cp_ukind_undef) THEN
683 IF (basic_kind /= cp_units_none) THEN
684 CALL cp_abort(__location__, &
685 "unit not yet fully specified, unit of kind "// &
686 trim(cp_to_string(basic_unit)))
687 END IF
688 END IF
689 SELECT CASE (basic_kind)
690 CASE (cp_ukind_undef)
691 SELECT CASE (basic_unit)
692 CASE (cp_units_none)
693 res = value
694 CASE default
695 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
696 END SELECT
697 CASE (cp_ukind_energy)
698 SELECT CASE (basic_unit)
700 res = value
701 CASE (cp_units_wavenum)
702 res = wavenumbers**(-my_power)*value
703 CASE (cp_units_joule)
704 res = joule**(-my_power)*value
705 CASE (cp_units_kcalmol)
706 res = kcalmol**(-my_power)*value
707 CASE (cp_units_kjmol)
708 res = kjmol**(-my_power)*value
709 CASE (cp_units_jmol)
710 res = (kjmol*1.0e+3_dp)**(-my_power)*value
711 CASE (cp_units_ry)
712 res = 0.5_dp**my_power*value
713 CASE (cp_units_ev)
714 res = evolt**(-my_power)*value
715 CASE (cp_units_kev)
716 res = (1.0e-3_dp*evolt)**(-my_power)*value
717 CASE (cp_units_k)
718 res = kelvin**(-my_power)*value
719 CASE default
720 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
721 END SELECT
722 CASE (cp_ukind_length)
723 SELECT CASE (basic_unit)
725 res = value
726 CASE (cp_units_m)
727 res = value*(1.0e10_dp*bohr)**my_power
728 CASE (cp_units_pm)
729 res = value*(0.01_dp*bohr)**my_power
730 CASE (cp_units_nm)
731 res = value*(10.0_dp*bohr)**my_power
732 CASE (cp_units_angstrom)
733 res = value*bohr**my_power
734 CASE default
735 cpabort("unknown length unit:"//trim(cp_to_string(basic_unit)))
736 END SELECT
738 SELECT CASE (basic_unit)
739 CASE (cp_units_k)
740 res = kelvin**(-my_power)*value
741 CASE (cp_units_au)
742 res = value
743 CASE default
744 cpabort("unknown temperature unit:"//trim(cp_to_string(basic_unit)))
745 END SELECT
746 CASE (cp_ukind_pressure)
747 SELECT CASE (basic_unit)
748 CASE (cp_units_bar)
749 res = bar**(-my_power)*value
750 CASE (cp_units_atm)
751 res = atm**(-my_power)*value
752 CASE (cp_units_kbar)
753 res = (1.0e-3_dp*bar)**(-my_power)*value
754 CASE (cp_units_pa)
755 res = pascal**(-my_power)*value
756 CASE (cp_units_mpa)
757 res = (1.0e-6_dp*pascal)**(-my_power)*value
758 CASE (cp_units_gpa)
759 res = (1.0e-9_dp*pascal)**(-my_power)*value
760 CASE (cp_units_au)
761 res = value
762 CASE default
763 cpabort("unknown pressure unit:"//trim(cp_to_string(basic_unit)))
764 END SELECT
765 CASE (cp_ukind_angle)
766 SELECT CASE (basic_unit)
767 CASE (cp_units_rad)
768 res = value
769 CASE (cp_units_deg)
770 res = value*(radians)**my_power
771 CASE default
772 cpabort("unknown angle unit:"//trim(cp_to_string(basic_unit)))
773 END SELECT
774 CASE (cp_ukind_time)
775 SELECT CASE (basic_unit)
776 CASE (cp_units_s)
777 res = value*seconds**(-my_power)
778 CASE (cp_units_fs)
779 res = value*femtoseconds**(-my_power)
780 CASE (cp_units_ps)
781 res = value*picoseconds**(-my_power)
782 CASE (cp_units_au)
783 res = value
784 CASE (cp_units_wn)
785 res = (twopi*wavenumbers)**(my_power)/value
786 CASE default
787 cpabort("unknown time unit:"//trim(cp_to_string(basic_unit)))
788 END SELECT
789 CASE (cp_ukind_mass)
790 SELECT CASE (basic_unit)
791 CASE (cp_units_kg)
792 res = e_mass**my_power*value
793 CASE (cp_units_amu)
794 res = massunit**my_power*value
796 res = value
797 CASE default
798 cpabort("unknown mass unit:"//trim(cp_to_string(basic_unit)))
799 END SELECT
800 CASE (cp_ukind_potential)
801 SELECT CASE (basic_unit)
802 CASE (cp_units_volt)
803 res = evolt**(-my_power)*value
804 CASE (cp_units_au)
805 res = value
806 CASE default
807 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
808 END SELECT
809 CASE (cp_ukind_force)
810 SELECT CASE (basic_unit)
811 CASE (cp_units_newton)
812 res = value*newton**(-my_power)
813 CASE (cp_units_mnewton)
814 res = value*(1.0e+3*newton)**(-my_power)
815 CASE (cp_units_au)
816 res = value
817 CASE default
818 cpabort("unknown force unit:"//trim(cp_to_string(basic_unit)))
819 END SELECT
820 CASE (cp_ukind_efield)
821 SELECT CASE (basic_unit)
823 res = (1.0e+10_dp*evolt*bohr)**(-my_power)*value
825 res = (10.0_dp*evolt*bohr)**(-my_power)*value
827 res = (evolt*bohr)**(-my_power)*value
828 CASE (cp_units_au)
829 res = value
830 CASE default
831 cpabort("unknown electric field unit:"//trim(cp_to_string(basic_unit)))
832 END SELECT
833 CASE (cp_ukind_none)
834 CALL cp_abort(__location__, &
835 "if the kind of the unit is none also unit must be undefined,not:" &
836 //trim(cp_to_string(basic_unit)))
837 CASE default
838 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
839 END SELECT
840 END FUNCTION cp_basic_unit_to_cp2k
841
842! **************************************************************************************************
843!> \brief returns the label of the current basic unit
844!> \param basic_kind the kind of the unit of the value
845!> \param basic_unit the unit of the value
846!> \param power the power of the unit (defaults to 1)
847!> \param accept_undefined ...
848!> \return ...
849!> \author fawzi
850! **************************************************************************************************
851 FUNCTION cp_basic_unit_desc(basic_kind, basic_unit, power, accept_undefined) &
852 result(res)
853 INTEGER, INTENT(in) :: basic_kind, basic_unit
854 INTEGER, INTENT(in), OPTIONAL :: power
855 LOGICAL, INTENT(in), OPTIONAL :: accept_undefined
856 CHARACTER(len=cp_unit_basic_desc_length) :: res
857
858 INTEGER :: a, my_power
859 LOGICAL :: my_accept_undefined
860
861 my_power = 1
862 res = ""
863 my_accept_undefined = .false.
864 IF (accept_undefined) my_accept_undefined = accept_undefined
865 IF (PRESENT(power)) my_power = power
866 IF (basic_unit == cp_units_none) THEN
867 IF (.NOT. my_accept_undefined .AND. basic_kind == cp_units_none) THEN
868 CALL cp_abort(__location__, "unit not yet fully specified, unit of kind "// &
869 trim(cp_to_string(basic_kind)))
870 END IF
871 END IF
872 SELECT CASE (basic_kind)
873 CASE (cp_ukind_undef)
874 SELECT CASE (basic_unit)
875 CASE (cp_units_none)
876 res = "internal_cp2k"
877 CASE DEFAULT
878 CALL cp_abort(__location__, &
879 "unit not yet fully specified, unit of kind "// &
880 trim(res))
881 END SELECT
882 CASE (cp_ukind_energy)
883 SELECT CASE (basic_unit)
885 res = "hartree"
886 CASE (cp_units_wavenum)
887 res = "wavenumber_e"
888 CASE (cp_units_joule)
889 res = "joule"
890 CASE (cp_units_kcalmol)
891 res = "kcalmol"
892 CASE (cp_units_kjmol)
893 res = "kjmol"
894 CASE (cp_units_jmol)
895 res = "jmol"
896 CASE (cp_units_ry)
897 res = "Ry"
898 CASE (cp_units_ev)
899 res = "eV"
900 CASE (cp_units_kev)
901 res = "keV"
902 CASE (cp_units_k)
903 res = "K_e"
904 CASE (cp_units_none)
905 res = "energy"
906 IF (.NOT. my_accept_undefined) THEN
907 CALL cp_abort(__location__, &
908 "unit not yet fully specified, unit of kind "// &
909 trim(res))
910 END IF
911 CASE default
912 cpabort("unknown energy unit:"//trim(cp_to_string(basic_unit)))
913 END SELECT
914 CASE (cp_ukind_length)
915 SELECT CASE (basic_unit)
917 res = "bohr"
918 CASE (cp_units_m)
919 res = "m"
920 CASE (cp_units_pm)
921 res = "pm"
922 CASE (cp_units_nm)
923 res = "nm"
924 CASE (cp_units_angstrom)
925 res = "angstrom"
926 CASE default
927 res = "length"
928 cpabort("unknown length unit:"//trim(cp_to_string(basic_unit)))
929 END SELECT
931 SELECT CASE (basic_unit)
932 CASE (cp_units_k)
933 res = "K"
934 CASE (cp_units_au)
935 res = "au_temp"
936 CASE (cp_units_none)
937 res = "temperature"
938 IF (.NOT. my_accept_undefined) THEN
939 CALL cp_abort(__location__, &
940 "unit not yet fully specified, unit of kind "// &
941 trim(res))
942 END IF
943 CASE default
944 cpabort("unknown temperature unit:"//trim(cp_to_string(basic_unit)))
945 END SELECT
946 CASE (cp_ukind_pressure)
947 SELECT CASE (basic_unit)
948 CASE (cp_units_bar)
949 res = "bar"
950 CASE (cp_units_atm)
951 res = "atm"
952 CASE (cp_units_kbar)
953 res = "kbar"
954 CASE (cp_units_pa)
955 res = "Pa"
956 CASE (cp_units_mpa)
957 res = "MPa"
958 CASE (cp_units_gpa)
959 res = "GPa"
960 CASE (cp_units_au)
961 res = "au_p"
962 CASE (cp_units_none)
963 res = "pressure"
964 IF (.NOT. my_accept_undefined) THEN
965 CALL cp_abort(__location__, &
966 "unit not yet fully specified, unit of kind "// &
967 trim(res))
968 END IF
969 CASE default
970 cpabort("unknown pressure unit:"//trim(cp_to_string(basic_unit)))
971 END SELECT
972 CASE (cp_ukind_angle)
973 SELECT CASE (basic_unit)
974 CASE (cp_units_rad)
975 res = "rad"
976 CASE (cp_units_deg)
977 res = "deg"
978 CASE (cp_units_none)
979 res = "angle"
980 IF (.NOT. my_accept_undefined) THEN
981 CALL cp_abort(__location__, &
982 "unit not yet fully specified, unit of kind "// &
983 trim(res))
984 END IF
985 CASE default
986 cpabort("unknown angle unit:"//trim(cp_to_string(basic_unit)))
987 END SELECT
988 CASE (cp_ukind_time)
989 SELECT CASE (basic_unit)
990 CASE (cp_units_s)
991 res = "s"
992 CASE (cp_units_fs)
993 res = "fs"
994 CASE (cp_units_ps)
995 res = "ps"
996 CASE (cp_units_au)
997 res = "au_t"
998 CASE (cp_units_wn)
999 res = "wavenumber_t"
1000 CASE (cp_units_none)
1001 res = "time"
1002 IF (.NOT. my_accept_undefined) THEN
1003 CALL cp_abort(__location__, &
1004 "unit not yet fully specified, unit of kind "// &
1005 trim(res))
1006 END IF
1007 CASE default
1008 cpabort("unknown time unit:"//trim(cp_to_string(basic_unit)))
1009 END SELECT
1010 CASE (cp_ukind_mass)
1011 SELECT CASE (basic_unit)
1012 CASE (cp_units_kg)
1013 res = "kg"
1014 CASE (cp_units_amu)
1015 res = "amu"
1017 res = "m_e"
1018 CASE (cp_units_none)
1019 res = "mass"
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 mass unit:"//trim(cp_to_string(basic_unit)))
1027 END SELECT
1028 CASE (cp_ukind_potential)
1029 SELECT CASE (basic_unit)
1030 CASE (cp_units_volt)
1031 res = "volt"
1032 CASE (cp_units_au)
1033 res = "au_pot"
1034 CASE (cp_units_none)
1035 res = "potential"
1036 IF (.NOT. my_accept_undefined) THEN
1037 CALL cp_abort(__location__, &
1038 "unit not yet fully specified, unit of kind "// &
1039 trim(res))
1040 END IF
1041 CASE default
1042 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
1043 END SELECT
1044 CASE (cp_ukind_force)
1045 SELECT CASE (basic_unit)
1046 CASE (cp_units_newton)
1047 res = "N"
1048 CASE (cp_units_mnewton)
1049 res = "mN"
1050 CASE (cp_units_au)
1051 res = "au_f"
1052 CASE (cp_units_none)
1053 res = "force"
1054 IF (.NOT. my_accept_undefined) THEN
1055 CALL cp_abort(__location__, &
1056 "unit not yet fully specified, unit of kind "// &
1057 trim(res))
1058 END IF
1059 CASE default
1060 cpabort("unknown potential unit:"//trim(cp_to_string(basic_unit)))
1061 END SELECT
1062 CASE (cp_ukind_efield)
1063 SELECT CASE (basic_unit)
1064 CASE (cp_units_volt_per_m)
1065 res = "Vm-1"
1067 res = "Vnm-1"
1069 res = "Vangstrom-1"
1070 CASE (cp_units_au)
1071 res = "au_efield"
1072 CASE (cp_units_none)
1073 res = "electric field"
1074 IF (.NOT. my_accept_undefined) THEN
1075 CALL cp_abort(__location__, &
1076 "unit not yet fully specified, unit of kind "// &
1077 trim(res))
1078 END IF
1079 CASE default
1080 cpabort("unknown efield unit:"//trim(cp_to_string(basic_unit)))
1081 END SELECT
1082 CASE (cp_ukind_none)
1083 CALL cp_abort(__location__, &
1084 "if the kind of the unit is none also unit must be undefined,not:" &
1085 //trim(cp_to_string(basic_unit)))
1086 CASE default
1087 cpabort("unknown kind of unit:"//trim(cp_to_string(basic_kind)))
1088 END SELECT
1089 IF (my_power /= 1) THEN
1090 a = len_trim(res)
1091 cpassert(len(res) - a >= 3)
1092 WRITE (res(a + 1:), "('^',i3)") my_power
1093 CALL compress(res, .true.)
1094 END IF
1095 END FUNCTION cp_basic_unit_desc
1096
1097! **************************************************************************************************
1098!> \brief returns the "name" of the given unit
1099!> \param unit the unit to describe
1100!> \param defaults defaults for the undefined units, optional
1101!> \param accept_undefined if defaults is not present or is not associated
1102!> whether undefined units should be accepted (defaults to false)
1103!> \return ...
1104!> \author fawzi
1105! **************************************************************************************************
1106 FUNCTION cp_unit_desc(unit, defaults, accept_undefined) &
1107 result(res)
1108 TYPE(cp_unit_type), INTENT(IN) :: unit
1109 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1110 LOGICAL, INTENT(in), OPTIONAL :: accept_undefined
1111 CHARACTER(len=cp_unit_desc_length) :: res
1112
1113 INTEGER :: i, my_unit, pos
1114 LOGICAL :: check, has_defaults, my_accept_undefined
1115
1116 res = ""
1117 pos = 1
1118 my_accept_undefined = .false.
1119 IF (PRESENT(accept_undefined)) my_accept_undefined = accept_undefined
1120 DO i = 1, unit%n_kinds
1121 cpassert(unit%kind_id(i) /= 0)
1122 cpassert(pos < len(res))
1123 my_unit = unit%unit_id(i)
1124 has_defaults = .false.
1125 IF (PRESENT(defaults)) has_defaults = ASSOCIATED(defaults%units(1)%unit)
1126 IF (my_unit == 0) THEN
1127 IF (has_defaults) THEN
1128 my_unit = defaults%units(unit%kind_id(i))%unit%unit_id(1)
1129 ELSE
1130 check = my_accept_undefined .OR. unit%kind_id(i) /= 0
1131 cpassert(check)
1132 END IF
1133 END IF
1134 IF (i > 1) THEN
1135 res(pos:pos) = "*"
1136 pos = pos + 1
1137 END IF
1138 res(pos:) = trim(cp_basic_unit_desc(basic_kind=unit%kind_id(i), &
1139 basic_unit=my_unit, accept_undefined=my_accept_undefined, &
1140 power=unit%power(i)))
1141 pos = len_trim(res) + 1
1142 END DO
1143
1144 END FUNCTION cp_unit_desc
1145
1146! **************************************************************************************************
1147!> \brief transform a value to the internal cp2k units
1148!> \param value the value to convert
1149!> \param unit the unit of the result
1150!> \param defaults the defaults unit for those that are left free
1151!> (cp_units_none)
1152!> \param power the power of the unit (defaults to 1)
1153!> \return ...
1154!> \author fawzi
1155! **************************************************************************************************
1156 FUNCTION cp_unit_to_cp2k1(value, unit, defaults, power) RESULT(res)
1157 REAL(kind=dp), INTENT(in) :: value
1158 TYPE(cp_unit_type), INTENT(IN) :: unit
1159 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1160 INTEGER, INTENT(in), OPTIONAL :: power
1161 REAL(kind=dp) :: res
1162
1163 INTEGER :: i_unit, my_basic_unit, my_power
1164
1165 my_power = 1
1166 IF (PRESENT(power)) my_power = power
1167 res = value
1168 DO i_unit = 1, unit%n_kinds
1169 cpassert(unit%kind_id(i_unit) > 0)
1170 my_basic_unit = unit%unit_id(i_unit)
1171 IF (my_basic_unit == 0 .AND. unit%kind_id(i_unit) /= cp_ukind_undef) THEN
1172 cpassert(PRESENT(defaults))
1173 cpassert(ASSOCIATED(defaults%units(unit%kind_id(i_unit))%unit))
1174 my_basic_unit = defaults%units(unit%kind_id(i_unit))%unit%unit_id(1)
1175 END IF
1176 res = cp_basic_unit_to_cp2k(value=res, basic_unit=my_basic_unit, &
1177 basic_kind=unit%kind_id(i_unit), &
1178 power=my_power*unit%power(i_unit))
1179 END DO
1180 END FUNCTION cp_unit_to_cp2k1
1181
1182! **************************************************************************************************
1183!> \brief converts from the internal cp2k units to the given unit
1184!> \param value the value to convert
1185!> \param unit the unit of the result
1186!> \param defaults the defaults unit for those that are left free
1187!> (cp_units_none)
1188!> \param power the power of the unit (defaults to 1)
1189!> \return ...
1190!> \author fawzi
1191! **************************************************************************************************
1192 FUNCTION cp_unit_from_cp2k1(value, unit, defaults, power) RESULT(res)
1193 REAL(kind=dp), INTENT(in) :: value
1194 TYPE(cp_unit_type), INTENT(IN) :: unit
1195 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1196 INTEGER, INTENT(in), OPTIONAL :: power
1197 REAL(kind=dp) :: res
1198
1199 INTEGER :: my_power
1200
1201 my_power = 1
1202 IF (PRESENT(power)) my_power = power
1203 IF (PRESENT(defaults)) THEN
1204 res = cp_unit_to_cp2k1(value=value, unit=unit, defaults=defaults, &
1205 power=-my_power)
1206 ELSE
1207 res = cp_unit_to_cp2k1(value=value, unit=unit, power=-my_power)
1208 END IF
1209 END FUNCTION cp_unit_from_cp2k1
1210
1211! **************************************************************************************************
1212!> \brief converts to the internal cp2k units to the given unit
1213!> \param value the value to convert
1214!> \param unit_str the unit of the result as string
1215!> \param defaults the defaults unit for those that are left free
1216!> (cp_units_none)
1217!> \param power the power of the unit (defaults to 1)
1218!> \return ...
1219!> \author fawzi
1220! **************************************************************************************************
1221 FUNCTION cp_unit_to_cp2k(value, unit_str, defaults, power) RESULT(res)
1222 REAL(kind=dp), INTENT(in) :: value
1223 CHARACTER(len=*), INTENT(in) :: unit_str
1224 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1225 INTEGER, INTENT(in), OPTIONAL :: power
1226 REAL(kind=dp) :: res
1227
1228 TYPE(cp_unit_type) :: my_unit
1229
1230 CALL cp_unit_create(my_unit, unit_str)
1231 IF (PRESENT(defaults)) THEN
1232 res = cp_unit_to_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1233 power=power)
1234 ELSE
1235 res = cp_unit_to_cp2k1(value=value, unit=my_unit, power=power)
1236 END IF
1237 CALL cp_unit_release(my_unit)
1238 END FUNCTION cp_unit_to_cp2k
1239
1240! **************************************************************************************************
1241!> \brief converts from the internal cp2k units to the given unit
1242!> \param value the value to convert
1243!> \param unit_str the unit of the result as string
1244!> \param defaults the defaults unit for those that are left free
1245!> (cp_units_none)
1246!> \param power the power of the unit (defaults to 1)
1247!> \return ...
1248!> \author fawzi
1249! **************************************************************************************************
1250 FUNCTION cp_unit_from_cp2k(value, unit_str, defaults, power) RESULT(res)
1251 REAL(kind=dp), INTENT(in) :: value
1252 CHARACTER(len=*), INTENT(in) :: unit_str
1253 TYPE(cp_unit_set_type), INTENT(IN), OPTIONAL :: defaults
1254 INTEGER, INTENT(in), OPTIONAL :: power
1255 REAL(kind=dp) :: res
1256
1257 TYPE(cp_unit_type) :: my_unit
1258
1259 CALL cp_unit_create(my_unit, unit_str)
1260 IF (PRESENT(defaults)) THEN
1261 res = cp_unit_from_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1262 power=power)
1263 ELSE
1264 res = cp_unit_from_cp2k1(value=value, unit=my_unit, power=power)
1265 END IF
1266 CALL cp_unit_release(my_unit)
1267 END FUNCTION cp_unit_from_cp2k
1268
1269! **************************************************************************************************
1270!> \brief returs true if the two units are compatible
1271!> \param ref_unit ...
1272!> \param unit ...
1273!> \return ...
1274!> \author Teodoro Laino [tlaino] - 11.2007 - University of Zurich
1275! **************************************************************************************************
1276 FUNCTION cp_unit_compatible(ref_unit, unit) RESULT(res)
1277 TYPE(cp_unit_type), INTENT(IN) :: ref_unit, unit
1278 LOGICAL :: res
1279
1280 INTEGER :: i
1281
1282 res = .true.
1283 DO i = 1, SIZE(ref_unit%kind_id)
1284 IF (ref_unit%kind_id(i) == unit%kind_id(i)) cycle
1285 IF ((ref_unit%kind_id(1) == cp_ukind_undef) .AND. (all(ref_unit%kind_id(2:) == cp_ukind_none))) cycle
1286 res = .false.
1287 EXIT
1288 END DO
1289
1290 END FUNCTION cp_unit_compatible
1291
1292! **************************************************************************************************
1293!> \brief initializes the given unit set
1294!> \param unit_set the set to initialize
1295!> \param name the name of the set, used for the dafault initialization of
1296!> the various units
1297!> \author fawzi
1298! **************************************************************************************************
1299 SUBROUTINE cp_unit_set_create(unit_set, name)
1300 TYPE(cp_unit_set_type), INTENT(OUT) :: unit_set
1301 CHARACTER(len=*), INTENT(in) :: name
1302
1303 CHARACTER(len=cp_unit_desc_length) :: my_name
1304 INTEGER :: i
1305
1306 my_name = name
1307 CALL uppercase(my_name)
1308
1309 DO i = 1, cp_ukind_max
1310 NULLIFY (unit_set%units(i)%unit)
1311 ALLOCATE (unit_set%units(i)%unit)
1312 END DO
1313 DO i = 1, cp_ukind_max
1314 SELECT CASE (name)
1315 CASE ('ATOM', 'ATOMIC', 'INTERNAL', 'CP2K')
1316 IF (i == cp_ukind_angle) THEN
1317 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1318 unit_id=[cp_units_rad], power=[1])
1319 ELSE
1320 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1321 unit_id=[cp_units_au], power=[1])
1322 END IF
1323 CASE ('OUTPUT')
1324 SELECT CASE (i)
1325 CASE (cp_ukind_undef)
1326 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_none], &
1327 power=[1])
1328 CASE (cp_ukind_energy)
1329 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_hartree], &
1330 power=[1])
1331 CASE (cp_ukind_length)
1332 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_angstrom], &
1333 power=[1])
1335 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_k], &
1336 power=[1])
1337 CASE (cp_ukind_angle)
1338 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_deg], &
1339 power=[1])
1340 CASE (cp_ukind_pressure)
1341 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_bar], &
1342 power=[1])
1343 CASE (cp_ukind_time)
1344 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_fs], &
1345 power=[1])
1346 CASE (cp_ukind_mass)
1347 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_amu], &
1348 power=[1])
1349 CASE (cp_ukind_potential)
1350 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_volt], &
1351 power=[1])
1352 CASE (cp_ukind_force)
1353 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_newton], &
1354 power=[1])
1355 CASE (cp_ukind_efield)
1356 CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_volt_per_m], &
1357 power=[1])
1358 CASE default
1359 cpabort("unhandled unit type "//trim(cp_to_string(i)))
1360 EXIT
1361 END SELECT
1362 CASE default
1363 cpabort('unknown parameter set name '//trim(name))
1364 END SELECT
1365 END DO
1366 END SUBROUTINE cp_unit_set_create
1367
1368! **************************************************************************************************
1369!> \brief releases the given unit set
1370!> \param unit_set the unit set to release
1371!> \author fawzi
1372! **************************************************************************************************
1373 SUBROUTINE cp_unit_set_release(unit_set)
1374 TYPE(cp_unit_set_type), INTENT(INOUT) :: unit_set
1375
1376 INTEGER :: i
1377
1378 DO i = 1, SIZE(unit_set%units)
1379 CALL cp_unit_release(unit_set%units(i)%unit)
1380 DEALLOCATE (unit_set%units(i)%unit)
1381 END DO
1382
1383 END SUBROUTINE cp_unit_set_release
1384
1385! **************************************************************************************************
1386!> \brief Exports all available units as XML.
1387!> \param iw ...
1388!> \author Ole Schuett
1389! **************************************************************************************************
1390 SUBROUTINE export_units_as_xml(iw)
1391 INTEGER, INTENT(IN) :: iw
1392
1393 CALL format_units_as_xml("energy", s2a("hartree", "wavenumber_e", "joule", "kcalmol", &
1394 "kjmol", "Ry", "eV", "keV", "K_e"), iw)
1395 CALL format_units_as_xml("length", s2a("bohr", "m", "pm", "nm", "angstrom"), iw)
1396 CALL format_units_as_xml("temperature", s2a("K", "au_temp"), iw)
1397 CALL format_units_as_xml("pressure", s2a("bar", "atm", "kbar", "Pa", "MPa", "GPa", "au_p"), iw)
1398 CALL format_units_as_xml("angle", s2a("rad", "deg"), iw)
1399 CALL format_units_as_xml("time", s2a("s", "fs", "ps", "au_t", "wavenumber_t"), iw)
1400 CALL format_units_as_xml("mass", s2a("kg", "amu", "m_e"), iw)
1401 CALL format_units_as_xml("potential", s2a("volt", "au_pot"), iw)
1402 CALL format_units_as_xml("force", s2a("N", "Newton", "mN", "mNewton", "au_f"), iw)
1403 CALL format_units_as_xml("efield", s2a("Vm-1", "Vnm-1", "VA-1", "volt_per_m", "volt_per_nm", &
1404 "volt_per_angstrom", "au_efield"), iw)
1405
1406 END SUBROUTINE export_units_as_xml
1407
1408! **************************************************************************************************
1409!> \brief Format units as xml.
1410!> \param unit_kind ...
1411!> \param units_set ...
1412!> \param iw ...
1413!> \author Ole Schuett
1414! **************************************************************************************************
1415 SUBROUTINE format_units_as_xml(unit_kind, units_set, iw)
1416 CHARACTER(LEN=*), INTENT(IN) :: unit_kind
1417 CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: units_set
1418 INTEGER, INTENT(IN) :: iw
1419
1420 INTEGER :: i
1421
1422 WRITE (iw, fmt='(T2,A)') '<UNIT_KIND name="'//trim(unit_kind)//'">'
1423 DO i = 1, SIZE(units_set)
1424 WRITE (iw, fmt='(T3,A)') '<UNIT>'//trim(units_set(i))//'</UNIT>'
1425 END DO
1426 WRITE (iw, fmt='(T3,A)') '<UNIT>'//trim(unit_kind)//'</UNIT>' ! internal unit
1427 WRITE (iw, fmt='(T2,A)') '</UNIT_KIND>'
1428 END SUBROUTINE format_units_as_xml
1429
1430END 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:1108
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:1157
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:1193
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:1251
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:1222
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:1374
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:1300
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:1391
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:1277
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