ADD_MESH_CLUSTER.PY 49KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) 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 Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. import bpy
  19. import io
  20. import math
  21. import os
  22. import copy
  23. from math import pi, cos, sin, tan, sqrt
  24. from mathutils import Vector, Matrix
  25. from copy import copy
  26. # -----------------------------------------------------------------------------
  27. # Atom, stick and element data
  28. # This is a list that contains some data of all possible elements. The structure
  29. # is as follows:
  30. #
  31. # 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
  32. #
  33. # No., name, short name, color, radius (used), radius (covalent), radius (atomic),
  34. #
  35. # charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
  36. # charge states for any atom are listed, if existing.
  37. # The list is fixed and cannot be changed ... (see below)
  38. ATOM_CLUSTER_ELEMENTS_DEFAULT = (
  39. ( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
  40. ( 2, "Helium", "He", ( 0.85, 1.0, 1.0, 1.0), 0.93, 0.93, 0.49 ),
  41. ( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
  42. ( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0, 1.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
  43. ( 5, "Boron", "B", ( 1.0, 0.70, 0.70, 1.0), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
  44. ( 6, "Carbon", "C", ( 0.56, 0.56, 0.56, 1.0), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
  45. ( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97, 1.0), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ),
  46. ( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05, 1.0), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ),
  47. ( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31, 1.0), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
  48. (10, "Neon", "Ne", ( 0.70, 0.89, 0.96, 1.0), 0.71, 0.71, 0.51 , 1 , 1.12 ),
  49. (11, "Sodium", "Na", ( 0.67, 0.36, 0.94, 1.0), 1.54, 1.54, 2.23 , 1 , 0.97 ),
  50. (12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0, 1.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
  51. (13, "Aluminium", "Al", ( 0.74, 0.65, 0.65, 1.0), 1.18, 1.18, 1.82 , 3 , 0.51 ),
  52. (14, "Silicon", "Si", ( 0.94, 0.78, 0.62, 1.0), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ),
  53. (15, "Phosphorus", "P", ( 1.0, 0.50, 0.0, 1.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ),
  54. (16, "Sulfur", "S", ( 1.0, 1.0, 0.18, 1.0), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ),
  55. (17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12, 1.0), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ),
  56. (18, "Argon", "Ar", ( 0.50, 0.81, 0.89, 1.0), 0.98, 0.98, 0.88 , 1 , 1.54 ),
  57. (19, "Potassium", "K", ( 0.56, 0.25, 0.83, 1.0), 2.03, 2.03, 2.77 , 1 , 0.81 ),
  58. (20, "Calcium", "Ca", ( 0.23, 1.0, 0.0, 1.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
  59. (21, "Scandium", "Sc", ( 0.90, 0.90, 0.90, 1.0), 1.44, 1.44, 2.09 , 3 , 0.73 ),
  60. (22, "Titanium", "Ti", ( 0.74, 0.76, 0.78, 1.0), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ),
  61. (23, "Vanadium", "V", ( 0.65, 0.65, 0.67, 1.0), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ),
  62. (24, "Chromium", "Cr", ( 0.54, 0.6, 0.78, 1.0), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ),
  63. (25, "Manganese", "Mn", ( 0.61, 0.47, 0.78, 1.0), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ),
  64. (26, "Iron", "Fe", ( 0.87, 0.4, 0.2, 1.0), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
  65. (27, "Cobalt", "Co", ( 0.94, 0.56, 0.62, 1.0), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
  66. (28, "Nickel", "Ni", ( 0.31, 0.81, 0.31, 1.0), 1.15, 1.15, 1.62 , 2 , 0.69 ),
  67. (29, "Copper", "Cu", ( 0.78, 0.50, 0.2, 1.0), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
  68. (30, "Zinc", "Zn", ( 0.49, 0.50, 0.69, 1.0), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
  69. (31, "Gallium", "Ga", ( 0.76, 0.56, 0.56, 1.0), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
  70. (32, "Germanium", "Ge", ( 0.4, 0.56, 0.56, 1.0), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ),
  71. (33, "Arsenic", "As", ( 0.74, 0.50, 0.89, 1.0), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ),
  72. (34, "Selenium", "Se", ( 1.0, 0.63, 0.0, 1.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ),
  73. (35, "Bromine", "Br", ( 0.65, 0.16, 0.16, 1.0), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ),
  74. (36, "Krypton", "Kr", ( 0.36, 0.72, 0.81, 1.0), 1.31, 1.31, 1.24 ),
  75. (37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69, 1.0), 2.16, 2.16, 2.98 , 1 , 1.47 ),
  76. (38, "Strontium", "Sr", ( 0.0, 1.0, 0.0, 1.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
  77. (39, "Yttrium", "Y", ( 0.58, 1.0, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
  78. (40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87, 1.0), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
  79. (41, "Niobium", "Nb", ( 0.45, 0.76, 0.78, 1.0), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ),
  80. (42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70, 1.0), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ),
  81. (43, "Technetium", "Tc", ( 0.23, 0.61, 0.61, 1.0), 1.27, 1.27, 1.95 , 7 , 0.97 ),
  82. (44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56, 1.0), 1.25, 1.25, 1.89 , 4 , 0.67 ),
  83. (45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54, 1.0), 1.25, 1.25, 1.83 , 3 , 0.68 ),
  84. (46, "Palladium", "Pd", ( 0.0, 0.41, 0.52, 1.0), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
  85. (47, "Silver", "Ag", ( 0.75, 0.75, 0.75, 1.0), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
  86. (48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56, 1.0), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
  87. (49, "Indium", "In", ( 0.65, 0.45, 0.45, 1.0), 1.44, 1.44, 2.00 , 3 , 0.81 ),
  88. (50, "Tin", "Sn", ( 0.4, 0.50, 0.50, 1.0), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ),
  89. (51, "Antimony", "Sb", ( 0.61, 0.38, 0.70, 1.0), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ),
  90. (52, "Tellurium", "Te", ( 0.83, 0.47, 0.0, 1.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ),
  91. (53, "Iodine", "I", ( 0.58, 0.0, 0.58, 1.0), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ),
  92. (54, "Xenon", "Xe", ( 0.25, 0.61, 0.69, 1.0), 1.31, 1.31, 1.24 ),
  93. (55, "Caesium", "Cs", ( 0.34, 0.09, 0.56, 1.0), 2.35, 2.35, 3.35 , 1 , 1.67 ),
  94. (56, "Barium", "Ba", ( 0.0, 0.78, 0.0, 1.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
  95. (57, "Lanthanum", "La", ( 0.43, 0.83, 1.0, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ),
  96. (58, "Cerium", "Ce", ( 1.0, 1.0, 0.78, 1.0), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ),
  97. (59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78, 1.0), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
  98. (60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78, 1.0), 1.64, 1.64, 2.64 , 3 , 0.99 ),
  99. (61, "Promethium", "Pm", ( 0.63, 1.0, 0.78, 1.0), 1.63, 1.63, 2.62 , 3 , 0.97 ),
  100. (62, "Samarium", "Sm", ( 0.56, 1.0, 0.78, 1.0), 1.62, 1.62, 2.59 , 3 , 0.96 ),
  101. (63, "Europium", "Eu", ( 0.38, 1.0, 0.78, 1.0), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
  102. (64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78, 1.0), 1.61, 1.61, 2.54 , 3 , 0.93 ),
  103. (65, "Terbium", "Tb", ( 0.18, 1.0, 0.78, 1.0), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
  104. (66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78, 1.0), 1.59, 1.59, 2.49 , 3 , 0.90 ),
  105. (67, "Holmium", "Ho", ( 0.0, 1.0, 0.61, 1.0), 1.58, 1.58, 2.47 , 3 , 0.89 ),
  106. (68, "Erbium", "Er", ( 0.0, 0.90, 0.45, 1.0), 1.57, 1.57, 2.45 , 3 , 0.88 ),
  107. (69, "Thulium", "Tm", ( 0.0, 0.83, 0.32, 1.0), 1.56, 1.56, 2.42 , 3 , 0.87 ),
  108. (70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21, 1.0), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
  109. (71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14, 1.0), 1.56, 1.56, 2.25 , 3 , 0.85 ),
  110. (72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
  111. (73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
  112. (74, "Tungsten", "W", ( 0.12, 0.58, 0.83, 1.0), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
  113. (75, "Rhenium", "Re", ( 0.14, 0.49, 0.67, 1.0), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
  114. (76, "Osmium", "Os", ( 0.14, 0.4, 0.58, 1.0), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
  115. (77, "Iridium", "Ir", ( 0.09, 0.32, 0.52, 1.0), 1.27, 1.27, 1.87 , 4 , 0.68 ),
  116. (78, "Platinum", "Pt", ( 0.81, 0.81, 0.87, 1.0), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
  117. (79, "Gold", "Au", ( 1.0, 0.81, 0.13, 1.0), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
  118. (80, "Mercury", "Hg", ( 0.72, 0.72, 0.81, 1.0), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
  119. (81, "Thallium", "Tl", ( 0.65, 0.32, 0.30, 1.0), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
  120. (82, "Lead", "Pb", ( 0.34, 0.34, 0.38, 1.0), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
  121. (83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70, 1.0), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ),
  122. (84, "Polonium", "Po", ( 0.67, 0.36, 0.0, 1.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
  123. (85, "Astatine", "At", ( 0.45, 0.30, 0.27, 1.0), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ),
  124. (86, "Radon", "Rn", ( 0.25, 0.50, 0.58, 1.0), 1.00, 1.00, 1.34 ),
  125. (87, "Francium", "Fr", ( 0.25, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 , 1 , 1.80 ),
  126. (88, "Radium", "Ra", ( 0.0, 0.49, 0.0, 1.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
  127. (89, "Actinium", "Ac", ( 0.43, 0.67, 0.98, 1.0), 1.00, 1.00, 1.00 , 3 , 1.18 ),
  128. (90, "Thorium", "Th", ( 0.0, 0.72, 1.0, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
  129. (91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ),
  130. (92, "Uranium", "U", ( 0.0, 0.56, 1.0, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ),
  131. (93, "Neptunium", "Np", ( 0.0, 0.50, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ),
  132. (94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
  133. (95, "Americium", "Am", ( 0.32, 0.36, 0.94, 1.0), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
  134. (96, "Curium", "Cm", ( 0.47, 0.36, 0.89, 1.0), 1.00, 1.00, 1.00 ),
  135. (97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89, 1.0), 1.00, 1.00, 1.00 ),
  136. (98, "Californium", "Cf", ( 0.63, 0.21, 0.83, 1.0), 1.00, 1.00, 1.00 ),
  137. (99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83, 1.0), 1.00, 1.00, 1.00 ),
  138. (100, "Fermium", "Fm", ( 0.70, 0.12, 0.72, 1.0), 1.00, 1.00, 1.00 ),
  139. (101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65, 1.0), 1.00, 1.00, 1.00 ),
  140. (102, "Nobelium", "No", ( 0.74, 0.05, 0.52, 1.0), 1.00, 1.00, 1.00 ),
  141. (103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 ),
  142. (104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
  143. (105, "Default", "Default", ( 1.0, 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
  144. (106, "Stick", "Stick", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
  145. )
  146. # This list here contains all data of the elements and will be used during
  147. # runtime. It is a list of classes.
  148. # During executing Atomic Blender, the list will be initialized with the fixed
  149. # data from above via the class structure below (CLASS_atom_pdb_Elements). We
  150. # have then one fixed list (above), which will never be changed, and a list of
  151. # classes with same data. The latter can be modified via loading a separate
  152. # custom data file.
  153. ATOM_CLUSTER_ELEMENTS = []
  154. ATOM_CLUSTER_ALL_ATOMS = []
  155. # This is the class, which stores the properties for one element.
  156. class CLASS_atom_cluster_Elements(object):
  157. __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
  158. def __init__(self, number, name, short_name, color, radii, radii_ionic):
  159. self.number = number
  160. self.name = name
  161. self.short_name = short_name
  162. self.color = color
  163. self.radii = radii
  164. self.radii_ionic = radii_ionic
  165. # This is the class, which stores the properties of one atom.
  166. class CLASS_atom_cluster_atom(object):
  167. __slots__ = ('location')
  168. def __init__(self, location):
  169. self.location = location
  170. # -----------------------------------------------------------------------------
  171. # Read atom data
  172. def DEF_atom_read_atom_data():
  173. del ATOM_CLUSTER_ELEMENTS[:]
  174. for item in ATOM_CLUSTER_ELEMENTS_DEFAULT:
  175. # All three radii into a list
  176. radii = [item[4],item[5],item[6]]
  177. # The handling of the ionic radii will be done later. So far, it is an
  178. # empty list.
  179. radii_ionic = []
  180. li = CLASS_atom_cluster_Elements(item[0],item[1],item[2],item[3],
  181. radii,radii_ionic)
  182. ATOM_CLUSTER_ELEMENTS.append(li)
  183. # -----------------------------------------------------------------------------
  184. # Routines for shapes
  185. def vec_in_sphere(atom_pos,size, skin):
  186. regular = True
  187. inner = True
  188. if atom_pos.length > size/2.0:
  189. regular = False
  190. if atom_pos.length < (size/2.0)*(1-skin):
  191. inner = False
  192. return (regular, inner)
  193. def vec_in_parabole(atom_pos, height, diameter):
  194. regular = True
  195. inner = True
  196. px = atom_pos[0]
  197. py = atom_pos[1]
  198. pz = atom_pos[2] + height/2.0
  199. a = diameter / sqrt(4 * height)
  200. if pz < 0.0:
  201. return (False, False)
  202. if px == 0.0 and py == 0.0:
  203. return (True, True)
  204. if py == 0.0:
  205. y = 0.0
  206. x = a * a * pz / px
  207. z = x * x / (a * a)
  208. else:
  209. y = pz * py * a * a / (px*px + py*py)
  210. x = y * px / py
  211. z = (x*x + y*y) / (a * a)
  212. if( atom_pos.length > sqrt(x*x+y*y+z*z) ):
  213. regular = False
  214. return (regular, inner)
  215. def vec_in_pyramide_square(atom_pos, size, skin):
  216. """
  217. Please, if possible leave all this! The code documents the
  218. mathemetical way of cutting a pyramide with square base.
  219. P1 = Vector((-size/2, 0.0, -size/4))
  220. P2 = Vector((0.0, -size/2, -size/4))
  221. P4 = Vector((size/2, 0.0, -size/4))
  222. P5 = Vector((0.0, size/2, -size/4))
  223. P6 = Vector((0.0, 0.0, size/4))
  224. # First face
  225. v11 = P1 - P2
  226. v12 = P1 - P6
  227. n1 = v11.cross(v12)
  228. g1 = -n1 * P1
  229. # Second face
  230. v21 = P6 - P4
  231. v22 = P6 - P5
  232. n2 = v21.cross(v22)
  233. g2 = -n2 * P6
  234. # Third face
  235. v31 = P1 - P5
  236. v32 = P1 - P6
  237. n3 = v32.cross(v31)
  238. g3 = -n3 * P1
  239. # Forth face
  240. v41 = P6 - P2
  241. v42 = P2 - P4
  242. n4 = v41.cross(v42)
  243. g4 = -n4 * P2
  244. # Fith face, base
  245. v51 = P2 - P1
  246. v52 = P2 - P4
  247. n5 = v51.cross(v52)
  248. g5 = -n5 * P2
  249. """
  250. # A much faster way for calculation:
  251. size2 = size * size
  252. size3 = size2 * size
  253. n1 = Vector((-1/4, -1/4, 1/4)) * size2
  254. g1 = -1/16 * size3
  255. n2 = Vector(( 1/4, 1/4, 1/4)) * size2
  256. g2 = g1
  257. n3 = Vector((-1/4, 1/4, 1/4)) * size2
  258. g3 = g1
  259. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  260. g4 = g1
  261. n5 = Vector(( 0.0, 0.0, -1/2)) * size2
  262. g5 = -1/8 * size3
  263. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  264. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  265. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  266. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  267. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  268. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  269. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  270. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  271. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  272. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  273. regular = True
  274. inner = True
  275. if(atom_pos.length > on_plane_1):
  276. regular = False
  277. if(atom_pos.length > on_plane_2):
  278. regular = False
  279. if(atom_pos.length > on_plane_3):
  280. regular = False
  281. if(atom_pos.length > on_plane_4):
  282. regular = False
  283. if(atom_pos.length > on_plane_5):
  284. regular = False
  285. if skin == 1.0:
  286. return (regular, inner)
  287. size = size * (1.0 - skin)
  288. size2 = size * size
  289. size3 = size2 * size
  290. n1 = Vector((-1/4, -1/4, 1/4)) * size2
  291. g1 = -1/16 * size3
  292. n2 = Vector(( 1/4, 1/4, 1/4)) * size2
  293. g2 = g1
  294. n3 = Vector((-1/4, 1/4, 1/4)) * size2
  295. g3 = g1
  296. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  297. g4 = g1
  298. n5 = Vector(( 0.0, 0.0, -1/2)) * size2
  299. g5 = -1/8 * size3
  300. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  301. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  302. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  303. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  304. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  305. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  306. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  307. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  308. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  309. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  310. inner = False
  311. if(atom_pos.length > on_plane_1):
  312. inner = True
  313. if(atom_pos.length > on_plane_2):
  314. inner = True
  315. if(atom_pos.length > on_plane_3):
  316. inner = True
  317. if(atom_pos.length > on_plane_4):
  318. inner = True
  319. if(atom_pos.length > on_plane_5):
  320. inner = True
  321. return (regular, inner)
  322. def vec_in_pyramide_hex_abc(atom_pos, size, skin):
  323. a = size/2.0
  324. #c = size/2.0*cos((30/360)*2.0*pi)
  325. c = size * 0.4330127020
  326. #s = size/2.0*sin((30/360)*2.0*pi)
  327. s = size * 0.25
  328. #h = 2.0 * (sqrt(6.0)/3.0) * c
  329. h = 1.632993162 * c
  330. """
  331. Please, if possible leave all this! The code documents the
  332. mathemetical way of cutting a tetraeder.
  333. P1 = Vector((0.0, a, 0.0))
  334. P2 = Vector(( -c, -s, 0.0))
  335. P3 = Vector(( c, -s, 0.0))
  336. P4 = Vector((0.0, 0.0, h))
  337. C = (P1+P2+P3+P4)/4.0
  338. P1 = P1 - C
  339. P2 = P2 - C
  340. P3 = P3 - C
  341. P4 = P4 - C
  342. # First face
  343. v11 = P1 - P2
  344. v12 = P1 - P4
  345. n1 = v11.cross(v12)
  346. g1 = -n1 * P1
  347. # Second face
  348. v21 = P2 - P3
  349. v22 = P2 - P4
  350. n2 = v21.cross(v22)
  351. g2 = -n2 * P2
  352. # Third face
  353. v31 = P3 - P1
  354. v32 = P3 - P4
  355. n3 = v31.cross(v32)
  356. g3 = -n3 * P3
  357. # Forth face
  358. v41 = P2 - P1
  359. v42 = P2 - P3
  360. n4 = v41.cross(v42)
  361. g4 = -n4 * P1
  362. """
  363. n1 = Vector(( -h*(a+s), c*h, c*a ))
  364. g1 = -1/2*c*(a*h+s*h)
  365. n2 = Vector(( 0, -2*c*h, 2*c*s ))
  366. g2 = -1/2*c*(a*h+s*h)
  367. n3 = Vector(( h*(a+s), c*h, a*c ))
  368. g3 = -1/2*c*(a*h+s*h)
  369. n4 = Vector(( 0, 0, -2*c*(s+a) ))
  370. g4 = -1/2*h*c*(s+a)
  371. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  372. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  373. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  374. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  375. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  376. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  377. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  378. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  379. regular = True
  380. inner = True
  381. if(atom_pos.length > on_plane_1):
  382. regular = False
  383. if(atom_pos.length > on_plane_2):
  384. regular = False
  385. if(atom_pos.length > on_plane_3):
  386. regular = False
  387. if(atom_pos.length > on_plane_4):
  388. regular = False
  389. if skin == 1.0:
  390. return (regular, inner)
  391. size = size * (1.0 - skin)
  392. a = size/2.0
  393. #c = size/2.0*cos((30/360)*2.0*pi)
  394. c= size * 0.4330127020
  395. #s = size/2.0*sin((30/360)*2.0*pi)
  396. s = size * 0.25
  397. #h = 2.0 * (sqrt(6.0)/3.0) * c
  398. h = 1.632993162 * c
  399. n1 = Vector(( -h*(a+s), c*h, c*a ))
  400. g1 = -1/2*c*(a*h+s*h)
  401. n2 = Vector(( 0, -2*c*h, 2*c*s ))
  402. g2 = -1/2*c*(a*h+s*h)
  403. n3 = Vector(( h*(a+s), c*h, a*c ))
  404. g3 = -1/2*c*(a*h+s*h)
  405. n4 = Vector(( 0, 0, -2*c*(s+a) ))
  406. g4 = -1/2*h*c*(s+a)
  407. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  408. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  409. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  410. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  411. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  412. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  413. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  414. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  415. inner = False
  416. if(atom_pos.length > on_plane_1):
  417. inner = True
  418. if(atom_pos.length > on_plane_2):
  419. inner = True
  420. if(atom_pos.length > on_plane_3):
  421. inner = True
  422. if(atom_pos.length > on_plane_4):
  423. inner = True
  424. return (regular, inner)
  425. def vec_in_octahedron(atom_pos,size, skin):
  426. regular = True
  427. inner = True
  428. """
  429. Please, if possible leave all this! The code documents the
  430. mathemetical way of cutting an octahedron.
  431. P1 = Vector((-size/2, 0.0, 0.0))
  432. P2 = Vector((0.0, -size/2, 0.0))
  433. P3 = Vector((0.0, 0.0, -size/2))
  434. P4 = Vector((size/2, 0.0, 0.0))
  435. P5 = Vector((0.0, size/2, 0.0))
  436. P6 = Vector((0.0, 0.0, size/2))
  437. # First face
  438. v11 = P2 - P1
  439. v12 = P2 - P3
  440. n1 = v11.cross(v12)
  441. g1 = -n1 * P2
  442. # Second face
  443. v21 = P1 - P5
  444. v22 = P1 - P3
  445. n2 = v21.cross(v22)
  446. g2 = -n2 * P1
  447. # Third face
  448. v31 = P1 - P2
  449. v32 = P1 - P6
  450. n3 = v31.cross(v32)
  451. g3 = -n3 * P1
  452. # Forth face
  453. v41 = P6 - P2
  454. v42 = P2 - P4
  455. n4 = v41.cross(v42)
  456. g4 = -n4 * P2
  457. # Fith face
  458. v51 = P2 - P3
  459. v52 = P2 - P4
  460. n5 = v51.cross(v52)
  461. g5 = -n5 * P2
  462. # Six face
  463. v61 = P6 - P4
  464. v62 = P6 - P5
  465. n6 = v61.cross(v62)
  466. g6 = -n6 * P6
  467. # Seventh face
  468. v71 = P5 - P4
  469. v72 = P5 - P3
  470. n7 = v71.cross(v72)
  471. g7 = -n7 * P5
  472. # Eigth face
  473. v81 = P1 - P5
  474. v82 = P1 - P6
  475. n8 = v82.cross(v81)
  476. g8 = -n8 * P1
  477. """
  478. # A much faster way for calculation:
  479. size2 = size * size
  480. size3 = size2 * size
  481. n1 = Vector((-1/4, -1/4, -1/4)) * size2
  482. g1 = -1/8 * size3
  483. n2 = Vector((-1/4, 1/4, -1/4)) * size2
  484. g2 = g1
  485. n3 = Vector((-1/4, -1/4, 1/4)) * size2
  486. g3 = g1
  487. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  488. g4 = g1
  489. n5 = Vector(( 1/4, -1/4, -1/4)) * size2
  490. g5 = g1
  491. n6 = Vector(( 1/4, 1/4, 1/4)) * size2
  492. g6 = g1
  493. n7 = Vector(( 1/4, 1/4, -1/4)) * size2
  494. g7 = g1
  495. n8 = Vector((-1/4, 1/4, 1/4)) * size2
  496. g8 = g1
  497. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  498. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  499. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  500. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  501. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  502. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  503. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  504. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  505. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  506. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  507. distance_plane_6 = abs((n6 @ atom_pos - g6)/n6.length)
  508. on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
  509. distance_plane_7 = abs((n7 @ atom_pos - g7)/n7.length)
  510. on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
  511. distance_plane_8 = abs((n8 @ atom_pos - g8)/n8.length)
  512. on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
  513. if(atom_pos.length > on_plane_1):
  514. regular = False
  515. if(atom_pos.length > on_plane_2):
  516. regular = False
  517. if(atom_pos.length > on_plane_3):
  518. regular = False
  519. if(atom_pos.length > on_plane_4):
  520. regular = False
  521. if(atom_pos.length > on_plane_5):
  522. regular = False
  523. if(atom_pos.length > on_plane_6):
  524. regular = False
  525. if(atom_pos.length > on_plane_7):
  526. regular = False
  527. if(atom_pos.length > on_plane_8):
  528. regular = False
  529. if skin == 1.0:
  530. return (regular, inner)
  531. size = size * (1.0 - skin)
  532. size2 = size * size
  533. size3 = size2 * size
  534. n1 = Vector((-1/4, -1/4, -1/4)) * size2
  535. g1 = -1/8 * size3
  536. n2 = Vector((-1/4, 1/4, -1/4)) * size2
  537. g2 = g1
  538. n3 = Vector((-1/4, -1/4, 1/4)) * size2
  539. g3 = g1
  540. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  541. g4 = g1
  542. n5 = Vector(( 1/4, -1/4, -1/4)) * size2
  543. g5 = g1
  544. n6 = Vector(( 1/4, 1/4, 1/4)) * size2
  545. g6 = g1
  546. n7 = Vector(( 1/4, 1/4, -1/4)) * size2
  547. g7 = g1
  548. n8 = Vector((-1/4, 1/4, 1/4)) * size2
  549. g8 = g1
  550. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  551. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  552. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  553. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  554. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  555. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  556. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  557. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  558. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  559. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  560. distance_plane_6 = abs((n6 @ atom_pos - g6)/n6.length)
  561. on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
  562. distance_plane_7 = abs((n7 @ atom_pos - g7)/n7.length)
  563. on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
  564. distance_plane_8 = abs((n8 @ atom_pos - g8)/n8.length)
  565. on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
  566. inner = False
  567. if(atom_pos.length > on_plane_1):
  568. inner = True
  569. if(atom_pos.length > on_plane_2):
  570. inner = True
  571. if(atom_pos.length > on_plane_3):
  572. inner = True
  573. if(atom_pos.length > on_plane_4):
  574. inner = True
  575. if(atom_pos.length > on_plane_5):
  576. inner = True
  577. if(atom_pos.length > on_plane_6):
  578. inner = True
  579. if(atom_pos.length > on_plane_7):
  580. inner = True
  581. if(atom_pos.length > on_plane_8):
  582. inner = True
  583. return (regular, inner)
  584. def vec_in_truncated_octahedron(atom_pos,size, skin):
  585. regular = True
  586. inner = True
  587. # The normal octahedron
  588. size2 = size * size
  589. size3 = size2 * size
  590. n1 = Vector((-1/4, -1/4, -1/4)) * size2
  591. g1 = -1/8 * size3
  592. n2 = Vector((-1/4, 1/4, -1/4)) * size2
  593. g2 = g1
  594. n3 = Vector((-1/4, -1/4, 1/4)) * size2
  595. g3 = g1
  596. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  597. g4 = g1
  598. n5 = Vector(( 1/4, -1/4, -1/4)) * size2
  599. g5 = g1
  600. n6 = Vector(( 1/4, 1/4, 1/4)) * size2
  601. g6 = g1
  602. n7 = Vector(( 1/4, 1/4, -1/4)) * size2
  603. g7 = g1
  604. n8 = Vector((-1/4, 1/4, 1/4)) * size2
  605. g8 = g1
  606. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  607. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  608. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  609. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  610. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  611. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  612. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  613. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  614. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  615. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  616. distance_plane_6 = abs((n6 @ atom_pos - g6)/n6.length)
  617. on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
  618. distance_plane_7 = abs((n7 @ atom_pos - g7)/n7.length)
  619. on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
  620. distance_plane_8 = abs((n8 @ atom_pos - g8)/n8.length)
  621. on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
  622. # Here are the 6 additional faces
  623. # pp = (size/2.0) - (sqrt(2.0)/2.0) * ((size/sqrt(2.0))/3.0)
  624. pp = size / 3.0
  625. n_1 = Vector((1.0,0.0,0.0))
  626. n_2 = Vector((-1.0,0.0,0.0))
  627. n_3 = Vector((0.0,1.0,0.0))
  628. n_4 = Vector((0.0,-1.0,0.0))
  629. n_5 = Vector((0.0,0.0,1.0))
  630. n_6 = Vector((0.0,0.0,-1.0))
  631. distance_plane_1b = abs((n_1 @ atom_pos + pp)/n_1.length)
  632. on_plane_1b = (atom_pos - n_1 * (distance_plane_1b/n_1.length)).length
  633. distance_plane_2b = abs((n_2 @ atom_pos + pp)/n_2.length)
  634. on_plane_2b = (atom_pos - n_2 * (distance_plane_2b/n_2.length)).length
  635. distance_plane_3b = abs((n_3 @ atom_pos + pp)/n_3.length)
  636. on_plane_3b = (atom_pos - n_3 * (distance_plane_3b/n_3.length)).length
  637. distance_plane_4b = abs((n_4 @ atom_pos + pp)/n_4.length)
  638. on_plane_4b = (atom_pos - n_4 * (distance_plane_4b/n_4.length)).length
  639. distance_plane_5b = abs((n_5 @ atom_pos + pp)/n_5.length)
  640. on_plane_5b = (atom_pos - n_5 * (distance_plane_5b/n_5.length)).length
  641. distance_plane_6b = abs((n_6 @ atom_pos + pp)/n_6.length)
  642. on_plane_6b = (atom_pos - n_6 * (distance_plane_6b/n_6.length)).length
  643. if(atom_pos.length > on_plane_1):
  644. regular = False
  645. if(atom_pos.length > on_plane_2):
  646. regular = False
  647. if(atom_pos.length > on_plane_3):
  648. regular = False
  649. if(atom_pos.length > on_plane_4):
  650. regular = False
  651. if(atom_pos.length > on_plane_5):
  652. regular = False
  653. if(atom_pos.length > on_plane_6):
  654. regular = False
  655. if(atom_pos.length > on_plane_7):
  656. regular = False
  657. if(atom_pos.length > on_plane_8):
  658. regular = False
  659. if(atom_pos.length > on_plane_1b):
  660. regular = False
  661. if(atom_pos.length > on_plane_2b):
  662. regular = False
  663. if(atom_pos.length > on_plane_3b):
  664. regular = False
  665. if(atom_pos.length > on_plane_4b):
  666. regular = False
  667. if(atom_pos.length > on_plane_5b):
  668. regular = False
  669. if(atom_pos.length > on_plane_6b):
  670. regular = False
  671. if skin == 1.0:
  672. return (regular, inner)
  673. size = size * (1.0 - skin)
  674. # The normal octahedron
  675. size2 = size * size
  676. size3 = size2 * size
  677. n1 = Vector((-1/4, -1/4, -1/4)) * size2
  678. g1 = -1/8 * size3
  679. n2 = Vector((-1/4, 1/4, -1/4)) * size2
  680. g2 = g1
  681. n3 = Vector((-1/4, -1/4, 1/4)) * size2
  682. g3 = g1
  683. n4 = Vector(( 1/4, -1/4, 1/4)) * size2
  684. g4 = g1
  685. n5 = Vector(( 1/4, -1/4, -1/4)) * size2
  686. g5 = g1
  687. n6 = Vector(( 1/4, 1/4, 1/4)) * size2
  688. g6 = g1
  689. n7 = Vector(( 1/4, 1/4, -1/4)) * size2
  690. g7 = g1
  691. n8 = Vector((-1/4, 1/4, 1/4)) * size2
  692. g8 = g1
  693. distance_plane_1 = abs((n1 @ atom_pos - g1)/n1.length)
  694. on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
  695. distance_plane_2 = abs((n2 @ atom_pos - g2)/n2.length)
  696. on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
  697. distance_plane_3 = abs((n3 @ atom_pos - g3)/n3.length)
  698. on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
  699. distance_plane_4 = abs((n4 @ atom_pos - g4)/n4.length)
  700. on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
  701. distance_plane_5 = abs((n5 @ atom_pos - g5)/n5.length)
  702. on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
  703. distance_plane_6 = abs((n6 @ atom_pos - g6)/n6.length)
  704. on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
  705. distance_plane_7 = abs((n7 @ atom_pos - g7)/n7.length)
  706. on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
  707. distance_plane_8 = abs((n8 @ atom_pos - g8)/n8.length)
  708. on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
  709. # Here are the 6 additional faces
  710. # pp = (size/2.0) - (sqrt(2.0)/2.0) * ((size/sqrt(2.0))/3.0)
  711. pp = size / 3.0
  712. n_1 = Vector((1.0,0.0,0.0))
  713. n_2 = Vector((-1.0,0.0,0.0))
  714. n_3 = Vector((0.0,1.0,0.0))
  715. n_4 = Vector((0.0,-1.0,0.0))
  716. n_5 = Vector((0.0,0.0,1.0))
  717. n_6 = Vector((0.0,0.0,-1.0))
  718. distance_plane_1b = abs((n_1 @ atom_pos + pp)/n_1.length)
  719. on_plane_1b = (atom_pos - n_1 * (distance_plane_1b/n_1.length)).length
  720. distance_plane_2b = abs((n_2 @ atom_pos + pp)/n_2.length)
  721. on_plane_2b = (atom_pos - n_2 * (distance_plane_2b/n_2.length)).length
  722. distance_plane_3b = abs((n_3 @ atom_pos + pp)/n_3.length)
  723. on_plane_3b = (atom_pos - n_3 * (distance_plane_3b/n_3.length)).length
  724. distance_plane_4b = abs((n_4 @ atom_pos + pp)/n_4.length)
  725. on_plane_4b = (atom_pos - n_4 * (distance_plane_4b/n_4.length)).length
  726. distance_plane_5b = abs((n_5 @ atom_pos + pp)/n_5.length)
  727. on_plane_5b = (atom_pos - n_5 * (distance_plane_5b/n_5.length)).length
  728. distance_plane_6b = abs((n_6 @ atom_pos + pp)/n_6.length)
  729. on_plane_6b = (atom_pos - n_6 * (distance_plane_6b/n_6.length)).length
  730. inner = False
  731. if(atom_pos.length > on_plane_1):
  732. inner = True
  733. if(atom_pos.length > on_plane_2):
  734. inner = True
  735. if(atom_pos.length > on_plane_3):
  736. inner = True
  737. if(atom_pos.length > on_plane_4):
  738. inner = True
  739. if(atom_pos.length > on_plane_5):
  740. inner = True
  741. if(atom_pos.length > on_plane_6):
  742. inner = True
  743. if(atom_pos.length > on_plane_7):
  744. inner = True
  745. if(atom_pos.length > on_plane_8):
  746. inner = True
  747. if(atom_pos.length > on_plane_1b):
  748. inner = True
  749. if(atom_pos.length > on_plane_2b):
  750. inner = True
  751. if(atom_pos.length > on_plane_3b):
  752. inner = True
  753. if(atom_pos.length > on_plane_4b):
  754. inner = True
  755. if(atom_pos.length > on_plane_5b):
  756. inner = True
  757. if(atom_pos.length > on_plane_6b):
  758. inner = True
  759. return (regular, inner)
  760. # -----------------------------------------------------------------------------
  761. # Routines for lattices
  762. def create_hexagonal_abcabc_lattice(ctype, size, skin, lattice):
  763. atom_number_total = 0
  764. atom_number_drawn = 0
  765. y_displ = 0
  766. z_displ = 0
  767. """
  768. e = (1/sqrt(2.0)) * lattice
  769. f = sqrt(3.0/4.0) * e
  770. df1 = (e/2.0) * tan((30.0/360.0)*2.0*pi)
  771. df2 = (e/2.0) / cos((30.0/360.0)*2.0*pi)
  772. g = sqrt(2.0/3.0) * e
  773. """
  774. e = 0.7071067810 * lattice
  775. f = 0.8660254038 * e
  776. df1 = 0.2886751348 * e
  777. df2 = 0.5773502690 * e
  778. g = 0.8164965810 * e
  779. if ctype == "parabolid_abc":
  780. # size = height, skin = diameter
  781. number_x = int(skin/(2*e))+4
  782. number_y = int(skin/(2*f))+4
  783. number_z = int(size/(2*g))
  784. else:
  785. number_x = int(size/(2*e))+4
  786. number_y = int(size/(2*f))+4
  787. number_z = int(size/(2*g))+1+4
  788. for k in range(-number_z,number_z+1):
  789. for j in range(-number_y,number_y+1):
  790. for i in range(-number_x,number_x+1):
  791. atom = Vector((float(i)*e,float(j)*f,float(k)*g))
  792. if y_displ == 1:
  793. if z_displ == 1:
  794. atom[0] += e/2.0
  795. else:
  796. atom[0] -= e/2.0
  797. if z_displ == 1:
  798. atom[0] -= e/2.0
  799. atom[1] += df1
  800. if z_displ == 2:
  801. atom[0] += 0.0
  802. atom[1] += df2
  803. if ctype == "sphere_hex_abc":
  804. message = vec_in_sphere(atom, size, skin)
  805. elif ctype == "pyramide_hex_abc":
  806. # size = height, skin = diameter
  807. message = vec_in_pyramide_hex_abc(atom, size, skin)
  808. elif ctype == "parabolid_abc":
  809. message = vec_in_parabole(atom, size, skin)
  810. if message[0] == True and message[1] == True:
  811. atom_add = CLASS_atom_cluster_atom(atom)
  812. ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
  813. atom_number_total += 1
  814. atom_number_drawn += 1
  815. if message[0] == True and message[1] == False:
  816. atom_number_total += 1
  817. if y_displ == 1:
  818. y_displ = 0
  819. else:
  820. y_displ = 1
  821. y_displ = 0
  822. if z_displ == 0:
  823. z_displ = 1
  824. elif z_displ == 1:
  825. z_displ = 2
  826. else:
  827. z_displ = 0
  828. print("Atom positions calculated")
  829. return (atom_number_total, atom_number_drawn)
  830. def create_hexagonal_abab_lattice(ctype, size, skin, lattice):
  831. atom_number_total = 0
  832. atom_number_drawn = 0
  833. y_displ = "even"
  834. z_displ = "even"
  835. """
  836. e = (1/sqrt(2.0)) * lattice
  837. f = sqrt(3.0/4.0) * e
  838. df = (e/2.0) * tan((30.0/360.0)*2*pi)
  839. g = sqrt(2.0/3.0) * e
  840. """
  841. e = 0.7071067814 * lattice
  842. f = 0.8660254038 * e
  843. df = 0.2886751348 * e
  844. g = 0.8164965810 * e
  845. if ctype == "parabolid_ab":
  846. # size = height, skin = diameter
  847. number_x = int(skin/(2*e))+4
  848. number_y = int(skin/(2*f))+4
  849. number_z = int(size/(2*g))
  850. else:
  851. number_x = int(size/(2*e))+4
  852. number_y = int(size/(2*f))+4
  853. number_z = int(size/(2*g))+1+4
  854. for k in range(-number_z,number_z+1):
  855. for j in range(-number_y,number_y+1):
  856. for i in range(-number_x,number_x+1):
  857. atom = Vector((float(i)*e,float(j)*f,float(k)*g))
  858. if "odd" in y_displ:
  859. if "odd" in z_displ:
  860. atom[0] += e/2.0
  861. else:
  862. atom[0] -= e/2.0
  863. if "odd" in z_displ:
  864. atom[0] -= e/2.0
  865. atom[1] += df
  866. if ctype == "sphere_hex_ab":
  867. message = vec_in_sphere(atom, size, skin)
  868. elif ctype == "parabolid_ab":
  869. # size = height, skin = diameter
  870. message = vec_in_parabole(atom, size, skin)
  871. if message[0] == True and message[1] == True:
  872. atom_add = CLASS_atom_cluster_atom(atom)
  873. ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
  874. atom_number_total += 1
  875. atom_number_drawn += 1
  876. if message[0] == True and message[1] == False:
  877. atom_number_total += 1
  878. if "even" in y_displ:
  879. y_displ = "odd"
  880. else:
  881. y_displ = "even"
  882. y_displ = "even"
  883. if "even" in z_displ:
  884. z_displ = "odd"
  885. else:
  886. z_displ = "even"
  887. print("Atom positions calculated")
  888. return (atom_number_total, atom_number_drawn)
  889. def create_square_lattice(ctype, size, skin, lattice):
  890. atom_number_total = 0
  891. atom_number_drawn = 0
  892. if ctype == "parabolid_square":
  893. # size = height, skin = diameter
  894. number_k = int(size/(2.0*lattice))
  895. number_j = int(skin/(2.0*lattice)) + 5
  896. number_i = int(skin/(2.0*lattice)) + 5
  897. else:
  898. number_k = int(size/(2.0*lattice))
  899. number_j = int(size/(2.0*lattice))
  900. number_i = int(size/(2.0*lattice))
  901. for k in range(-number_k,number_k+1):
  902. for j in range(-number_j,number_j+1):
  903. for i in range(-number_i,number_i+1):
  904. atom = Vector((float(i),float(j),float(k))) * lattice
  905. if ctype == "sphere_square":
  906. message = vec_in_sphere(atom, size, skin)
  907. elif ctype == "pyramide_square":
  908. message = vec_in_pyramide_square(atom, size, skin)
  909. elif ctype == "parabolid_square":
  910. # size = height, skin = diameter
  911. message = vec_in_parabole(atom, size, skin)
  912. elif ctype == "octahedron":
  913. message = vec_in_octahedron(atom, size, skin)
  914. elif ctype == "truncated_octahedron":
  915. message = vec_in_truncated_octahedron(atom,size, skin)
  916. if message[0] == True and message[1] == True:
  917. atom_add = CLASS_atom_cluster_atom(atom)
  918. ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
  919. atom_number_total += 1
  920. atom_number_drawn += 1
  921. if message[0] == True and message[1] == False:
  922. atom_number_total += 1
  923. print("Atom positions calculated")
  924. return (atom_number_total, atom_number_drawn)
  925. # -----------------------------------------------------------------------------
  926. # Routine for the icosahedron
  927. # Note that the icosahedron needs a special treatment since it requires a
  928. # non-common crystal lattice. The faces are (111) facets and the geometry
  929. # is five-fold. So far, a max size of 8217 atoms can be chosen.
  930. # More details about icosahedron shaped clusters can be found in:
  931. #
  932. # 1. C. Mottet, G. Tréglia, B. Legrand, Surface Science 383 (1997) L719-L727
  933. # 2. C. R. Henry, Surface Science Reports 31 (1998) 231-325
  934. # The following code is a translation from an existing Fortran code into Python.
  935. # The Fortran code has been created by Christine Mottet and translated by me
  936. # (Clemens Barth).
  937. # Although a couple of code lines are non-typical for Python, it is best to
  938. # leave the code as is.
  939. #
  940. # To do:
  941. #
  942. # 1. Unlimited cluster size
  943. # 2. Skin effect
  944. def create_icosahedron(size, lattice):
  945. natot = int(1 + (10*size*size+15*size+11)*size/3)
  946. x = list(range(natot+1))
  947. y = list(range(natot+1))
  948. z = list(range(natot+1))
  949. xs = list(range(12+1))
  950. ys = list(range(12+1))
  951. zs = list(range(12+1))
  952. xa = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
  953. ya = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
  954. za = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
  955. naret = [[ [] for i in range(12+1)] for j in range(12+1)]
  956. nfacet = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(12+1)]
  957. rac2 = sqrt(2.0)
  958. rac5 = sqrt(5.0)
  959. tdef = (rac5+1.0)/2.0
  960. rapp = sqrt(2.0*(1.0-tdef/(tdef*tdef+1.0)))
  961. nats = 2 * (5*size*size+1)
  962. nat = 13
  963. epsi = 0.01
  964. x[1] = 0.0
  965. y[1] = 0.0
  966. z[1] = 0.0
  967. for i in range(2, 5+1):
  968. z[i] = 0.0
  969. y[i+4] = 0.0
  970. x[i+8] = 0.0
  971. for i in range(2, 3+1):
  972. x[i] = tdef
  973. x[i+2] = -tdef
  974. x[i+4] = 1.0
  975. x[i+6] = -1.0
  976. y[i+8] = tdef
  977. y[i+10] = -tdef
  978. for i in range(2, 4+1, 2):
  979. y[i] = 1.0
  980. y[i+1] = -1.0
  981. z[i+4] = tdef
  982. z[i+5] = -tdef
  983. z[i+8] = 1.0
  984. z[i+9] = -1.0
  985. xdef = rac2 / sqrt(tdef * tdef + 1)
  986. for i in range(2, 13+1):
  987. x[i] = x[i] * xdef / 2.0
  988. y[i] = y[i] * xdef / 2.0
  989. z[i] = z[i] * xdef / 2.0
  990. if size > 1:
  991. for n in range (2, size+1):
  992. ifacet = 0
  993. iaret = 0
  994. inatf = 0
  995. for i in range(1, 12+1):
  996. for j in range(1, 12+1):
  997. naret[i][j] = 0
  998. for k in range (1, 12+1):
  999. nfacet[i][j][k] = 0
  1000. nl1 = 6
  1001. nl2 = 8
  1002. nl3 = 9
  1003. k1 = 0
  1004. k2 = 0
  1005. k3 = 0
  1006. k12 = 0
  1007. for i in range(1, 12+1):
  1008. nat += 1
  1009. xs[i] = n * x[i+1]
  1010. ys[i] = n * y[i+1]
  1011. zs[i] = n * z[i+1]
  1012. x[nat] = xs[i]
  1013. y[nat] = ys[i]
  1014. z[nat] = zs[i]
  1015. k1 += 1
  1016. for i in range(1, 12+1):
  1017. for j in range(2, 12+1):
  1018. if j <= i:
  1019. continue
  1020. xij = xs[j] - xs[i]
  1021. yij = ys[j] - ys[i]
  1022. zij = zs[j] - zs[i]
  1023. xij2 = xij * xij
  1024. yij2 = yij * yij
  1025. zij2 = zij * zij
  1026. dij2 = xij2 + yij2 + zij2
  1027. dssn = n * rapp / rac2
  1028. dssn2 = dssn * dssn
  1029. diffij = abs(dij2-dssn2)
  1030. if diffij >= epsi:
  1031. continue
  1032. for k in range(3, 12+1):
  1033. if k <= j:
  1034. continue
  1035. xjk = xs[k] - xs[j]
  1036. yjk = ys[k] - ys[j]
  1037. zjk = zs[k] - zs[j]
  1038. xjk2 = xjk * xjk
  1039. yjk2 = yjk * yjk
  1040. zjk2 = zjk * zjk
  1041. djk2 = xjk2 + yjk2 + zjk2
  1042. diffjk = abs(djk2-dssn2)
  1043. if diffjk >= epsi:
  1044. continue
  1045. xik = xs[k] - xs[i]
  1046. yik = ys[k] - ys[i]
  1047. zik = zs[k] - zs[i]
  1048. xik2 = xik * xik
  1049. yik2 = yik * yik
  1050. zik2 = zik * zik
  1051. dik2 = xik2 + yik2 + zik2
  1052. diffik = abs(dik2-dssn2)
  1053. if diffik >= epsi:
  1054. continue
  1055. if nfacet[i][j][k] != 0:
  1056. continue
  1057. ifacet += 1
  1058. nfacet[i][j][k] = ifacet
  1059. if naret[i][j] == 0:
  1060. iaret += 1
  1061. naret[i][j] = iaret
  1062. for l in range(1,n-1+1):
  1063. nat += 1
  1064. xa[i][j][l] = xs[i]+l*(xs[j]-xs[i]) / n
  1065. ya[i][j][l] = ys[i]+l*(ys[j]-ys[i]) / n
  1066. za[i][j][l] = zs[i]+l*(zs[j]-zs[i]) / n
  1067. x[nat] = xa[i][j][l]
  1068. y[nat] = ya[i][j][l]
  1069. z[nat] = za[i][j][l]
  1070. if naret[i][k] == 0:
  1071. iaret += 1
  1072. naret[i][k] = iaret
  1073. for l in range(1, n-1+1):
  1074. nat += 1
  1075. xa[i][k][l] = xs[i]+l*(xs[k]-xs[i]) / n
  1076. ya[i][k][l] = ys[i]+l*(ys[k]-ys[i]) / n
  1077. za[i][k][l] = zs[i]+l*(zs[k]-zs[i]) / n
  1078. x[nat] = xa[i][k][l]
  1079. y[nat] = ya[i][k][l]
  1080. z[nat] = za[i][k][l]
  1081. if naret[j][k] == 0:
  1082. iaret += 1
  1083. naret[j][k] = iaret
  1084. for l in range(1, n-1+1):
  1085. nat += 1
  1086. xa[j][k][l] = xs[j]+l*(xs[k]-xs[j]) / n
  1087. ya[j][k][l] = ys[j]+l*(ys[k]-ys[j]) / n
  1088. za[j][k][l] = zs[j]+l*(zs[k]-zs[j]) / n
  1089. x[nat] = xa[j][k][l]
  1090. y[nat] = ya[j][k][l]
  1091. z[nat] = za[j][k][l]
  1092. for l in range(2, n-1+1):
  1093. for ll in range(1, l-1+1):
  1094. xf = xa[i][j][l]+ll*(xa[i][k][l]-xa[i][j][l]) / l
  1095. yf = ya[i][j][l]+ll*(ya[i][k][l]-ya[i][j][l]) / l
  1096. zf = za[i][j][l]+ll*(za[i][k][l]-za[i][j][l]) / l
  1097. nat += 1
  1098. inatf += 1
  1099. x[nat] = xf
  1100. y[nat] = yf
  1101. z[nat] = zf
  1102. k3 += 1
  1103. atom_number_total = 0
  1104. atom_number_drawn = 0
  1105. for i in range (1,natot+1):
  1106. atom = Vector((x[i],y[i],z[i])) * lattice
  1107. atom_add = CLASS_atom_cluster_atom(atom)
  1108. ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
  1109. atom_number_total += 1
  1110. atom_number_drawn += 1
  1111. return (atom_number_total, atom_number_drawn)