properties.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Aug 14 20:14:16 2018
  4. @author: USER
  5. """
  6. # Codes are free to use. Do whatever you want
  7. from __future__ import absolute_import
  8. """Read raw data"""
  9. ####################### LIBRARY #############################
  10. # exceptions library
  11. from exceptions import (Data_Format_Exception,
  12. Data_Match_Exception)
  13. # Python stdlib imports
  14. import datetime
  15. # data processing library
  16. import numpy as np
  17. # pyrod library
  18. ####################### CONSTANT ############################
  19. # constant
  20. ####################### FUNCTIONS ###########################
  21. ######################## CLASSS #############################
  22. # film property--roughenss, surface roughness and interface roughenss
  23. class roughness(object):
  24. def __init__(self, iq):
  25. self.q = iq
  26. # r_beta -- robbinson roughness factor
  27. def robinson_roughness(self, r_beta):
  28. """Robinson roughness model: beta is the film fraction in first layer.
  29. In surface layer n, the fraction is beta^n.
  30. This fuction is for cubic crystal, which is common for pervoskite
  31. [1]. Robinson, Ian K. "Crystal truncation rods and surface roughness."
  32. Physical Review B 33.6 (1986): 3830."""
  33. if r_beta < 0:
  34. raise Data_Format_Exception('robinsion_roughness factor should be positive')
  35. r_factor = (1-r_beta)/((1-r_beta)**2 + 4*r_beta*(np.sin(np.pi*self.q)**2))**0.5
  36. return r_factor
  37. def interface_roughness(self, i_beta):
  38. """interface roughness model, refinement for small angle reflection
  39. exp(-q2*r2)"""
  40. if i_beta < 0:
  41. raise Data_Format_Exception('interface_roughness factor should be positive')
  42. i_factor = np.exp(-1*(i_beta*self.q))
  43. return i_factor
  44. # film vacancy--gradient vacancy, layer surface
  45. class vacancy(object):
  46. def __init__(self, iq, var_list, var_table):
  47. self.q = iq
  48. self.l = var_list
  49. self.t = var_table
  50. def gradient_vacancy(self, alpha, va, vi):
  51. """
  52. Normally, A and O is easy to exist vancany in ABO3, and exponential function is
  53. good fitting in XRD fitting. However, some materials have special vancany mdoel
  54. For example: the oxygen vancany distribtion of SCoO3 and SrFeO3, oxygen vancany
  55. is very complex. Even for STO, linear oxygen vancany clustering is very common
  56. in thermal threatment.
  57. ...............................
  58. [1].Druce, J., et al. "Surface termination and subsurface restructuring of
  59. perovskite-based solid oxide electrode materials." Energy & Environmental
  60. Science 7.11 (2014): 3593-3599.
  61. """
  62. # check and put vacancy at interface and surface in order
  63. if va < 0 or vi < 0 or alpha < 0:
  64. raise Data_Format_Exception('interface_roughness factor should be positive')
  65. vs = np.max([va, vi])
  66. ve = np.min([va, vi])
  67. # layers
  68. layer = range(len(self.t['posz_list']))
  69. # factors
  70. a = (vs - ve)/(np.exp(-alpha*(layer-1)) - 1)
  71. b = ve - a
  72. gradient_v = a + b*np.exp(-alpha*np.array(layer))
  73. return gradient_v
  74. def surface_vacancy(self, ions, vs, layers = [-1]):
  75. """vacancy for specified layers and ions. Normally, A site ion and O2- is vacancy"""
  76. if not len(ions) == len(vs):
  77. raise Data_Match_Exception('ions number should match vacancy number!')
  78. ocu_table = self.t['ocu_table']
  79. ion_table = self.t['ion_table']
  80. ion_index = 0
  81. for ion in ions:
  82. for layer in layers:
  83. layer_ion = ion_table[-1*(1 + layer)]
  84. ion_locate = layer_ion.index(ion)
  85. ocu_table[-1*(1 + layer), ion_locate] = 1-vs[ion_index]
  86. ion_index += 1
  87. return ocu_table
  88. # strain relex for epitaxial films. 50uc, normally.
  89. # interface relax and surface relax
  90. class relax(object):
  91. def __init__(self, posz_list):
  92. self.pz = posz_list
  93. def stain_relax(self, cl, bc, sc):
  94. # sr -- strain relax
  95. # sc -- strained lattice c
  96. # cl -- critalc layaers number
  97. # bc -- bulk lattice c
  98. ln = len(self.pz)
  99. sr = self.pz*((sc-bc)*np.exp(-np.array(range(ln)/cl) + bc))
  100. return sr
  101. # layer relax include interface relax and surface relax
  102. # surface relax is common and well studied
  103. # interface relax and second surface layer relax is also included
  104. def layer_relax(self, rv, layers):
  105. if not len(rv) == len(layers):
  106. raise Data_Match_Exception('relax value number should match layer number')
  107. lr = self.pz
  108. # input relax value in posz_list
  109. for layer in layers:
  110. lr[layer] = rv[layer]
  111. return lr