1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch 2!! 3!! This program is free software; you can redistribute it and/or modify 4!! it under the terms of the GNU General Public License as published by 5!! the Free Software Foundation; either version 2, or (at your option) 6!! any later version. 7!! 8!! This program is distributed in the hope that it will be useful, 9!! but WITHOUT ANY WARRANTY; without even the implied warranty of 10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11!! GNU General Public License for more details. 12!! 13!! You should have received a copy of the GNU General Public License 14!! along with this program; if not, write to the Free Software 15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16!! 02110-1301, USA. 17!! 18 19! 20!> Atomic weights should be read in "atomic mass units" (u) (not to 21!! be confused with mass in "atomic units"), that is, it should be given 22!! the relative atomic weight). 1 u is roughly the mass of the proton, 23!! and exactly one twelfth of mass of the ^{12}C isotope. The relation of the 24!! atomic mass unit and the atomic unit of mass, au_[mass], is: 25!! 26!! 1 au_[mass] = 5.485799110e-4 u 27!! 28!! The atomic unit of mass is the mass of the electron. Unfortunately, the 29!! code uses units of mass of (eV/A^2)(h/(2pieV))^2, which are related to 30!! atomic units through 1 cu_[mass] = 7.619963358 au_[mass] . So: 31!! 32!! 1 u = (1/5.485799110e-4) au_[mass] = (1/5.485799110e-4) * 33!! (1/7.619963358) cu_[mass] = 239.225360 cu_[mass]. 34 35#include "global.h" 36 37module unit_oct_m 38 39 implicit none 40 41 private 42 public :: & 43 unit_t, & 44 units_to_atomic, & 45 units_from_atomic, & 46 units_abbrev, & 47 operator(*), & 48 operator(/), & 49 operator(**), & 50 sqrt 51 52 type unit_t 53 ! Components are public by default 54 FLOAT :: factor 55 character(len=20) :: abbrev !< common abbreviation of the unit name 56 character(len=50) :: name !< common name 57 end type unit_t 58 59 interface operator (*) 60 module procedure units_multiply 61 end interface operator (*) 62 63 interface operator (/) 64 module procedure units_divide 65 end interface operator (/) 66 67 interface operator (**) 68 module procedure units_pow 69 end interface operator (**) 70 71 interface units_to_atomic 72 module procedure dunits_to_atomic, zunits_to_atomic 73 end interface units_to_atomic 74 75 interface units_from_atomic 76 module procedure dunits_from_atomic, zunits_from_atomic 77 end interface units_from_atomic 78 79 interface sqrt 80 module procedure units_sqrt 81 end interface sqrt 82 83contains 84 85 !----------------------------------------------- 86 87 FLOAT elemental pure function dunits_to_atomic(this, val) result(res) 88 type(unit_t), intent(in) :: this 89 FLOAT, intent(in) :: val 90 91 res = val*this%factor 92 93 end function dunits_to_atomic 94 95 !----------------------------------------------- 96 97 CMPLX elemental pure function zunits_to_atomic(this, val) result(res) 98 type(unit_t), intent(in) :: this 99 CMPLX, intent(in) :: val 100 101 res = val*this%factor 102 103 end function zunits_to_atomic 104 105 !----------------------------------------------- 106 107 FLOAT elemental pure function dunits_from_atomic(this, val) result(res) 108 type(unit_t), intent(in) :: this 109 FLOAT, intent(in) :: val 110 111 res = val/this%factor 112 113 end function dunits_from_atomic 114 115 !----------------------------------------------- 116 117 CMPLX elemental pure function zunits_from_atomic(this, val) result(res) 118 type(unit_t), intent(in) :: this 119 CMPLX, intent(in) :: val 120 121 res = val/this%factor 122 123 end function zunits_from_atomic 124 125 !----------------------------------------------- 126 127 character(len=20) pure function units_abbrev(this) result(abbrev) 128 type(unit_t), intent(in) :: this 129 130 abbrev = this%abbrev 131 end function units_abbrev 132 133 !----------------------------------------------- 134 135 type(unit_t) pure function units_multiply(aa, bb) result(cc) 136 type(unit_t), intent(in) :: aa 137 type(unit_t), intent(in) :: bb 138 139 cc%factor = aa%factor*bb%factor 140 cc%abbrev = trim(aa%abbrev)//'*'//trim(bb%abbrev) 141 142 end function units_multiply 143 144 !----------------------------------------------- 145 146 type(unit_t) pure function units_divide(aa, bb) result(cc) 147 type(unit_t), intent(in) :: aa 148 type(unit_t), intent(in) :: bb 149 150 cc%factor = aa%factor/bb%factor 151 cc%abbrev = trim(aa%abbrev)//'/'//trim(bb%abbrev) 152 153 end function units_divide 154 !----------------------------------------------- 155 156 type(unit_t) pure function units_pow(aa, nn) result(cc) 157 type(unit_t), intent(in) :: aa 158 integer, intent(in) :: nn 159 160 cc%factor = aa%factor**nn 161 162 ! We have to do the conversion by hand. This is ugly, but we 163 ! cannot use write here since this function might be called inside 164 ! another write (stupid Fortran). 165 166 select case(nn) 167 case(-3) 168 cc%abbrev = trim(aa%abbrev)//'^-3' 169 case(-2) 170 cc%abbrev = trim(aa%abbrev)//'^-2' 171 case(-1) 172 cc%abbrev = trim(aa%abbrev)//'^-1' 173 case(0) 174 cc%abbrev = '1' 175 case(1) 176 cc%abbrev = trim(aa%abbrev) 177 case(2) 178 cc%abbrev = trim(aa%abbrev)//'^2' 179 case(3) 180 cc%abbrev = trim(aa%abbrev)//'^3' 181 case(4) 182 cc%abbrev = trim(aa%abbrev)//'^4' 183 case(5) 184 cc%abbrev = trim(aa%abbrev)//'^5' 185 case default 186 cc%abbrev = trim(aa%abbrev)//'^n' 187 end select 188 189 end function units_pow 190 191 192 !----------------------------------------------- 193 194 type(unit_t) pure function units_sqrt(aa) result(cc) 195 type(unit_t), intent(in) :: aa 196 197 cc%factor = sqrt(aa%factor) 198 cc%abbrev = 'sqrt('//trim(aa%abbrev)//')' 199 200 end function units_sqrt 201 202end module unit_oct_m 203 204!! Local Variables: 205!! mode: f90 206!! coding: utf-8 207!! End: 208