Line data Source code
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 : ! **************************************************************************************************
30 : MODULE cp_units
31 :
32 : USE cp_log_handling, ONLY: cp_to_string
33 : USE kinds, ONLY: dp
34 : USE mathconstants, ONLY: radians,&
35 : twopi
36 : USE physcon, ONLY: &
37 : a_bohr, atm, bar, bohr, debye, e_charge, e_mass, evolt, femtoseconds, joule, kcalmol, &
38 : kelvin, kjmol, massunit, newton, pascal, picoseconds, seconds, wavenumbers
39 : USE string_utilities, ONLY: compress,&
40 : s2a,&
41 : uppercase
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, &
53 : cp_ukind_temperature = 3, &
54 : cp_ukind_angle = 4, &
55 : cp_ukind_pressure = 5, &
56 : cp_ukind_time = 6, &
57 : cp_ukind_mass = 7, &
58 : cp_ukind_undef = 8, &
59 : cp_ukind_potential = 9, &
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, &
121 : cp_units_volt_per_angstrom = 204
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, &
129 : cp_unit_desc_length = cp_unit_max_kinds*cp_unit_basic_desc_length
130 :
131 : PUBLIC :: cp_unit_type, cp_unit_set_type
132 : PUBLIC :: cp_unit_create, cp_unit_release, &
133 : cp_unit_to_cp2k, cp_unit_from_cp2k, cp_unit_desc, &
134 : cp_unit_set_create, cp_unit_set_release, &
135 : cp_unit_to_cp2k1, cp_unit_from_cp2k1, cp_unit_compatible, export_units_as_xml
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 : ! **************************************************************************************************
143 : TYPE cp_unit_type
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 : ! **************************************************************************************************
161 : TYPE cp_unit_set_type
162 : TYPE(cp_unit_p_type), DIMENSION(cp_ukind_max) :: units = cp_unit_p_type()
163 : END TYPE cp_unit_set_type
164 :
165 : CONTAINS
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 200423900 : 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 8016956 : 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 72152604 : unit_id = cp_units_none
185 8016956 : kind_id = cp_ukind_none
186 8016956 : power = 0
187 8016956 : i_low = 1
188 8016956 : i_high = 1
189 8016956 : len_string = LEN(string)
190 8016956 : i_unit = 0
191 8016956 : next_power = 1
192 8016956 : DO WHILE (i_low < len_string)
193 7550277 : IF (string(i_low:i_low) /= ' ') EXIT
194 8016956 : i_low = i_low + 1
195 : END DO
196 : i_high = i_low
197 52939864 : DO WHILE (i_high <= len_string)
198 : IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
199 46230458 : string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
200 51633187 : i_high = i_high + 1
201 : END DO
202 : DO
203 8657480 : IF (i_high <= i_low .OR. i_low > len_string) EXIT
204 8648691 : i_unit = i_unit + 1
205 8648691 : IF (i_unit > cp_unit_max_kinds) THEN
206 0 : CPABORT("Maximum number of combined units exceeded")
207 0 : EXIT
208 : END IF
209 : ! read unit
210 8648691 : unit_string = string(i_low:i_high - 1)
211 8648691 : CALL uppercase(unit_string)
212 8969261 : SELECT CASE (TRIM(unit_string))
213 : CASE ("INTERNAL_CP2K")
214 320570 : unit_id(i_unit) = cp_units_none
215 320570 : kind_id(i_unit) = cp_ukind_undef
216 : CASE ("HARTREE")
217 317150 : unit_id(i_unit) = cp_units_hartree
218 317150 : kind_id(i_unit) = cp_ukind_energy
219 : CASE ("AU_E")
220 45918 : unit_id(i_unit) = cp_units_au
221 45918 : kind_id(i_unit) = cp_ukind_energy
222 : CASE ("WAVENUMBER_E")
223 0 : unit_id(i_unit) = cp_units_wavenum
224 0 : kind_id(i_unit) = cp_ukind_energy
225 : CASE ("JOULE", "J")
226 0 : unit_id(i_unit) = cp_units_joule
227 0 : kind_id(i_unit) = cp_ukind_energy
228 : CASE ("KCALMOL")
229 246457 : unit_id(i_unit) = cp_units_kcalmol
230 246457 : kind_id(i_unit) = cp_ukind_energy
231 : CASE ("KJMOL")
232 2248 : unit_id(i_unit) = cp_units_kjmol
233 2248 : kind_id(i_unit) = cp_ukind_energy
234 : CASE ("JMOL")
235 0 : unit_id(i_unit) = cp_units_jmol
236 0 : kind_id(i_unit) = cp_ukind_energy
237 : CASE ("RY")
238 55039 : unit_id(i_unit) = cp_units_Ry
239 55039 : kind_id(i_unit) = cp_ukind_energy
240 : CASE ("EV")
241 753938 : unit_id(i_unit) = cp_units_eV
242 753938 : kind_id(i_unit) = cp_ukind_energy
243 : CASE ("KEV")
244 21907 : unit_id(i_unit) = cp_units_keV
245 21907 : kind_id(i_unit) = cp_ukind_energy
246 : CASE ("K_E")
247 101813 : unit_id(i_unit) = cp_units_k
248 101813 : kind_id(i_unit) = cp_ukind_energy
249 : CASE ("ENERGY")
250 0 : unit_id(i_unit) = cp_units_none
251 0 : kind_id(i_unit) = cp_ukind_energy
252 : CASE ("AU_L")
253 278 : unit_id(i_unit) = cp_units_au
254 278 : kind_id(i_unit) = cp_ukind_length
255 : CASE ("BOHR")
256 647346 : unit_id(i_unit) = cp_units_bohr
257 647346 : kind_id(i_unit) = cp_ukind_length
258 : CASE ("M")
259 24920 : unit_id(i_unit) = cp_units_m
260 24920 : kind_id(i_unit) = cp_ukind_length
261 : CASE ("PM")
262 2 : unit_id(i_unit) = cp_units_pm
263 2 : kind_id(i_unit) = cp_ukind_length
264 : CASE ("NM")
265 11521 : unit_id(i_unit) = cp_units_nm
266 11521 : kind_id(i_unit) = cp_ukind_length
267 : CASE ("ANGSTROM")
268 3677867 : unit_id(i_unit) = cp_units_angstrom
269 3677867 : kind_id(i_unit) = cp_ukind_length
270 : CASE ("LENGTH")
271 0 : unit_id(i_unit) = cp_units_none
272 0 : kind_id(i_unit) = cp_ukind_length
273 : CASE ("K", "K_TEMP")
274 493723 : unit_id(i_unit) = cp_units_k
275 493723 : kind_id(i_unit) = cp_ukind_temperature
276 : CASE ("AU_TEMP")
277 0 : unit_id(i_unit) = cp_units_au
278 0 : kind_id(i_unit) = cp_ukind_temperature
279 : CASE ("TEMPERATURE")
280 0 : unit_id(i_unit) = cp_units_none
281 0 : kind_id(i_unit) = cp_ukind_temperature
282 : CASE ("ATM")
283 0 : unit_id(i_unit) = cp_units_atm
284 0 : kind_id(i_unit) = cp_ukind_pressure
285 : CASE ("BAR")
286 85690 : unit_id(i_unit) = cp_units_bar
287 85690 : kind_id(i_unit) = cp_ukind_pressure
288 : CASE ("KBAR")
289 22 : unit_id(i_unit) = cp_units_kbar
290 22 : kind_id(i_unit) = cp_ukind_pressure
291 : CASE ("PA")
292 2924 : unit_id(i_unit) = cp_units_Pa
293 2924 : kind_id(i_unit) = cp_ukind_pressure
294 : CASE ("MPA")
295 0 : unit_id(i_unit) = cp_units_MPa
296 0 : kind_id(i_unit) = cp_ukind_pressure
297 : CASE ("GPA")
298 1772 : unit_id(i_unit) = cp_units_GPa
299 1772 : kind_id(i_unit) = cp_ukind_pressure
300 : CASE ("AU_P")
301 0 : unit_id(i_unit) = cp_units_au
302 0 : kind_id(i_unit) = cp_ukind_pressure
303 : CASE ("PRESSURE")
304 0 : unit_id(i_unit) = cp_units_none
305 0 : kind_id(i_unit) = cp_ukind_pressure
306 : CASE ("RAD")
307 92117 : unit_id(i_unit) = cp_units_rad
308 92117 : kind_id(i_unit) = cp_ukind_angle
309 : CASE ("DEG")
310 160140 : unit_id(i_unit) = cp_units_deg
311 160140 : kind_id(i_unit) = cp_ukind_angle
312 : CASE ("ANGLE")
313 0 : unit_id(i_unit) = cp_units_none
314 0 : kind_id(i_unit) = cp_ukind_angle
315 : CASE ("S")
316 39526 : unit_id(i_unit) = cp_units_s
317 39526 : kind_id(i_unit) = cp_ukind_time
318 : CASE ("FS")
319 1038212 : unit_id(i_unit) = cp_units_fs
320 1038212 : kind_id(i_unit) = cp_ukind_time
321 : CASE ("PS")
322 366924 : unit_id(i_unit) = cp_units_ps
323 366924 : kind_id(i_unit) = cp_ukind_time
324 : CASE ("WAVENUMBER_T")
325 34 : unit_id(i_unit) = cp_units_wn
326 34 : kind_id(i_unit) = cp_ukind_time
327 : CASE ("AU_T")
328 91227 : unit_id(i_unit) = cp_units_au
329 91227 : kind_id(i_unit) = cp_ukind_time
330 : CASE ("TIME")
331 0 : unit_id(i_unit) = cp_units_none
332 0 : kind_id(i_unit) = cp_ukind_time
333 : CASE ("KG")
334 0 : unit_id(i_unit) = cp_units_kg
335 0 : kind_id(i_unit) = cp_ukind_mass
336 : CASE ("AMU")
337 1618 : unit_id(i_unit) = cp_units_amu
338 1618 : kind_id(i_unit) = cp_ukind_mass
339 : CASE ("M_E")
340 0 : unit_id(i_unit) = cp_units_m_e
341 0 : kind_id(i_unit) = cp_ukind_mass
342 : CASE ("AU_M")
343 21903 : unit_id(i_unit) = cp_units_au
344 21903 : kind_id(i_unit) = cp_ukind_mass
345 : CASE ("MASS")
346 0 : unit_id(i_unit) = cp_units_none
347 0 : kind_id(i_unit) = cp_ukind_mass
348 : CASE ("VOLT")
349 19102 : unit_id(i_unit) = cp_units_volt
350 19102 : kind_id(i_unit) = cp_ukind_potential
351 : CASE ("AU_POT")
352 0 : unit_id(i_unit) = cp_units_au
353 0 : kind_id(i_unit) = cp_ukind_potential
354 : CASE ("POTENTIAL")
355 0 : unit_id(i_unit) = cp_units_none
356 0 : kind_id(i_unit) = cp_ukind_potential
357 : CASE ("N", "NEWTON")
358 16 : unit_id(i_unit) = cp_units_Newton
359 16 : kind_id(i_unit) = cp_ukind_force
360 : CASE ("MN", "MNEWTON")
361 2988 : unit_id(i_unit) = cp_units_mNewton
362 2988 : kind_id(i_unit) = cp_ukind_force
363 : CASE ("AU_F")
364 0 : unit_id(i_unit) = cp_units_au
365 0 : kind_id(i_unit) = cp_ukind_force
366 : CASE ("FORCE")
367 0 : unit_id(i_unit) = cp_units_none
368 0 : kind_id(i_unit) = cp_ukind_force
369 : CASE ("VM-1", "VOLT_PER_M")
370 2943 : unit_id(i_unit) = cp_units_volt_per_m
371 2943 : kind_id(i_unit) = cp_ukind_efield
372 : CASE ("VNM-1", "VOLT_PER_NM")
373 0 : unit_id(i_unit) = cp_units_volt_per_nm
374 0 : kind_id(i_unit) = cp_ukind_efield
375 : CASE ("VA-1", "VOLT_PER_ANGSTROM")
376 0 : unit_id(i_unit) = cp_units_volt_per_angstrom
377 0 : kind_id(i_unit) = cp_ukind_efield
378 : CASE ("AU_EFIELD")
379 0 : unit_id(i_unit) = cp_units_au
380 0 : kind_id(i_unit) = cp_ukind_efield
381 : CASE ("EFIELD")
382 0 : unit_id(i_unit) = cp_units_none
383 0 : kind_id(i_unit) = cp_ukind_efield
384 : CASE ("DEBYE")
385 826 : unit_id(i_unit) = cp_units_debye
386 826 : kind_id(i_unit) = cp_ukind_dipole
387 : CASE ("E_ANGSTROM")
388 0 : unit_id(i_unit) = cp_units_e_angstrom
389 0 : kind_id(i_unit) = cp_ukind_dipole
390 : CASE ("C_M")
391 0 : unit_id(i_unit) = cp_units_c_m
392 0 : kind_id(i_unit) = cp_ukind_dipole
393 : CASE ("AU_DIP")
394 10 : unit_id(i_unit) = cp_units_au
395 10 : kind_id(i_unit) = cp_ukind_dipole
396 : CASE ("DIPOLE")
397 0 : unit_id(i_unit) = cp_units_none
398 0 : 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 0 : "au_efield, au_dip)")
404 : CASE default
405 8648691 : CPABORT("Unknown unit: "//string(i_low:i_high - 1))
406 : END SELECT
407 8648691 : power(i_unit) = next_power
408 : ! parse op
409 8648691 : i_low = i_high
410 8733045 : DO WHILE (i_low <= len_string)
411 1989836 : IF (string(i_low:i_low) /= ' ') EXIT
412 8733045 : i_low = i_low + 1
413 : END DO
414 : i_high = i_low
415 8648691 : DO WHILE (i_high <= len_string)
416 : IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
417 1905482 : string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
418 0 : i_high = i_high + 1
419 : END DO
420 8648691 : IF (i_high < i_low .OR. i_low > len_string) EXIT
421 :
422 1905482 : IF (i_high <= len_string) THEN
423 1905482 : IF (string(i_low:i_high) == '^') THEN
424 1271043 : i_low = i_high + 1
425 1271043 : DO WHILE (i_low <= len_string)
426 1271043 : IF (string(i_low:i_low) /= ' ') EXIT
427 1271043 : i_low = i_low + 1
428 : END DO
429 : i_high = i_low
430 3758901 : DO WHILE (i_high <= len_string)
431 1264958 : SELECT CASE (string(i_high:i_high))
432 : CASE ('+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
433 2487858 : i_high = i_high + 1
434 : CASE default
435 2493943 : EXIT
436 : END SELECT
437 : END DO
438 1271043 : IF (i_high <= i_low .OR. i_low > len_string) THEN
439 0 : CPABORT("an integer number is expected after a '^'")
440 0 : EXIT
441 : END IF
442 1271043 : formatstr = "(i"//cp_to_string(i_high - i_low + 1)//")"
443 : READ (string(i_low:i_high - 1), formatstr) &
444 1271043 : next_power
445 1271043 : power(i_unit) = power(i_unit)*next_power
446 : ! next op
447 1271043 : i_low = i_high
448 1275963 : DO WHILE (i_low < len_string)
449 10988 : IF (string(i_low:i_low) /= ' ') EXIT
450 1275963 : i_low = i_low + 1
451 : END DO
452 : i_high = i_low
453 1272237 : DO WHILE (i_high <= len_string)
454 : IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
455 7077 : string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
456 1211 : i_high = i_high + 1
457 : END DO
458 : END IF
459 : END IF
460 1905482 : IF (i_low > len_string) EXIT
461 640524 : next_power = 1
462 8657480 : IF (i_high <= len_string) THEN
463 640322 : IF (string(i_low:i_high) == "*" .OR. string(i_low:i_high) == '/') THEN
464 640305 : IF (string(i_low:i_high) == '/') next_power = -1
465 640305 : i_low = i_high + 1
466 640305 : DO WHILE (i_low <= len_string)
467 640305 : IF (string(i_low:i_low) /= ' ') EXIT
468 640305 : i_low = i_low + 1
469 : END DO
470 : i_high = i_low
471 3178124 : DO WHILE (i_high <= len_string)
472 : IF (string(i_high:i_high) == ' ' .OR. string(i_high:i_high) == '^' .OR. &
473 3136626 : string(i_high:i_high) == '*' .OR. string(i_high:i_high) == '/') EXIT
474 2579336 : 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 8016956 : power=power)
481 8016956 : desc = cp_unit_desc(unit)
482 8016956 : 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 228540704 : 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 8162168 : CPASSERT(SIZE(kind_id) <= cp_unit_max_kinds)
503 8162168 : CPASSERT(SIZE(unit_id) <= cp_unit_max_kinds)
504 72443028 : unit%kind_id(1:SIZE(kind_id)) = kind_id
505 9178652 : unit%kind_id(SIZE(kind_id) + 1:) = cp_ukind_none
506 72443028 : unit%unit_id(1:SIZE(unit_id)) = unit_id
507 17340820 : unit%unit_id(SIZE(unit_id):) = cp_units_none
508 8162168 : IF (PRESENT(power)) THEN
509 72443028 : unit%power(1:SIZE(power)) = power
510 9178652 : unit%power(SIZE(power) + 1:) = 0
511 73459512 : DO i = 1, SIZE(unit%power)
512 73459512 : IF (unit%power(i) == 0) THEN
513 56503441 : unit%kind_id(i) = cp_ukind_none
514 56503441 : unit%unit_id(i) = cp_units_none
515 : END IF
516 : END DO
517 : ELSE
518 0 : DO i = 1, SIZE(unit%power)
519 0 : IF (unit%unit_id(i) /= 0) THEN
520 0 : unit%power(i) = 1
521 : ELSE
522 0 : unit%power(i) = 0
523 : END IF
524 : END DO
525 : END IF
526 :
527 : ! remove unnecessary units
528 : ! reorder & compress
529 8162168 : unit%n_kinds = 0
530 73459512 : DO i = 1, SIZE(unit%kind_id)
531 : ! find max and compress in the rest
532 : DO
533 65297344 : max_kind = unit%kind_id(i)
534 65297344 : max_pos = i
535 65297344 : repeat = .FALSE.
536 293838048 : DO j = i + 1, SIZE(unit%kind_id)
537 293838048 : IF (unit%kind_id(j) >= max_kind) THEN
538 168261171 : 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 0 : unit%power(max_pos) = unit%power(max_pos) + unit%power(j)
541 0 : unit%kind_id(j) = cp_ukind_none
542 0 : unit%unit_id(j) = cp_units_none
543 0 : unit%power(j) = 0
544 0 : IF (unit%power(max_pos) == 0) THEN
545 0 : unit%kind_id(max_pos) = cp_ukind_none
546 0 : unit%unit_id(max_pos) = cp_units_none
547 0 : unit%power(max_pos) = 0
548 0 : repeat = .TRUE.
549 0 : EXIT
550 : END IF
551 168261171 : 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 634353 : max_kind = unit%kind_id(j)
555 634353 : max_pos = j
556 : END IF
557 : END IF
558 : END DO
559 65297344 : IF (.NOT. repeat) EXIT
560 : END DO
561 65297344 : IF (max_kind /= 0) unit%n_kinds = unit%n_kinds + 1
562 : ! put the max at pos i
563 65297344 : IF (max_pos /= i) THEN
564 631425 : unit%kind_id(max_pos) = unit%kind_id(i)
565 631425 : unit%kind_id(i) = max_kind
566 631425 : max_kind = unit%unit_id(max_pos)
567 631425 : unit%unit_id(max_pos) = unit%unit_id(i)
568 631425 : unit%unit_id(i) = max_kind
569 631425 : max_kind = unit%power(max_pos)
570 631425 : unit%power(max_pos) = unit%power(i)
571 631425 : unit%power(i) = max_kind
572 : END IF
573 : ! check unit
574 : CALL cp_basic_unit_check(basic_kind=unit%kind_id(i), &
575 73459512 : basic_unit=unit%unit_id(i))
576 : END DO
577 8162168 : 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 8162168 : ELEMENTAL SUBROUTINE cp_unit_release(unit)
587 : TYPE(cp_unit_type), INTENT(IN) :: unit
588 :
589 : MARK_USED(unit)
590 :
591 8162168 : 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 65297344 : SUBROUTINE cp_basic_unit_check(basic_kind, basic_unit)
600 : INTEGER, INTENT(in) :: basic_kind, basic_unit
601 :
602 65630015 : SELECT CASE (basic_kind)
603 : CASE (cp_ukind_undef)
604 1889242 : SELECT CASE (basic_unit)
605 : CASE (cp_units_none)
606 : CASE default
607 332671 : CPABORT("unknown undef unit:"//TRIM(cp_to_string(basic_unit)))
608 : END SELECT
609 : CASE (cp_ukind_energy)
610 5930606 : SELECT CASE (basic_unit)
611 : CASE (cp_units_hartree, cp_units_wavenum, cp_units_joule, cp_units_kcalmol, &
612 : cp_units_kjmol, cp_units_Ry, cp_units_eV, cp_units_keV, cp_units_au, cp_units_k, &
613 : cp_units_jmol, cp_units_none)
614 : CASE default
615 1556571 : CPABORT("unknown energy unit:"//TRIM(cp_to_string(basic_unit)))
616 : END SELECT
617 : CASE (cp_ukind_length)
618 4879859 : SELECT CASE (basic_unit)
619 : CASE (cp_units_bohr, cp_units_angstrom, cp_units_au, cp_units_none, cp_units_m, &
620 : cp_units_pm, cp_units_nm)
621 : CASE default
622 4374035 : CPABORT("unknown length unit:"//TRIM(cp_to_string(basic_unit)))
623 : END SELECT
624 : CASE (cp_ukind_temperature)
625 608333 : SELECT CASE (basic_unit)
626 : CASE (cp_units_k, cp_units_au, cp_units_none)
627 : CASE default
628 505824 : CPABORT("unknown temperature unit:"//TRIM(cp_to_string(basic_unit)))
629 : END SELECT
630 : CASE (cp_ukind_pressure)
631 366867 : SELECT CASE (basic_unit)
632 : CASE (cp_units_bar, cp_units_atm, cp_units_kbar, cp_units_Pa, cp_units_MPa, cp_units_GPa, cp_units_au, cp_units_none)
633 : CASE default
634 102509 : CPABORT("unknown pressure unit:"//TRIM(cp_to_string(basic_unit)))
635 : END SELECT
636 : CASE (cp_ukind_angle)
637 1812382 : SELECT CASE (basic_unit)
638 : CASE (cp_units_rad, cp_units_deg, cp_units_none)
639 : CASE default
640 264358 : CPABORT("unknown angle unit:"//TRIM(cp_to_string(basic_unit)))
641 : END SELECT
642 : CASE (cp_ukind_time)
643 1583646 : SELECT CASE (basic_unit)
644 : CASE (cp_units_s, cp_units_fs, cp_units_ps, cp_units_au, cp_units_wn, cp_units_none)
645 : CASE default
646 1548024 : CPABORT("unknown time unit:"//TRIM(cp_to_string(basic_unit)))
647 : END SELECT
648 : CASE (cp_ukind_mass)
649 66825 : SELECT CASE (basic_unit)
650 : CASE (cp_units_kg, cp_units_amu, cp_units_m_e, cp_units_au, cp_units_none)
651 : CASE default
652 35622 : CPABORT("unknown mass unit:"//TRIM(cp_to_string(basic_unit)))
653 : END SELECT
654 : CASE (cp_ukind_potential)
655 46308 : SELECT CASE (basic_unit)
656 : CASE (cp_units_volt, cp_units_au, cp_units_none)
657 : CASE default
658 31203 : CPABORT("unknown potential unit:"//TRIM(cp_to_string(basic_unit)))
659 : END SELECT
660 : CASE (cp_ukind_force)
661 30149 : SELECT CASE (basic_unit)
662 : CASE (cp_units_Newton, cp_units_mNewton, cp_units_au, cp_units_none)
663 : CASE default
664 15105 : CPABORT("unknown force unit:"//TRIM(cp_to_string(basic_unit)))
665 : END SELECT
666 : CASE (cp_ukind_efield)
667 27981 : SELECT CASE (basic_unit)
668 : CASE (cp_units_volt_per_m, cp_units_volt_per_nm, &
669 : cp_units_volt_per_angstrom, cp_units_au, cp_units_none)
670 : CASE default
671 15044 : CPABORT("unknown electric field unit:"//TRIM(cp_to_string(basic_unit)))
672 : END SELECT
673 : CASE (cp_ukind_dipole)
674 56516378 : SELECT CASE (basic_unit)
675 : CASE (cp_units_debye, cp_units_e_angstrom, cp_units_c_m, cp_units_au, cp_units_none)
676 : CASE default
677 12937 : CPABORT("unknown dipole unit:"//TRIM(cp_to_string(basic_unit)))
678 : END SELECT
679 : CASE (cp_ukind_none)
680 56503441 : 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 0 : //TRIM(cp_to_string(basic_unit)))
684 : END IF
685 : CASE default
686 65297344 : CPABORT("unknown kind of unit:"//TRIM(cp_to_string(basic_kind)))
687 : END SELECT
688 65297344 : 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 5315416 : 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 5315416 : my_power = 1
708 5315416 : IF (PRESENT(power)) my_power = power
709 5315416 : IF (basic_unit == cp_units_none .AND. basic_kind /= cp_ukind_undef) THEN
710 0 : IF (basic_kind /= cp_units_none) THEN
711 : CALL cp_abort(__LOCATION__, &
712 : "unit not yet fully specified, unit of kind "// &
713 0 : TRIM(cp_to_string(basic_unit)))
714 : END IF
715 : END IF
716 5350851 : SELECT CASE (basic_kind)
717 : CASE (cp_ukind_undef)
718 931146 : SELECT CASE (basic_unit)
719 : CASE (cp_units_none)
720 35435 : res = value
721 : CASE default
722 35435 : CPABORT("unknown energy unit:"//TRIM(cp_to_string(basic_unit)))
723 : END SELECT
724 : CASE (cp_ukind_energy)
725 3346073 : SELECT CASE (basic_unit)
726 : CASE (cp_units_hartree, cp_units_au)
727 161645 : res = value
728 : CASE (cp_units_wavenum)
729 0 : res = wavenumbers**(-my_power)*value
730 : CASE (cp_units_joule)
731 0 : res = joule**(-my_power)*value
732 : CASE (cp_units_kcalmol)
733 224581 : res = kcalmol**(-my_power)*value
734 : CASE (cp_units_kjmol)
735 2248 : res = kjmol**(-my_power)*value
736 : CASE (cp_units_jmol)
737 0 : res = (kjmol*1.0E+3_dp)**(-my_power)*value
738 : CASE (cp_units_Ry)
739 24278 : res = 0.5_dp**my_power*value
740 : CASE (cp_units_eV)
741 458654 : res = evolt**(-my_power)*value
742 : CASE (cp_units_keV)
743 8 : res = (1.0E-3_dp*evolt)**(-my_power)*value
744 : CASE (cp_units_k)
745 24297 : res = kelvin**(-my_power)*value
746 : CASE default
747 895711 : CPABORT("unknown energy unit:"//TRIM(cp_to_string(basic_unit)))
748 : END SELECT
749 : CASE (cp_ukind_length)
750 369149 : SELECT CASE (basic_unit)
751 : CASE (cp_units_bohr, cp_units_au)
752 176275 : res = value
753 : CASE (cp_units_m)
754 66 : res = value*(1.0E10_dp*bohr)**my_power
755 : CASE (cp_units_pm)
756 2 : res = value*(0.01_dp*bohr)**my_power
757 : CASE (cp_units_nm)
758 10075 : res = value*(10.0_dp*bohr)**my_power
759 : CASE (cp_units_angstrom)
760 2998010 : res = value*bohr**my_power
761 : CASE default
762 3184428 : CPABORT("unknown length unit:"//TRIM(cp_to_string(basic_unit)))
763 : END SELECT
764 : CASE (cp_ukind_temperature)
765 237238 : SELECT CASE (basic_unit)
766 : CASE (cp_units_k)
767 192874 : res = kelvin**(-my_power)*value
768 : CASE (cp_units_au)
769 0 : res = value
770 : CASE default
771 192874 : CPABORT("unknown temperature unit:"//TRIM(cp_to_string(basic_unit)))
772 : END SELECT
773 : CASE (cp_ukind_pressure)
774 264135 : SELECT CASE (basic_unit)
775 : CASE (cp_units_bar)
776 42588 : res = bar**(-my_power)*value
777 : CASE (cp_units_atm)
778 0 : res = atm**(-my_power)*value
779 : CASE (cp_units_kbar)
780 22 : res = (1.0E-3_dp*bar)**(-my_power)*value
781 : CASE (cp_units_Pa)
782 1462 : res = pascal**(-my_power)*value
783 : CASE (cp_units_MPa)
784 0 : res = (1.0E-6_dp*pascal)**(-my_power)*value
785 : CASE (cp_units_GPa)
786 292 : res = (1.0E-9_dp*pascal)**(-my_power)*value
787 : CASE (cp_units_au)
788 0 : res = value
789 : CASE default
790 44364 : CPABORT("unknown pressure unit:"//TRIM(cp_to_string(basic_unit)))
791 : END SELECT
792 : CASE (cp_ukind_angle)
793 812964 : SELECT CASE (basic_unit)
794 : CASE (cp_units_rad)
795 73057 : res = value
796 : CASE (cp_units_deg)
797 148490 : res = value*(radians)**my_power
798 : CASE default
799 221547 : CPABORT("unknown angle unit:"//TRIM(cp_to_string(basic_unit)))
800 : END SELECT
801 : CASE (cp_ukind_time)
802 215 : SELECT CASE (basic_unit)
803 : CASE (cp_units_s)
804 24 : res = value*seconds**(-my_power)
805 : CASE (cp_units_fs)
806 392493 : res = value*femtoseconds**(-my_power)
807 : CASE (cp_units_ps)
808 299757 : res = value*picoseconds**(-my_power)
809 : CASE (cp_units_au)
810 47599 : res = value
811 : CASE (cp_units_wn)
812 34 : res = (twopi*wavenumbers)**(my_power)/value
813 : CASE default
814 739907 : CPABORT("unknown time unit:"//TRIM(cp_to_string(basic_unit)))
815 : END SELECT
816 : CASE (cp_ukind_mass)
817 77 : SELECT CASE (basic_unit)
818 : CASE (cp_units_kg)
819 0 : res = e_mass**my_power*value
820 : CASE (cp_units_amu)
821 182 : res = massunit**my_power*value
822 : CASE (cp_units_m_e, cp_units_au)
823 9 : res = value
824 : CASE default
825 191 : CPABORT("unknown mass unit:"//TRIM(cp_to_string(basic_unit)))
826 : END SELECT
827 : CASE (cp_ukind_potential)
828 121 : SELECT CASE (basic_unit)
829 : CASE (cp_units_volt)
830 77 : res = evolt**(-my_power)*value
831 : CASE (cp_units_au)
832 0 : res = value
833 : CASE default
834 77 : CPABORT("unknown potential unit:"//TRIM(cp_to_string(basic_unit)))
835 : END SELECT
836 : CASE (cp_ukind_force)
837 18 : SELECT CASE (basic_unit)
838 : CASE (cp_units_Newton)
839 16 : res = value*newton**(-my_power)
840 : CASE (cp_units_mNewton)
841 28 : res = value*(1.0E+3_dp*newton)**(-my_power)
842 : CASE (cp_units_au)
843 0 : res = value
844 : CASE default
845 44 : CPABORT("unknown force unit:"//TRIM(cp_to_string(basic_unit)))
846 : END SELECT
847 : CASE (cp_ukind_efield)
848 838 : SELECT CASE (basic_unit)
849 : CASE (cp_units_volt_per_m)
850 2 : res = (1.0E+10_dp*evolt*bohr)**(-my_power)*value
851 : CASE (cp_units_volt_per_nm)
852 0 : res = (10.0_dp*evolt*bohr)**(-my_power)*value
853 : CASE (cp_units_volt_per_angstrom)
854 0 : res = (evolt*bohr)**(-my_power)*value
855 : CASE (cp_units_au)
856 0 : res = value
857 : CASE default
858 2 : CPABORT("unknown electric field unit:"//TRIM(cp_to_string(basic_unit)))
859 : END SELECT
860 : CASE (cp_ukind_dipole)
861 826 : SELECT CASE (basic_unit)
862 : CASE (cp_units_debye)
863 826 : res = debye**(-my_power)*value
864 : CASE (cp_units_e_angstrom)
865 0 : res = value*bohr**my_power
866 : CASE (cp_units_c_m)
867 0 : res = (e_charge*a_bohr)**(-my_power)*value
868 : CASE (cp_units_au)
869 10 : res = value
870 : CASE default
871 836 : 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 0 : //TRIM(cp_to_string(basic_unit)))
877 : CASE default
878 5315416 : CPABORT("unknown kind of unit:"//TRIM(cp_to_string(basic_kind)))
879 : END SELECT
880 5315416 : 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 8648691 : 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 8648691 : my_power = 1
902 8648691 : res = ""
903 8648691 : my_accept_undefined = .FALSE.
904 8648691 : IF (accept_undefined) my_accept_undefined = accept_undefined
905 8648691 : IF (PRESENT(power)) my_power = power
906 8648691 : IF (basic_unit == cp_units_none) THEN
907 320570 : 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 0 : TRIM(cp_to_string(basic_kind)))
910 : END IF
911 : END IF
912 8969261 : SELECT CASE (basic_kind)
913 : CASE (cp_ukind_undef)
914 1865040 : SELECT CASE (basic_unit)
915 : CASE (cp_units_none)
916 320570 : res = "internal_cp2k"
917 : CASE DEFAULT
918 : CALL cp_abort(__LOCATION__, &
919 : "unit not yet fully specified, unit of kind "// &
920 320570 : TRIM(res))
921 : END SELECT
922 : CASE (cp_ukind_energy)
923 4725002 : SELECT CASE (basic_unit)
924 : CASE (cp_units_hartree, cp_units_au)
925 363068 : res = "hartree"
926 : CASE (cp_units_wavenum)
927 0 : res = "wavenumber_e"
928 : CASE (cp_units_joule)
929 0 : res = "joule"
930 : CASE (cp_units_kcalmol)
931 246457 : res = "kcalmol"
932 : CASE (cp_units_kjmol)
933 2248 : res = "kjmol"
934 : CASE (cp_units_jmol)
935 0 : res = "jmol"
936 : CASE (cp_units_Ry)
937 55039 : res = "Ry"
938 : CASE (cp_units_eV)
939 753938 : res = "eV"
940 : CASE (cp_units_keV)
941 21907 : res = "keV"
942 : CASE (cp_units_k)
943 101813 : res = "K_e"
944 : CASE (cp_units_none)
945 0 : res = "energy"
946 0 : IF (.NOT. my_accept_undefined) THEN
947 : CALL cp_abort(__LOCATION__, &
948 : "unit not yet fully specified, unit of kind "// &
949 0 : TRIM(res))
950 : END IF
951 : CASE default
952 1544470 : CPABORT("unknown energy unit:"//TRIM(cp_to_string(basic_unit)))
953 : END SELECT
954 : CASE (cp_ukind_length)
955 1141347 : SELECT CASE (basic_unit)
956 : CASE (cp_units_bohr, cp_units_au)
957 647624 : res = "bohr"
958 : CASE (cp_units_m)
959 24920 : res = "m"
960 : CASE (cp_units_pm)
961 2 : res = "pm"
962 : CASE (cp_units_nm)
963 11521 : res = "nm"
964 : CASE (cp_units_angstrom)
965 3677867 : res = "angstrom"
966 : CASE default
967 0 : res = "length"
968 4361934 : CPABORT("unknown length unit:"//TRIM(cp_to_string(basic_unit)))
969 : END SELECT
970 : CASE (cp_ukind_temperature)
971 584131 : SELECT CASE (basic_unit)
972 : CASE (cp_units_k)
973 493723 : res = "K"
974 : CASE (cp_units_au)
975 0 : res = "au_temp"
976 : CASE (cp_units_none)
977 0 : res = "temperature"
978 0 : IF (.NOT. my_accept_undefined) THEN
979 : CALL cp_abort(__LOCATION__, &
980 : "unit not yet fully specified, unit of kind "// &
981 0 : TRIM(res))
982 : END IF
983 : CASE default
984 493723 : CPABORT("unknown temperature unit:"//TRIM(cp_to_string(basic_unit)))
985 : END SELECT
986 : CASE (cp_ukind_pressure)
987 337947 : SELECT CASE (basic_unit)
988 : CASE (cp_units_bar)
989 85690 : res = "bar"
990 : CASE (cp_units_atm)
991 0 : res = "atm"
992 : CASE (cp_units_kbar)
993 22 : res = "kbar"
994 : CASE (cp_units_Pa)
995 2924 : res = "Pa"
996 : CASE (cp_units_MPa)
997 0 : res = "MPa"
998 : CASE (cp_units_GPa)
999 1772 : res = "GPa"
1000 : CASE (cp_units_au)
1001 0 : res = "au_p"
1002 : CASE (cp_units_none)
1003 0 : res = "pressure"
1004 0 : IF (.NOT. my_accept_undefined) THEN
1005 : CALL cp_abort(__LOCATION__, &
1006 : "unit not yet fully specified, unit of kind "// &
1007 0 : TRIM(res))
1008 : END IF
1009 : CASE default
1010 90408 : CPABORT("unknown pressure unit:"//TRIM(cp_to_string(basic_unit)))
1011 : END SELECT
1012 : CASE (cp_ukind_angle)
1013 1628040 : SELECT CASE (basic_unit)
1014 : CASE (cp_units_rad)
1015 92117 : res = "rad"
1016 : CASE (cp_units_deg)
1017 160140 : res = "deg"
1018 : CASE (cp_units_none)
1019 0 : res = "angle"
1020 0 : IF (.NOT. my_accept_undefined) THEN
1021 : CALL cp_abort(__LOCATION__, &
1022 : "unit not yet fully specified, unit of kind "// &
1023 0 : TRIM(res))
1024 : END IF
1025 : CASE default
1026 252257 : CPABORT("unknown angle unit:"//TRIM(cp_to_string(basic_unit)))
1027 : END SELECT
1028 : CASE (cp_ukind_time)
1029 63047 : SELECT CASE (basic_unit)
1030 : CASE (cp_units_s)
1031 39526 : res = "s"
1032 : CASE (cp_units_fs)
1033 1038212 : res = "fs"
1034 : CASE (cp_units_ps)
1035 366924 : res = "ps"
1036 : CASE (cp_units_au)
1037 91227 : res = "au_t"
1038 : CASE (cp_units_wn)
1039 34 : res = "wavenumber_t"
1040 : CASE (cp_units_none)
1041 0 : res = "time"
1042 0 : IF (.NOT. my_accept_undefined) THEN
1043 : CALL cp_abort(__LOCATION__, &
1044 : "unit not yet fully specified, unit of kind "// &
1045 0 : TRIM(res))
1046 : END IF
1047 : CASE default
1048 1535923 : CPABORT("unknown time unit:"//TRIM(cp_to_string(basic_unit)))
1049 : END SELECT
1050 : CASE (cp_ukind_mass)
1051 19102 : SELECT CASE (basic_unit)
1052 : CASE (cp_units_kg)
1053 0 : res = "kg"
1054 : CASE (cp_units_amu)
1055 1618 : res = "amu"
1056 : CASE (cp_units_m_e, cp_units_au)
1057 21903 : res = "m_e"
1058 : CASE (cp_units_none)
1059 0 : res = "mass"
1060 0 : IF (.NOT. my_accept_undefined) THEN
1061 : CALL cp_abort(__LOCATION__, &
1062 : "unit not yet fully specified, unit of kind "// &
1063 0 : TRIM(res))
1064 : END IF
1065 : CASE default
1066 23521 : CPABORT("unknown mass unit:"//TRIM(cp_to_string(basic_unit)))
1067 : END SELECT
1068 : CASE (cp_ukind_potential)
1069 22106 : SELECT CASE (basic_unit)
1070 : CASE (cp_units_volt)
1071 19102 : res = "volt"
1072 : CASE (cp_units_au)
1073 0 : res = "au_pot"
1074 : CASE (cp_units_none)
1075 0 : res = "potential"
1076 0 : IF (.NOT. my_accept_undefined) THEN
1077 : CALL cp_abort(__LOCATION__, &
1078 : "unit not yet fully specified, unit of kind "// &
1079 0 : TRIM(res))
1080 : END IF
1081 : CASE default
1082 19102 : CPABORT("unknown potential unit:"//TRIM(cp_to_string(basic_unit)))
1083 : END SELECT
1084 : CASE (cp_ukind_force)
1085 2959 : SELECT CASE (basic_unit)
1086 : CASE (cp_units_Newton)
1087 16 : res = "N"
1088 : CASE (cp_units_mNewton)
1089 2988 : res = "mN"
1090 : CASE (cp_units_au)
1091 0 : res = "au_f"
1092 : CASE (cp_units_none)
1093 0 : res = "force"
1094 0 : IF (.NOT. my_accept_undefined) THEN
1095 : CALL cp_abort(__LOCATION__, &
1096 : "unit not yet fully specified, unit of kind "// &
1097 0 : TRIM(res))
1098 : END IF
1099 : CASE default
1100 3004 : CPABORT("unknown potential unit:"//TRIM(cp_to_string(basic_unit)))
1101 : END SELECT
1102 : CASE (cp_ukind_efield)
1103 3779 : SELECT CASE (basic_unit)
1104 : CASE (cp_units_volt_per_m)
1105 2943 : res = "Vm-1"
1106 : CASE (cp_units_volt_per_nm)
1107 0 : res = "Vnm-1"
1108 : CASE (cp_units_volt_per_angstrom)
1109 0 : res = "Vangstrom-1"
1110 : CASE (cp_units_au)
1111 0 : res = "au_efield"
1112 : CASE (cp_units_none)
1113 0 : res = "electric field"
1114 0 : IF (.NOT. my_accept_undefined) THEN
1115 : CALL cp_abort(__LOCATION__, &
1116 : "unit not yet fully specified, unit of kind "// &
1117 0 : TRIM(res))
1118 : END IF
1119 : CASE default
1120 2943 : CPABORT("unknown efield unit:"//TRIM(cp_to_string(basic_unit)))
1121 : END SELECT
1122 : CASE (cp_ukind_dipole)
1123 826 : SELECT CASE (basic_unit)
1124 : CASE (cp_units_debye)
1125 826 : res = "debye"
1126 : CASE (cp_units_e_angstrom)
1127 0 : res = "e_angstrom"
1128 : CASE (cp_units_c_m)
1129 0 : res = "C_m"
1130 : CASE (cp_units_au)
1131 10 : res = "au_dip"
1132 : CASE (cp_units_none)
1133 0 : res = "dipole"
1134 0 : IF (.NOT. my_accept_undefined) THEN
1135 : CALL cp_abort(__LOCATION__, &
1136 : "unit not yet fully specified, unit of kind "// &
1137 0 : TRIM(res))
1138 : END IF
1139 : CASE default
1140 836 : 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 0 : //TRIM(cp_to_string(basic_unit)))
1146 : CASE default
1147 8648691 : CPABORT("unknown kind of unit:"//TRIM(cp_to_string(basic_kind)))
1148 : END SELECT
1149 8648691 : IF (my_power /= 1) THEN
1150 1309605 : a = LEN_TRIM(res)
1151 1309605 : CPASSERT(LEN(res) - a >= 3)
1152 1309605 : WRITE (res(a + 1:), "('^',i3)") my_power
1153 1309605 : CALL compress(res, .TRUE.)
1154 : END IF
1155 8648691 : 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 8016956 : 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 8016956 : res = ""
1177 8016956 : pos = 1
1178 8016956 : my_accept_undefined = .FALSE.
1179 8016956 : IF (PRESENT(accept_undefined)) my_accept_undefined = accept_undefined
1180 16665647 : DO i = 1, unit%n_kinds
1181 8648691 : CPASSERT(unit%kind_id(i) /= 0)
1182 8648691 : CPASSERT(pos < LEN(res))
1183 8648691 : my_unit = unit%unit_id(i)
1184 8648691 : has_defaults = .FALSE.
1185 8648691 : IF (PRESENT(defaults)) has_defaults = ASSOCIATED(defaults%units(1)%unit)
1186 8648691 : IF (my_unit == 0) THEN
1187 0 : IF (has_defaults) THEN
1188 0 : my_unit = defaults%units(unit%kind_id(i))%unit%unit_id(1)
1189 : ELSE
1190 0 : check = my_accept_undefined .OR. unit%kind_id(i) /= 0
1191 0 : CPASSERT(check)
1192 : END IF
1193 : END IF
1194 8648691 : IF (i > 1) THEN
1195 640507 : res(pos:pos) = "*"
1196 640507 : 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 8648691 : power=unit%power(i)))
1201 16665647 : pos = LEN_TRIM(res) + 1
1202 : END DO
1203 :
1204 8016956 : 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 4775691 : 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 4775691 : my_power = 1
1226 4775691 : IF (PRESENT(power)) my_power = power
1227 4775691 : res = value
1228 10091107 : DO i_unit = 1, unit%n_kinds
1229 5315416 : CPASSERT(unit%kind_id(i_unit) > 0)
1230 5315416 : my_basic_unit = unit%unit_id(i_unit)
1231 5315416 : IF (my_basic_unit == 0 .AND. unit%kind_id(i_unit) /= cp_ukind_undef) THEN
1232 0 : CPASSERT(PRESENT(defaults))
1233 0 : CPASSERT(ASSOCIATED(defaults%units(unit%kind_id(i_unit))%unit))
1234 0 : 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 10091107 : power=my_power*unit%power(i_unit))
1239 : END DO
1240 4775691 : 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 790516 : 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 790516 : my_power = 1
1262 790516 : IF (PRESENT(power)) my_power = power
1263 790516 : IF (PRESENT(defaults)) THEN
1264 : res = cp_unit_to_cp2k1(value=value, unit=unit, defaults=defaults, &
1265 0 : power=-my_power)
1266 : ELSE
1267 790516 : res = cp_unit_to_cp2k1(value=value, unit=unit, power=-my_power)
1268 : END IF
1269 790516 : 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 3865596 : 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 3865596 : CALL cp_unit_create(my_unit, unit_str)
1291 3865596 : IF (PRESENT(defaults)) THEN
1292 : res = cp_unit_to_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1293 0 : power=power)
1294 : ELSE
1295 3865596 : res = cp_unit_to_cp2k1(value=value, unit=my_unit, power=power)
1296 : END IF
1297 3865596 : CALL cp_unit_release(my_unit)
1298 104371092 : 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 586868 : 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 586868 : CALL cp_unit_create(my_unit, unit_str)
1320 586868 : IF (PRESENT(defaults)) THEN
1321 : res = cp_unit_from_cp2k1(value=value, unit=my_unit, defaults=defaults, &
1322 0 : power=power)
1323 : ELSE
1324 586868 : res = cp_unit_from_cp2k1(value=value, unit=my_unit, power=power)
1325 : END IF
1326 586868 : CALL cp_unit_release(my_unit)
1327 15845436 : 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 119579 : 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 119579 : res = .TRUE.
1343 1076211 : DO i = 1, SIZE(ref_unit%kind_id)
1344 956632 : IF (ref_unit%kind_id(i) == unit%kind_id(i)) CYCLE
1345 5456 : IF ((ref_unit%kind_id(1) == cp_ukind_undef) .AND. (ALL(ref_unit%kind_id(2:) == cp_ukind_none))) CYCLE
1346 : res = .FALSE.
1347 1076211 : EXIT
1348 : END DO
1349 :
1350 119579 : 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 157313 : 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 12101 : my_name = name
1367 12101 : CALL uppercase(my_name)
1368 :
1369 157313 : DO i = 1, cp_ukind_max
1370 145212 : NULLIFY (unit_set%units(i)%unit)
1371 3642401 : ALLOCATE (unit_set%units(i)%unit)
1372 : END DO
1373 157313 : DO i = 1, cp_ukind_max
1374 12101 : SELECT CASE (name)
1375 : CASE ('ATOM', 'ATOMIC', 'INTERNAL', 'CP2K')
1376 0 : IF (i == cp_ukind_angle) THEN
1377 : CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1378 0 : unit_id=[cp_units_rad], power=[1])
1379 : ELSE
1380 : CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], &
1381 0 : unit_id=[cp_units_au], power=[1])
1382 : END IF
1383 : CASE ('OUTPUT')
1384 12101 : 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 24202 : 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 24202 : 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 24202 : power=[1])
1394 : CASE (cp_ukind_temperature)
1395 : CALL cp_unit_create2(unit_set%units(i)%unit, kind_id=[i], unit_id=[cp_units_k], &
1396 24202 : 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 24202 : 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 24202 : 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 24202 : 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 24202 : 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 24202 : 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 24202 : 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 24202 : 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 24202 : power=[1])
1421 : CASE default
1422 0 : CPABORT("unhandled unit type "//TRIM(cp_to_string(i)))
1423 145212 : EXIT
1424 : END SELECT
1425 : CASE default
1426 145212 : CPABORT('unknown parameter set name '//TRIM(name))
1427 : END SELECT
1428 : END DO
1429 12101 : 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 12101 : SUBROUTINE cp_unit_set_release(unit_set)
1437 : TYPE(cp_unit_set_type), INTENT(INOUT) :: unit_set
1438 :
1439 : INTEGER :: i
1440 :
1441 157313 : DO i = 1, SIZE(unit_set%units)
1442 145212 : CALL cp_unit_release(unit_set%units(i)%unit)
1443 157313 : DEALLOCATE (unit_set%units(i)%unit)
1444 : END DO
1445 :
1446 12101 : 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 0 : 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 0 : "kjmol", "Ry", "eV", "keV", "K_e"), iw)
1458 0 : CALL format_units_as_xml("length", s2a("bohr", "m", "pm", "nm", "angstrom"), iw)
1459 0 : CALL format_units_as_xml("temperature", s2a("K", "au_temp"), iw)
1460 0 : CALL format_units_as_xml("pressure", s2a("bar", "atm", "kbar", "Pa", "MPa", "GPa", "au_p"), iw)
1461 0 : CALL format_units_as_xml("angle", s2a("rad", "deg"), iw)
1462 0 : CALL format_units_as_xml("time", s2a("s", "fs", "ps", "au_t", "wavenumber_t"), iw)
1463 0 : CALL format_units_as_xml("mass", s2a("kg", "amu", "m_e"), iw)
1464 0 : CALL format_units_as_xml("potential", s2a("volt", "au_pot"), iw)
1465 0 : 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 0 : "volt_per_angstrom", "au_efield"), iw)
1468 0 : CALL format_units_as_xml("dipole", s2a("debye", "e_angstrom", "C_m", "au_dip"), iw)
1469 :
1470 0 : 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 0 : 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 0 : WRITE (iw, FMT='(T2,A)') '<UNIT_KIND name="'//TRIM(unit_kind)//'">'
1487 0 : DO i = 1, SIZE(units_set)
1488 0 : WRITE (iw, FMT='(T3,A)') '<UNIT>'//TRIM(units_set(i))//'</UNIT>'
1489 : END DO
1490 0 : WRITE (iw, FMT='(T3,A)') '<UNIT>'//TRIM(unit_kind)//'</UNIT>' ! internal unit
1491 0 : WRITE (iw, FMT='(T2,A)') '</UNIT_KIND>'
1492 0 : END SUBROUTINE format_units_as_xml
1493 :
1494 0 : END MODULE cp_units
|