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,56 @@
1
+ ##! /usr/bin/env ruby
2
+ ## coding: utf-8
3
+ #
4
+ ##require "mathextension/vector3dinternal.rb"
5
+ ##require "crystal/cell2.rb"
6
+ ##require "crysna/sitenamelabeledcell.rb"
7
+ #
8
+ ##
9
+ ##
10
+ ##
11
+ #module Crysna::SiteOperation
12
+ # ##
13
+ # #def initialize(sites, operations)
14
+ # # @sites = sites
15
+ # # @operations = operations
16
+ # #end
17
+ #
18
+ # # Return site operations.
19
+ # #
20
+ # # MEMO: assuming cubic cell.
21
+ # def self.site_operation(sites, operations)
22
+ # #pp sites.map {|name, pos| CrystalCell::Atom.new(0, Mageo::Vector3DInternal[*pos])}
23
+ # #pp sites.map {|name, pos| Mageo::Vector3DInternal[*pos]}
24
+ # new_sites = {}
25
+ # sites.each do |name, pos|
26
+ # new_sites[name] = Mageo::Vector3DInternal[*pos]
27
+ # end
28
+ # sites = new_sites
29
+ #
30
+ # axes = CrystalCell::LatticeAxes.new([ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ])
31
+ #
32
+ # snlcell = SiteNameLabeledCell.new(
33
+ # axes,
34
+ # sites.map {|name, pos| CrystalCell::Atom.new(0, Mageo::Vector3DInternal[*pos])},
35
+ # sites
36
+ # )
37
+ #
38
+ # cell = CrystalCell::Cell.new(
39
+ # axes,
40
+ # sites.map { |name, pos| CrystalCell::Atom.new(0, pos, name) }
41
+ # )
42
+ #
43
+ # results = []
44
+ # operations.each do |operation|
45
+ # rotation = operation["rotation"]
46
+ # translation = operation["translation"]
47
+ # site_changes = {}
48
+ # cell.operate(rotation, translation).atoms.each do |atom|
49
+ # site_changes[atom.name] =
50
+ # SiteNameLabeledCell.nearest_site(axes, atom.position, sites)
51
+ # end
52
+ # results << site_changes
53
+ # end
54
+ # return results
55
+ # end
56
+ #end
@@ -0,0 +1,24 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #require "rubygems"
5
+ #require "mageo"
6
+
7
+ #
8
+ #
9
+ #
10
+ class Crysna::SiteWithPosition < Crysna::Site
11
+ def initialize(name, global_vector, internal_vector) #, polyhedron = nil)
12
+ @internal_vector = internal_vector.to_v3di if internal_vector
13
+ super(name, global_vector)
14
+ end
15
+
16
+ #Return coordinates as a sum of global and internal vectors.
17
+ def coordinates
18
+ #unless @internal_vector
19
+ # raise NotSetInternalVectorError, "@internal_vector is not set."
20
+ #end
21
+ @global_vector + @internal_vector
22
+ end
23
+
24
+ end
@@ -0,0 +1,448 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #gem "ruby-graphviz"
5
+ require 'ruby-graphviz'
6
+
7
+ #class Hash
8
+ # def find_key(value)
9
+ # self.each do |key, val|
10
+ # return key if val == value
11
+ # end
12
+ # return nil
13
+ # end
14
+ #end
15
+
16
+ #
17
+ #
18
+ #
19
+ class Crysna::TransitionFinder
20
+ def initialize(cells, site_migrations, site_operations)
21
+ @site_migrations = site_migrations
22
+ @site_operations = site_operations
23
+ @cell_candidates = cells.map do |cell|
24
+ new_cell = cell.minimize(@site_operations)
25
+ new_cell.name = cell.name
26
+ new_cell
27
+ end
28
+ @edges = []
29
+ @cell_manager = Crysna::TransitionFinder::CellManager.new
30
+
31
+ #@graph = GraphViz.new( "Transition",
32
+ # :type => "graph",
33
+ # :use => "dot"
34
+ # )
35
+ #@nodes = {}
36
+ #@edges = []
37
+ end
38
+
39
+ #Start finding and retrun path.
40
+ #'start' is the name of the starting cell.
41
+ #'truncate_energy' is end condition of cell enegy.
42
+ #If truncate_energy == false, 'finding one MEP mode' is selected.
43
+ #The returned array of cell transitions.
44
+ #When 'finding one MEP mode', return an array of one item.
45
+ #Return nil if the transition path cannot be found.
46
+ #NOTE: specification may be changed in future.
47
+ def find_path(start, truncate_energy, result_io, dot_io)
48
+ pair = meet_transit_cells(start, truncate_energy)
49
+ if pair
50
+ ## Show
51
+ result_io.puts "-"*60
52
+ result_io.puts "One direction"
53
+ write_path(@cell_manager.ascend(pair[0]), result_io)
54
+
55
+ result_io.puts "-"*60
56
+ result_io.puts "The other direction"
57
+ write_path(@cell_manager.ascend(pair[1]), result_io)
58
+
59
+ #@graph.output(dot_io)
60
+ #dot_io.puts @graph.output( :none => String )
61
+
62
+ write_dot(pair, dot_io)
63
+ else
64
+ result_io.puts "Cannot find path."
65
+ cell_transition = nil
66
+ end
67
+ #return cell_transition
68
+ end
69
+
70
+ private
71
+
72
+ def write_dot(goal_pair, dot_io)
73
+ min_path_edges0 = two_indices(@cell_manager.ascend(goal_pair[0]).reverse)
74
+ min_path_edges1 = two_indices(@cell_manager.ascend(goal_pair[1]).reverse)
75
+ min_path_edges0 = each_sort(min_path_edges0)
76
+ min_path_edges1 = each_sort(min_path_edges1)
77
+
78
+ dot_io.puts "graph Transition {"
79
+ ##nodes
80
+ @cell_manager.cells.each_with_index do |cell, index|
81
+ conf = cell.configuration_string_full
82
+ node_id_str = sprintf("%3d", index)
83
+ str = " #{node_id_str} [label = \"#{node_id_str}\\n#{conf}\\n#{cell.energy}\"];"
84
+ dot_io.puts str
85
+ end
86
+
87
+ dot_io.puts
88
+
89
+ ##normal edges
90
+ @edges.each do |edge|
91
+ index0 = edge.nodes[0]
92
+ index1 = edge.nodes[1]
93
+
94
+ indices_for_test = [index0, index1].sort
95
+ #str = " #{index0} -- #{index1} "
96
+ str = sprintf(" %3d -- %3d ", index0, index1)
97
+ if min_path_edges0.include?(indices_for_test)
98
+ str += "[label = \"#{edge.note.chomp}\", penwidth = 3, color = red];"
99
+ elsif min_path_edges1.include?(indices_for_test)
100
+ str += "[label = \"#{edge.note.chomp}\", penwidth = 3, color = green];"
101
+ else
102
+ str += "[label = \"#{edge.note.chomp}\"];"
103
+ end
104
+ dot_io.puts str
105
+ end
106
+
107
+ ##connect goal_pair
108
+ str = " #{goal_pair[0]} -- #{goal_pair[1]} [label = \"Semi-identical\", penwidth = 3, color = blue, style = dotted];"
109
+ dot_io.puts str
110
+
111
+ ##close
112
+ dot_io.puts "}"
113
+
114
+ end
115
+
116
+ #Generate and return an array of edges
117
+ #which connect between reached and not reached cells.
118
+ def reach_unreach_edges
119
+ results = []
120
+ @edges.each do |edge|
121
+ if @cell_manager[edge.nodes[0]].reach? ^ @cell_manager[edge.nodes[1]].reach?
122
+ results << edge
123
+ end
124
+ end
125
+ return results
126
+ end
127
+
128
+ #Return index of the cell which is periodically equal to the cell
129
+ #in @cell_candidates
130
+ #Not minimize(symid)-expressed cell is minimized to be found.
131
+ #Rerurn nil if no periodically equal cell is included.
132
+ def find_periodically_candidate(cell)
133
+ cell = cell.minimize(@site_operations)
134
+ result = nil
135
+ @cell_candidates.each_with_index do |ref_cell, index|
136
+ if cell.periodically_equal? ref_cell
137
+ result = index
138
+ break
139
+ end
140
+ end
141
+ return result
142
+ end
143
+
144
+ #Retrun [from, to] nodes.
145
+ #If the nodes of 'edge' is both reached or both not_reached, raise RuntimeError.
146
+ def from_to_node_indices(edge)
147
+ flag0 = @cell_manager[edge.nodes[0]].reach?
148
+ flag1 = @cell_manager[edge.nodes[1]].reach?
149
+ if flag0 == true && flag1 == false
150
+ results = [edge.nodes[0], edge.nodes[1]]
151
+ elsif flag0 == false && flag1 == true
152
+ results = [edge.nodes[1], edge.nodes[0]]
153
+ else
154
+ raise RuntimeError, "Must not happen."
155
+ end
156
+ return results
157
+ end
158
+
159
+ # Argument 'cell_id' indicates an index of a base cell in @cell_manager.
160
+ # New nodes from the base cell are added into @cell_manager.
161
+ # New edges between the base cell and new cells are added into @edges.
162
+ # New nodes:
163
+ # They are found from the base cell via a single migration.
164
+ # Energy of new cell is set to be the same vale of symmetric identical cell
165
+ # in @cell_candidates.
166
+ # If it is not found in @cell_candidates, set to be Float::INFINITY
167
+ #
168
+ # Each edge has 'note' of the infomation of migration and operation;
169
+ # migration element, source site, destination site,
170
+ # symmetry operation to minimum_expression.
171
+ # 'reach_flag's of new cells are set to be false,
172
+ # 'from_edges' to be empty, energy to be set nil.
173
+ # NOTE: edge weight should be as in edge list.
174
+ def expand_edges(cell_id)
175
+ $log_io.puts "-" * 30
176
+ $log_io.puts "#{self.class}.expand_edges with cell_id of #{cell_id}"
177
+
178
+ cell = @cell_manager[cell_id]
179
+ $log_io.puts "[cell_id = #{cell_id}]"
180
+ $log_io.puts " #{cell.configuration_string_full}, energy=#{cell.energy}, reach_flag=#{cell.reach_flag.to_s}, name=\"#{cell.name}\""
181
+
182
+ $log_io.puts '-' * 60
183
+ $log_io.puts 'Loop to find lowest edge: start'
184
+ cell.atoms.each_with_index do |atom, atom_id|
185
+ $log_io.puts '-' * 30
186
+ $log_io.puts "Migrating atom: index=#{atom_id}, element=#{atom.element}, site=#{atom.sitename}"
187
+ @site_migrations[atom.site.name].each do |site, global_vector|
188
+ $log_io.puts "-" * 10
189
+ $log_io.puts "To site=#{site}, global_vector=#{global_vector}"
190
+ new_cell = cell.migrate(atom_id, site, global_vector)
191
+ $log_io.puts " Generated cell: #{new_cell.configuration_string}(#{new_cell.configuration_string_full})"
192
+
193
+ min_ope = minimum_operation(new_cell)
194
+ $log_io.puts " minimum_operation id: #{min_ope}"
195
+
196
+ identical_cell = new_cell.operate(@site_operations[min_ope]["operation"])
197
+ $log_io.puts " Symmetrically identical cell: #{identical_cell.configuration_string}(#{identical_cell.configuration_string_full})"
198
+
199
+ ##Check including @cell_manager
200
+ id = @cell_manager.index_same_atoms(new_cell)
201
+ if id
202
+ $log_io.puts "This cell is contained in @cell_manager."
203
+ $log_io.puts "Truncated."
204
+ next
205
+ else
206
+ $log_io.puts "This cell is not included in @cell_manager."
207
+ end
208
+
209
+ ##Check including @cell_candidates
210
+ id = find_periodically_candidate(identical_cell)
211
+ if id
212
+ $log_io.puts "This cell is contained in @cell_candidates."
213
+ energy = @cell_candidates[id].energy
214
+ else
215
+ $log_io.puts "This cell is not included in @cell_candidates."
216
+ energy = Float::INFINITY
217
+ end
218
+
219
+ ##
220
+ new_cell.name = new_cell.occupied_sitename
221
+ new_cell.energy = energy
222
+
223
+ new_cell_id = @cell_manager.add(new_cell)
224
+ $log_io.puts "The cell is added into @cell_manager as index of #{new_cell_id}"
225
+
226
+ energy = [@cell_manager[cell_id].energy, new_cell.energy].max
227
+ note =
228
+ "|[migration] elem=#{atom.element}" +
229
+ ", #{atom.sitename}"+
230
+ " -> #{site}#{global_vector.to_a}\n" # +
231
+
232
+ new_edge = Crysna::TransitionFinder::Edge.new(
233
+ [cell_id, new_cell_id],
234
+ energy,
235
+ note
236
+ )
237
+ $log_io.puts "New edge: cell_ids of (#{cell_id} -- #{new_cell_id}), energy=#{energy}"
238
+ @edges.push(new_edge)
239
+
240
+ conf_full = new_cell.configuration_string_full
241
+ #@nodes[conf_full] = @graph.add_nodes(conf_full, :label => conf_full)
242
+ #pp @nodes
243
+ #pp cell.configuration_string_full
244
+ #pp new_cell.configuration_string_full
245
+ #puts
246
+ #puts
247
+ #pp @nodes[cell.configuration_string_full]
248
+ #pp @nodes[new_cell.configuration_string_full]
249
+ #@graph.add_edges(@nodes[cell.configuration_string_full],
250
+ # @nodes[new_cell.configuration_string_full]
251
+ # )
252
+ end
253
+ end
254
+ $log_io.puts 'Finding lowest edge loop end'
255
+ $log_io.puts '-'*60
256
+ end
257
+
258
+ ##Return an index in @site_operations to minimuze expresion.
259
+ def minimum_operation(cell)
260
+ min_ope = @site_operations[0]["operation"]
261
+ min_id = @site_operations[0]["operation_id"]
262
+
263
+ $log_io.puts " in minimum_operation:"
264
+
265
+ @site_operations.each do |site_ope|
266
+ id = site_ope["operation_id"]
267
+ ope = site_ope["operation"]
268
+ $log_io.puts '-'*30
269
+ $log_io.puts " site_ope id: #{id}"
270
+
271
+ min = cell.operate(min_ope)
272
+ cur = cell.operate(ope)
273
+ write_log_cell(cur)
274
+ if cur < min
275
+ min_id = id
276
+ min_ope = ope
277
+ $log_io.puts " min_exp is updated."
278
+ end
279
+ end
280
+ $log_io.puts '-'*30
281
+ return min_id
282
+ end
283
+
284
+ def write_log_state
285
+ $log_io.puts "state" + "-" * 30
286
+ $log_io.puts "cells in cellmanager:"
287
+ @cell_manager.cells.size.times do |i|
288
+ $log_io.puts " [#{i}]"
289
+ cell = @cell_manager[i]
290
+ $log_io.puts " name: #{cell.name}"
291
+ write_log_cell(cell)
292
+ $log_io.puts " energy: #{cell.energy}"
293
+ $log_io.puts
294
+ end
295
+
296
+ end
297
+
298
+ def write_log_cell(cell)
299
+ $log_io.puts " atoms of cell:"
300
+ cell.atoms.each do |atom|
301
+ $log_io.puts " - #{atom.site.name} #{atom.site.global_vector}"
302
+ end
303
+ end
304
+
305
+ def meet_transit_cells(start, truncate_energy)
306
+ $log_io.puts "#{self.class}.find_path"
307
+ cur_cell = @cell_candidates.find{|tmp| tmp.name == start}
308
+ start_index = cur_index = @cell_manager.add(cur_cell)
309
+ @cell_manager.reach(cur_index, nil)
310
+
311
+ conf = cur_cell.configuration_string
312
+ conf_full = cur_cell.configuration_string_full
313
+ $log_io.puts "Starting point: #{start}"
314
+ $log_io.puts "#{conf}(#{conf_full}) is added as cur_index of #{cur_index}"
315
+ #@nodes[conf_full] = @graph.add_nodes( conf_full,
316
+ # #:shape => "circle",
317
+ # #:penwidth => 2,
318
+ # #:fontsize => 12,
319
+ # #:style => :filled,
320
+ # #:fillcolor => "orange",
321
+ # :label => conf_full
322
+ #)
323
+ write_log_state
324
+ expand_edges(cur_index)
325
+
326
+ iteration = 0
327
+ while true
328
+ iteration += 1
329
+ $log_io.puts "-" * 10 + "Iteration #{iteration}" + "-" * 40
330
+
331
+ write_log_state
332
+ $log_io.puts "-" * 60
333
+
334
+ $log_io.puts "reach_unreach_edges: "
335
+ reach_unreach_edges.each do |edge|
336
+ #$log_io.puts edge.inspect
337
+ $log_io.puts " #{edge.nodes.to_s}"
338
+ end
339
+
340
+ $log_io.puts "cur_index:" + cur_index.to_s
341
+
342
+ cur_cell = @cell_manager[cur_index]
343
+ $log_io.puts "[#{cur_index}] #{cur_cell.configuration_string_full}, energy=#{cur_cell.energy}, reach_flag=#{cur_cell.reach_flag.to_s}, name=\"#{cur_cell.name}\""
344
+ if truncate_energy
345
+ if @cell_manager.max{|cell| cell.energy} > truncate_energy
346
+ break
347
+ end
348
+ else
349
+ if @cell_manager.contain_periodically_shift_cells?
350
+ $log_io.puts "truncate condition reached by contain_periodically_shift_cells."
351
+ $log_io.puts @cell_manager.periodically_shift_indices.to_s
352
+ break
353
+ end
354
+ end
355
+
356
+ ##Choose the lowest edge
357
+ $log_io.puts "-" * 30
358
+ $log_io.puts "reach_unreach_edges"
359
+ reach_unreach_edges.each do |edge|
360
+ $log_io.puts "-" * 10
361
+ $log_io.puts edge.note
362
+ $log_io.puts "energy=#{edge.weight}"
363
+ end
364
+
365
+ new_edge = reach_unreach_edges.min_by {|edge| edge.weight}
366
+ $log_io.puts "-" * 20
367
+ if new_edge
368
+ $log_io.puts "Chosen edge: #{new_edge.note}"
369
+ $log_io.puts "energy=#{new_edge.weight}"
370
+ else
371
+ $log_io.puts "Chosen edge: nil"
372
+ $log_io.puts "break finding loop."
373
+ break
374
+ end
375
+
376
+ ##Show cells state
377
+ $log_io.puts "-" * 30
378
+ $log_io.puts "Cells state"
379
+ from_index, to_index = from_to_node_indices(new_edge)
380
+ @cell_manager.reach(to_index, new_edge)
381
+ cur_index = to_index
382
+
383
+ @cell_manager.cells.each_with_index do |cell, index|
384
+ $log_io.puts "-" * 20
385
+ $log_io.puts "[#{index}] #{cell.configuration_string_full}, energy=#{cell.energy}, reach_flag=#{cell.reach_flag.to_s}, name=\"#{cell.name}\""
386
+ #$log_io.puts "-" * 10
387
+ $log_io.puts "Number of from_edges: #{cell.from_edges.size}"
388
+ cell.from_edges.each do |edge|
389
+ $log_io.puts "-" * 10
390
+ if edge
391
+ $log_io.puts "Nodes: #{edge.nodes}"
392
+ $log_io.puts edge.note
393
+ else
394
+ $log_io.puts "Nil edge(Starting point)"
395
+ next
396
+ end
397
+ end
398
+ end
399
+ $log_io.puts "-" * 30
400
+ $log_io.puts "cur_index is set to be #{cur_index}"
401
+
402
+ expand_edges(to_index)
403
+ $log_io.puts "-" * 60
404
+ $log_io.puts "find_path loop: next"
405
+ $log_io.puts "-" * 60
406
+ $log_io.puts
407
+ end
408
+
409
+ result = @cell_manager.periodically_shift_indices.find {|i| i.size > 1}
410
+ result
411
+ end
412
+
413
+ def write_path(cell_ids, result_io)
414
+ cell_ids.reverse.each do |index|
415
+ cell = @cell_manager[index]
416
+ edge = cell.from_edges[0]
417
+ if edge
418
+ result_io.puts "|"
419
+ result_io.puts "#{edge.note}"
420
+ result_io.puts "|"
421
+ else
422
+ end
423
+
424
+ result_io.puts "[cell]"
425
+ result_io.puts " atoms: #{cell.configuration_string_full}"
426
+
427
+ min_ope = minimum_operation(cell)
428
+ symid_cell = cell.operate(@site_operations[min_ope]["operation"])
429
+ result_io.puts " symmetrically identical cell: #{symid_cell.configuration_string}" +
430
+ "(operation_id=#{min_ope})"
431
+ result_io.puts " energy: #{cell.energy}"
432
+ end
433
+ end
434
+
435
+ def two_indices(ary)
436
+ results = []
437
+ ((ary.size) -1 ).times do |i|
438
+ results << [ary[i], ary[i+1]]
439
+ end
440
+ results
441
+ end
442
+
443
+ def each_sort(arys)
444
+ arys.map {|ary| ary.sort}
445
+ end
446
+
447
+ end
448
+