crysna 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/CHANGES +24 -0
  4. data/Gemfile +26 -0
  5. data/Gemfile.lock +91 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +19 -0
  8. data/Rakefile +53 -0
  9. data/VERSION +1 -0
  10. data/bin/checkmodel +66 -0
  11. data/bin/collectcell +92 -0
  12. data/bin/fitframe +68 -0
  13. data/bin/occupiedpolyhedralsite +96 -0
  14. data/bin/occupiedscattersite +77 -0
  15. data/bin/site2poscar +66 -0
  16. data/bin/site2pov +30 -0
  17. data/bin/sitecombination +69 -0
  18. data/bin/sitemigration +80 -0
  19. data/bin/sitemigrationdistance +87 -0
  20. data/bin/siteoperation +109 -0
  21. data/bin/sitesingle +36 -0
  22. data/bin/siteuniq +32 -0
  23. data/bin/symidsite +65 -0
  24. data/bin/transitcell +46 -0
  25. data/crysna.gemspec +219 -0
  26. data/lib/crysna.rb +26 -0
  27. data/lib/crysna/atom.rb +97 -0
  28. data/lib/crysna/cell.rb +314 -0
  29. data/lib/crysna/frameatom.rb +13 -0
  30. data/lib/crysna/frameinterstitialcell.rb +309 -0
  31. data/lib/crysna/interstitialatom.rb +13 -0
  32. data/lib/crysna/modelstructure.rb +333 -0
  33. data/lib/crysna/optionmanager.rb +177 -0
  34. data/lib/crysna/site.rb +35 -0
  35. data/lib/crysna/siteconfiguration.rb +26 -0
  36. data/lib/crysna/sitenamelabeledcell.rb +220 -0
  37. data/lib/crysna/siteoperation.rb +56 -0
  38. data/lib/crysna/sitewithposition.rb +24 -0
  39. data/lib/crysna/transitionfinder.rb +448 -0
  40. data/lib/crysna/transitionfinder/cell.rb +144 -0
  41. data/lib/crysna/transitionfinder/cellmanager.rb +129 -0
  42. data/lib/crysna/transitionfinder/edge.rb +54 -0
  43. data/test/.gitignore +1 -0
  44. data/test/cell_orig/POSCAR +17 -0
  45. data/test/cell_orig/model.yaml +122 -0
  46. data/test/collectcells/.gitignore +2 -0
  47. data/test/collectcells/model.yaml +154 -0
  48. data/test/collectcells/nooutcar/minexpconfiguration.yaml +22 -0
  49. data/test/collectcells/normal-higher/OUTCAR +2406 -0
  50. data/test/collectcells/normal-higher/minexpconfiguration.yaml +22 -0
  51. data/test/collectcells/normal-lower/OUTCAR +2406 -0
  52. data/test/collectcells/normal-lower/minexpconfiguration.yaml +22 -0
  53. data/test/collectcells/normal/OUTCAR +2406 -0
  54. data/test/collectcells/normal/minexpconfiguration.yaml +22 -0
  55. data/test/collectcells/normalB/OUTCAR +2406 -0
  56. data/test/collectcells/normalB/minexpconfiguration.yaml +22 -0
  57. data/test/collectcells/unfinished/OUTCAR +40702 -0
  58. data/test/collectcells/unfinished/minexpconfiguration.yaml +22 -0
  59. data/test/collectcells/unidentified/OUTCAR +3541 -0
  60. data/test/collectcells/unidentified/minexpconfiguration.yaml +2 -0
  61. data/test/fitmodelstructure/.gitignore +1 -0
  62. data/test/fitmodelstructure/AgI/CONTCAR +17 -0
  63. data/test/fitmodelstructure/AgI/fitmodelstructure.log +1161 -0
  64. data/test/fitmodelstructure/AgI/model.yaml +45 -0
  65. data/test/fitmodelstructure/normal/CONTCAR +17 -0
  66. data/test/fitmodelstructure/normal/fitmodelstructure.log +5063 -0
  67. data/test/fitmodelstructure/normal/model.yaml +122 -0
  68. data/test/fitmodelstructure/unidentified/CONTCAR +44 -0
  69. data/test/fitmodelstructure/unidentified/fitmodelstructure.log +8833 -0
  70. data/test/fitmodelstructure/unidentified/model.yaml +154 -0
  71. data/test/helper.rb +17 -0
  72. data/test/identifypolyhedralsites/.gitignore +1 -0
  73. data/test/identifypolyhedralsites/identifyatomsites.log +333 -0
  74. data/test/identifypolyhedralsites/normal/fitmodelstructure.yaml +60 -0
  75. data/test/identifypolyhedralsites/normal/model.yaml +122 -0
  76. data/test/identifypolyhedralsites/unidentified/fitmodelstructure.yaml +2 -0
  77. data/test/identifypolyhedralsites/unidentified/model.yaml +154 -0
  78. data/test/identifypolyhedralsites/volumemismatch/fitmodelstructure.yaml +101 -0
  79. data/test/identifypolyhedralsites/volumemismatch/model.yaml +154 -0
  80. data/test/identifyscattersites/CONTCAR +17 -0
  81. data/test/identifyscattersites/POSCAR +12 -0
  82. data/test/identifyscattersites/fitmodelstructure.log +1 -0
  83. data/test/identifyscattersites/fitmodelstructure.yaml +0 -0
  84. data/test/identifyscattersites/identifyscattersites.yaml +5 -0
  85. data/test/identifyscattersites/model.yaml +45 -0
  86. data/test/minexpconfiguration/.gitignore +1 -0
  87. data/test/minexpconfiguration/collective/AgI/.gitignore +2 -0
  88. data/test/minexpconfiguration/collective/AgI/siteoperations.yaml +51265 -0
  89. data/test/minexpconfiguration/collective/AgI/sitesingle.yaml +15 -0
  90. data/test/minexpconfiguration/collective/AgI/test.sh +2 -0
  91. data/test/minexpconfiguration/normal/identifysites.yaml +22 -0
  92. data/test/minexpconfiguration/normal/minexpconfiguration.log +0 -0
  93. data/test/minexpconfiguration/normal/siteoperations.yaml +1793 -0
  94. data/test/minexpconfiguration/unidentified/identifysites.yaml +2 -0
  95. data/test/minexpconfiguration/unidentified/siteoperations.yaml +1793 -0
  96. data/test/sitecombination/initsites.yaml +7 -0
  97. data/test/sitecombination/initsites_test2.yaml +8 -0
  98. data/test/sitecombination/sitecombination.yaml +29 -0
  99. data/test/siteconfiguration/elements-sitenames.yaml +2 -0
  100. data/test/siteconfiguration/latticeaxes.yaml +3 -0
  101. data/test/siteconfiguration/sitenames-coordinates.yaml +4 -0
  102. data/test/sitemigrationsdistance/model.yaml +45 -0
  103. data/test/siteoperations/.gitignore +2 -0
  104. data/test/siteoperations/model.yaml +43 -0
  105. data/test/siteoperations/symmetryoperations.yaml +1441 -0
  106. data/test/sitesingle/.gitignore +1 -0
  107. data/test/sitesingle/sitecombination.yaml +29 -0
  108. data/test/siteuniq/minexpconfiguration.yaml +15 -0
  109. data/test/siteuniq/siteuniq.yaml +8 -0
  110. data/test/test_atom.rb +206 -0
  111. data/test/test_cell.rb +604 -0
  112. data/test/test_commands.rb +340 -0
  113. data/test/test_crystana.rb +7 -0
  114. data/test/test_frameatom.rb +22 -0
  115. data/test/test_frameinterstitialcell.rb +939 -0
  116. data/test/test_interstitialatom.rb +22 -0
  117. data/test/test_modelstructure.rb +807 -0
  118. data/test/test_optionmanager.rb +172 -0
  119. data/test/test_site.rb +40 -0
  120. data/test/test_siteconfiguration.rb +29 -0
  121. data/test/test_sitenamelabeledcell.rb +528 -0
  122. data/test/test_siteoperation.rb +79 -0
  123. data/test/test_sitewithposition.rb +20 -0
  124. data/test/test_transitionfinder.rb +432 -0
  125. data/test/transitcell/.gitignore +2 -0
  126. data/test/transitcell/collectcells.yaml +51 -0
  127. data/test/transitcell/sitemigrations.yaml +8 -0
  128. data/test/transitcell/siteoperations.yaml +17 -0
  129. data/test/transitcell/transitcell.log +1342 -0
  130. data/test/transitionfinder/collectcells.yaml +81 -0
  131. data/test/transitionfinder/sitemigrations.yaml +33 -0
  132. data/test/transitionfinder/siteoperations.yaml +16 -0
  133. data/test/transitionfinder/test_cell.rb +287 -0
  134. data/test/transitionfinder/test_cellmanager.rb +185 -0
  135. data/test/transitionfinder/test_edge.rb +49 -0
  136. data/test/uniquesitesgenerator/elements-sitenames.yaml +1 -0
  137. data/test/uniquesitesgenerator/siteoperations.yaml +9 -0
  138. metadata +406 -0
@@ -0,0 +1,177 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "optparse"
5
+
6
+ #
7
+ #
8
+ #
9
+ class Crysna::OptionManager
10
+
11
+ DEFAULT_CELLS_FILE = 'cells.yaml'
12
+ DEFAULT_FITTED_STRUCTURE_FILE = 'fittedstructure.yaml'
13
+ DEFAULT_OCCUPIED_SITES_FILE = 'occupiedsite.yaml'
14
+ DEFAULT_MODEL_FILE = 'model.yaml'
15
+ DEFAULT_SITE_CANDIDATE_FILE = 'sitecandidate.yaml'
16
+ DEFAULT_SITE_COMBINATION_FILE = 'sitecombination.yaml'
17
+ DEFAULT_SITE_MIGRATION_FILE = 'sitemigration.yaml'
18
+ DEFAULT_SITE_OPERATION_FILE = 'siteoperation.yaml'
19
+ DEFAULT_SITE_SINGLE_FILE = 'sitesingle.yaml'
20
+ DEFAULT_SYM_OPERATION_FILE = 'symoperation.yaml'
21
+ DEFAULT_SYM_ID_SITE_FILE = 'symidsite.yaml'
22
+ DEFAULT_SITE_UNIQUE_FILE = 'siteunique.yaml'
23
+
24
+ ALL_OPTIONS = [
25
+ :cells, :fitted, :occupied, :model, :symid,
26
+ :migration, :operation, :symmetry, :quiet,
27
+ :combination,
28
+ :candidate,
29
+ :single,
30
+ :unique,
31
+ ]
32
+
33
+
34
+ class INVARID_OPTION < Exception; end
35
+
36
+ attr_reader :options
37
+ attr_accessor :parser
38
+
39
+ # activates にセットしたものしか有効にしない。
40
+ def initialize(activates = ALL_OPTIONS)
41
+ @parser = OptionParser.new
42
+ @options = {}
43
+
44
+ activates.each do |option|
45
+ unless ALL_OPTIONS.include? option
46
+ raise INVARID_OPTION, option.to_s
47
+ end
48
+ end
49
+
50
+ activates.each do |opt|
51
+ case opt
52
+ when :cells ; set_cells
53
+ when :fitted ; set_fitted
54
+ when :occupied ; set_occupied
55
+ when :model ; set_model
56
+ when :symid ; set_symid
57
+ when :migration ; set_migration
58
+ when :operation ; set_operation
59
+ when :symmetry ; set_symmetry
60
+ when :single ; set_single
61
+ when :unique ; set_unique
62
+ when :quiet ; set_quiet
63
+ when :combination ; set_combination
64
+ when :candidate ; set_candidate
65
+ else
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ def set_cells
72
+ @options[:cells] = DEFAULT_CELLS_FILE
73
+ @parser.on("-c file",
74
+ "--cells=file",
75
+ "Indicate cells file. #{DEFAULT_CELLS_FILE} as default"
76
+ ){|str| @options[:cells] = str}
77
+ end
78
+
79
+ def set_fitted
80
+ @options[:fitted] = DEFAULT_FITTED_STRUCTURE_FILE
81
+ @parser.on("-f file",
82
+ "--fitted=file",
83
+ "Indicate fitted_structure file. #{DEFAULT_FITTED_STRUCTURE_FILE} as default"
84
+ ){|str| @options[:fitted] = str}
85
+ end
86
+
87
+ def set_occupied
88
+ @options[:occupied] = DEFAULT_OCCUPIED_SITES_FILE
89
+ @parser.on("-p file",
90
+ "--occupied=file",
91
+ "Indicate occupied_site file. Default: #{DEFAULT_OCCUPIED_SITES_FILE}"
92
+ ){|str| @options[:occupied] = str}
93
+ end
94
+
95
+ def set_model
96
+ @options[:model] = DEFAULT_MODEL_FILE
97
+ @parser.on("-m file",
98
+ "--model=file",
99
+ "Indicate model_structure file. Default: #{DEFAULT_MODEL_FILE}"
100
+ ){|str| @options[:model] = str}
101
+ end
102
+
103
+ def set_symid
104
+ @options[:symid] = DEFAULT_SYM_ID_SITE_FILE
105
+ @parser.on("-i file",
106
+ "--symmetric-id=file",
107
+ "Indicate symmetric_identification file. Default: #{DEFAULT_SYM_ID_SITE_FILE}"
108
+ ){|str| @options[:symid] = str}
109
+ end
110
+
111
+ def set_migration
112
+ @options[:migration] = DEFAULT_SITE_MIGRATION_FILE
113
+ @parser.on("-M file",
114
+ "--sitemigration=file",
115
+ "Indicate site_migration file. #{DEFAULT_SITE_MIGRATION_FILE} as default"
116
+ ){|str| @options[:migration] = str}
117
+ end
118
+
119
+ def set_operation
120
+ @options[:operation] = DEFAULT_SITE_OPERATION_FILE
121
+ @parser.on("-o file",
122
+ "--siteoperation=file",
123
+ "Indicate site_operation file. #{DEFAULT_SITE_OPERATION_FILE} as default"
124
+ ){|str| @options[:operation] = str}
125
+ end
126
+
127
+ def set_symmetry
128
+ @options[:symmetry] = DEFAULT_SYM_OPERATION_FILE
129
+ @parser.on("-y file",
130
+ "--symmetry=file",
131
+ "Indicate symmetry_operation file. #{DEFAULT_SYM_OPERATION_FILE} as default"
132
+ ){|str| @options[:symmetry] = str}
133
+ end
134
+
135
+ def set_single
136
+ @options[:single] = DEFAULT_SITE_SINGLE_FILE
137
+ @parser.on("-s file",
138
+ "--single=file",
139
+ "Indicate site_single file. #{DEFAULT_SITE_SINGLE_FILE} as default"
140
+ ){|str| @options[:single] = str}
141
+ end
142
+
143
+ def set_unique
144
+ @options[:unique] = DEFAULT_SITE_UNIQUE_FILE
145
+ @parser.on("-u file",
146
+ "--unique=file",
147
+ "Indicate site_unique file. #{DEFAULT_SITE_UNIQUE_FILE} as default"
148
+ ){|str| @options[:unique] = str}
149
+ end
150
+
151
+ def set_combination
152
+ @options[:combination] = DEFAULT_SITE_COMBINATION_FILE
153
+ @parser.on("-b file",
154
+ "--combination=file",
155
+ "Indicate site_combination file. #{DEFAULT_SITE_COMBINATION_FILE} as default"
156
+ ){|str| @options[:combination] = str}
157
+ end
158
+
159
+ def set_candidate
160
+ @options[:candidate] = DEFAULT_SITE_CANDIDATE_FILE
161
+ @parser.on("-d file",
162
+ "--candidate=file",
163
+ "Indicate site_candidate file. #{DEFAULT_SITE_CANDIDATE_FILE} as default"
164
+ ){|str| @options[:candidate] = str}
165
+ end
166
+
167
+ def set_quiet
168
+ @options[:quiet] = false
169
+ @parser.on("-q" , "--quite" , "Supress standard output."){
170
+ @options[:quiet] = true}
171
+ end
172
+
173
+ def parse!(ary)
174
+ @parser.parse!(ary)
175
+ end
176
+
177
+ end
@@ -0,0 +1,35 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #require "rubygems"
5
+ #require "mageo"
6
+
7
+ #
8
+ #
9
+ #
10
+ class Crysna::Site
11
+ attr_reader :name, :global_vector #, :polyhedron
12
+ attr_accessor :internal_vector
13
+
14
+ class NotSetInternalVectorError < Exception; end
15
+
16
+ #
17
+ def initialize(name, global_vector)
18
+ @name = name
19
+ @global_vector = global_vector.to_v3di
20
+ end
21
+
22
+ def equal?(other)
23
+ return false unless self.name == other.name
24
+ return false unless same_globla_vector?(other)
25
+ return true
26
+ end
27
+ alias :== :equal?
28
+
29
+ def same_globla_vector?(other)
30
+ return false unless self.global_vector == other.global_vector
31
+ return true
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,26 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #
5
+ # 座標情報を持たず、ラベル名でのみセルを表現するクラス
6
+ #
7
+ class Crysna::SiteConfiguration
8
+ attr_reader :elem_sites
9
+ #
10
+ def initialize(hash)
11
+ @elem_sites = hash
12
+ end
13
+
14
+ def self.generate_cell(elems, sites)
15
+ ##pp elems, sites
16
+ #cell = {}
17
+ #elems.each do |elem, num|
18
+ # site_elem = []
19
+ # num.times { site_elem << sites.shift}
20
+ # cell[elem] = site_elem
21
+ #end
22
+ #return cell
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,220 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #require "crystal/cell2.rb"
5
+ #require "crystal/periodiccell.rb"
6
+
7
+ # 原子に一意のサイト名がついていることを前提とする幾つかのメソッドのためのクラス。
8
+ # このクラスになってさえいれば、この前提はクリアしたものとして扱える。
9
+ # また、サイト名が unique に原子につけられることを new するときにチェックする。
10
+ #
11
+ # このクラスがなかったら、このプログラム用の雑多なメソッドを CrystalCell::PeriodicCell に
12
+ # 入れなければならなくなるので、名前空間の切り分け的な機能も期待。
13
+ #
14
+ # 通常の CrystalCell::Cell 系クラスとの大きな違いとして、
15
+ # モデル構造のサイト名と座標をハッシュとしてインスタンス変数に持つ。
16
+ #
17
+ # new されたときに最近接のサイトでサイト名を原子につけるが、
18
+ # その後操作を加えたら、
19
+ # つけられたサイト名がその時点で最近接であることは保証されない。
20
+ # このクラスはあまり汎用性を考えない。
21
+ # 厳密な定義とか、他の CrystalCell::Cell系クラスとの整合性よりも
22
+ # 早いプログラミングを目的とする。
23
+ class SiteNameLabeledCell < CrystalCell::Cell
24
+ TOLERANCE = 1.0E-5
25
+
26
+ class InitializeError < Exception; end
27
+ class TypeError < Exception; end
28
+ class RangeError < Exception; end
29
+ class OutOfCellError < Exception; end
30
+
31
+ undef add_atom
32
+
33
+ # sites はサイト名を鍵、内部座標を値とするハッシュ。
34
+ # 内部座標は Mageo::Vector3DInternal クラスインスタンスであることを前提とする。
35
+ #
36
+ # サイト名の数(sites.size)と保持している原子の数が違えば例外。
37
+ #
38
+ # 一対一対応しなければ例外。
39
+ # 例外は比較的頻繁に生じるだろうから、
40
+ # 外部で例外をキャッチする必要があることに注意。
41
+ def initialize(axes, atoms, sites)
42
+
43
+ unless atoms.size == sites.size
44
+ raise InitializeError,
45
+ "atoms.size is #{atoms.size}, while sites.size is #{sites.size}"
46
+ end
47
+ #super(axes)
48
+ @axes = axes
49
+ @sites = sites
50
+
51
+ self.class.check_inside_all_sites(@sites)
52
+
53
+ atoms = self.class.label_sitenames(axes, atoms, sites)
54
+ unless self.class.labeled_all_atoms?(atoms, sites)
55
+ raise InitializeError,
56
+ "Not labeled site names for every atom."
57
+ end
58
+
59
+ @atoms = self.class.periodically_translate_atoms_to_nearest_site(axes, atoms, sites)
60
+ unless self.class.unique_sitenames?(@atoms)
61
+ raise InitializeError,
62
+ "Not unique site names for atoms."
63
+ end
64
+ end
65
+
66
+ # 各原子に付いているサイト名を見て、
67
+ # そのサイト座標と原子座標の空間的な距離の二乗を全ての原子について和を取り、
68
+ # その値を返す。
69
+ def sum_square_distances
70
+ @atoms.inject(0.0) do |result, atom|
71
+ result += (self.to_pcell.nearest_distance(@sites[atom.name] , atom.position))**2
72
+ end
73
+ end
74
+
75
+ # CrystalCell::Cell クラスインスタンスに変換したものを返す。
76
+ # 原子の座標はそのまま変換しない。
77
+ def to_cell
78
+ result = CrystalCell::Cell.new(@axes)
79
+ result.comment = self.comment
80
+ @atoms.each do |atom|
81
+ result.add_atom(atom)
82
+ end
83
+ return result
84
+ end
85
+
86
+ # 原子座標の相加平均を内部座標で返す。
87
+ def center_of_atoms
88
+ sum = Mageo::Vector3DInternal[0.0, 0.0, 0.0]
89
+ @atoms.each do |atom|
90
+ sum += atom.position
91
+ end
92
+ sum = sum * (1.0/(@sites.size.to_f))
93
+ end
94
+
95
+ # モデルサイト座標の相加平均を内部座標で返す。
96
+ def center_of_sites
97
+ sum = Mageo::Vector3DInternal[0.0, 0.0, 0.0]
98
+ @sites.each do |sitename, vec|
99
+ sum += vec
100
+ end
101
+ sum = sum * (1.0/(@sites.size.to_f))
102
+ end
103
+
104
+ # サイト名を鍵、その原子の内部座標を値とするハッシュ を返す。
105
+ def sitenames_positions
106
+ results = {}
107
+ @atoms.each do |i|
108
+ results[i.name] = i.position
109
+ end
110
+ return results
111
+ end
112
+
113
+ # サイト名を鍵、その原子の元素を値とするハッシュ を返す。
114
+ def sitenames_elements
115
+ results = {}
116
+ @atoms.each do |i|
117
+ results[i.name] = i.element
118
+ end
119
+ return results
120
+ end
121
+
122
+ private
123
+
124
+ # 与えられた原子のリストのそれぞれの原子について、
125
+ # 周期境界条件的に最も近いサイトを判定し
126
+ # 原子にサイト名をつけるた原子に map した配列を返す。
127
+ def self.label_sitenames(axes, atoms, sites)
128
+ atoms.each do |atom|
129
+ name = SiteNameLabeledCell.nearest_site(axes, atom.position, sites)
130
+ atom.name = name
131
+ end
132
+ return atoms
133
+ end
134
+
135
+ # 与えられた原子のリストのそれぞれの原子につけられたサイト名から、
136
+ # サイトの座標に最も近くなるように周期的並進移動した原子に map した配列を返す。
137
+ # 原子の内部座標は 0〜1 の間になるとは限らない。
138
+ def self.periodically_translate_atoms_to_nearest_site(axes, atoms, sites)
139
+ cell = CrystalCell::PeriodicCell.new(axes, atoms)
140
+ atoms = cell.atoms
141
+ atoms.map! do |atom|
142
+ translation = cell.nearest_direction(atom.position, sites[atom.name])
143
+ atom.translate(translation * (-1.0))
144
+ end
145
+ return atoms
146
+ end
147
+
148
+ # 引数で与えられた 格子の軸、サイト名ハッシュに対して、
149
+ # 与えられた内部座標 に最も近いサイト名の文字列を返す。
150
+ def self.nearest_site(axes, internal_coord, sites)
151
+ pc = CrystalCell::PeriodicCell.new(axes)
152
+ results = sites.min_by do |key, val|
153
+ pc.nearest_distance(val, internal_coord)
154
+ end
155
+ return results[0]
156
+ end
157
+ #private_class_method :nearest_site
158
+
159
+ # 原子についているサイト名が uniq なら true
160
+ def self.unique_sitenames?(atoms)
161
+ sitenames = atoms.map{|atom| atom.name}
162
+ return false if sitenames.include?(nil)
163
+ return sitenames.uniq.size == atoms.size
164
+ end
165
+ #private_class_method :unique_sitenames?
166
+
167
+ # 各サイトについて内部座標が 0以上1未満でなければ
168
+ # 例外 SiteNameLabeledCell::OutOfCellError を生じる。
169
+ def self.check_inside_all_sites(sites)
170
+ sites.each do |name, vec|
171
+ vec.to_a.each do |val|
172
+ if (val < 0.0-TOLERANCE) || (1.0+TOLERANCE <= val)
173
+ raise OutOfCellError, "#{name}, #{vec.inspect}"
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ def self.labeled_all_atoms?(atoms, sites)
180
+ atoms.each do |atom|
181
+ return false unless sites.keys.include?(atom.name)
182
+ end
183
+ return true
184
+ end
185
+
186
+ # 引数で与えられたサイト名に対して最も近い原子の @atoms 内の index を返す。
187
+ # サイト名 site_name は文字列であることを前提とする。
188
+ def nearest_atom_index(site_name)
189
+ raise SiteNameLabeledCell::TypeError if site_name.class != String
190
+ min_d = self.to_pcell.nearest_distance(@sites[site_name], @atoms[0].position)
191
+ min_id = 0
192
+ @atoms.size.times do |i|
193
+ tmp = self.to_pcell.nearest_distance(@sites[site_name], @atoms[i].position)
194
+ if tmp < min_d
195
+ min_d = tmp
196
+ min_id = i
197
+ end
198
+ end
199
+ return min_id
200
+ end
201
+
202
+ #def site_name(pos)
203
+ # raise SiteNameLabeledCellTypeError if pos.class == Mageo::Vector3D
204
+ # k
205
+ #end
206
+
207
+ end
208
+
209
+ class CrystalCell::Cell
210
+ # CrystalCell::Cell クラスインスタンスを SiteNameLabeledCell クラスインスタンスに
211
+ # 変換したものを返す。
212
+ # 細かい挙動は SiteNameLabeledCell.initialize を参照のこと。
213
+ # sites には サイト名を鍵、内部座標を値としたハッシュを渡す。
214
+ def to_snlcell(sites)
215
+ result = SiteNameLabeledCell.new(@axes, @atoms, sites)
216
+ result.comment = self.comment
217
+ return result
218
+ end
219
+ end
220
+