crysna 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+