crysna 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/CHANGES +24 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +91 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/checkmodel +66 -0
- data/bin/collectcell +92 -0
- data/bin/fitframe +68 -0
- data/bin/occupiedpolyhedralsite +96 -0
- data/bin/occupiedscattersite +77 -0
- data/bin/site2poscar +66 -0
- data/bin/site2pov +30 -0
- data/bin/sitecombination +69 -0
- data/bin/sitemigration +80 -0
- data/bin/sitemigrationdistance +87 -0
- data/bin/siteoperation +109 -0
- data/bin/sitesingle +36 -0
- data/bin/siteuniq +32 -0
- data/bin/symidsite +65 -0
- data/bin/transitcell +46 -0
- data/crysna.gemspec +219 -0
- data/lib/crysna.rb +26 -0
- data/lib/crysna/atom.rb +97 -0
- data/lib/crysna/cell.rb +314 -0
- data/lib/crysna/frameatom.rb +13 -0
- data/lib/crysna/frameinterstitialcell.rb +309 -0
- data/lib/crysna/interstitialatom.rb +13 -0
- data/lib/crysna/modelstructure.rb +333 -0
- data/lib/crysna/optionmanager.rb +177 -0
- data/lib/crysna/site.rb +35 -0
- data/lib/crysna/siteconfiguration.rb +26 -0
- data/lib/crysna/sitenamelabeledcell.rb +220 -0
- data/lib/crysna/siteoperation.rb +56 -0
- data/lib/crysna/sitewithposition.rb +24 -0
- data/lib/crysna/transitionfinder.rb +448 -0
- data/lib/crysna/transitionfinder/cell.rb +144 -0
- data/lib/crysna/transitionfinder/cellmanager.rb +129 -0
- data/lib/crysna/transitionfinder/edge.rb +54 -0
- data/test/.gitignore +1 -0
- data/test/cell_orig/POSCAR +17 -0
- data/test/cell_orig/model.yaml +122 -0
- data/test/collectcells/.gitignore +2 -0
- data/test/collectcells/model.yaml +154 -0
- data/test/collectcells/nooutcar/minexpconfiguration.yaml +22 -0
- data/test/collectcells/normal-higher/OUTCAR +2406 -0
- data/test/collectcells/normal-higher/minexpconfiguration.yaml +22 -0
- data/test/collectcells/normal-lower/OUTCAR +2406 -0
- data/test/collectcells/normal-lower/minexpconfiguration.yaml +22 -0
- data/test/collectcells/normal/OUTCAR +2406 -0
- data/test/collectcells/normal/minexpconfiguration.yaml +22 -0
- data/test/collectcells/normalB/OUTCAR +2406 -0
- data/test/collectcells/normalB/minexpconfiguration.yaml +22 -0
- data/test/collectcells/unfinished/OUTCAR +40702 -0
- data/test/collectcells/unfinished/minexpconfiguration.yaml +22 -0
- data/test/collectcells/unidentified/OUTCAR +3541 -0
- data/test/collectcells/unidentified/minexpconfiguration.yaml +2 -0
- data/test/fitmodelstructure/.gitignore +1 -0
- data/test/fitmodelstructure/AgI/CONTCAR +17 -0
- data/test/fitmodelstructure/AgI/fitmodelstructure.log +1161 -0
- data/test/fitmodelstructure/AgI/model.yaml +45 -0
- data/test/fitmodelstructure/normal/CONTCAR +17 -0
- data/test/fitmodelstructure/normal/fitmodelstructure.log +5063 -0
- data/test/fitmodelstructure/normal/model.yaml +122 -0
- data/test/fitmodelstructure/unidentified/CONTCAR +44 -0
- data/test/fitmodelstructure/unidentified/fitmodelstructure.log +8833 -0
- data/test/fitmodelstructure/unidentified/model.yaml +154 -0
- data/test/helper.rb +17 -0
- data/test/identifypolyhedralsites/.gitignore +1 -0
- data/test/identifypolyhedralsites/identifyatomsites.log +333 -0
- data/test/identifypolyhedralsites/normal/fitmodelstructure.yaml +60 -0
- data/test/identifypolyhedralsites/normal/model.yaml +122 -0
- data/test/identifypolyhedralsites/unidentified/fitmodelstructure.yaml +2 -0
- data/test/identifypolyhedralsites/unidentified/model.yaml +154 -0
- data/test/identifypolyhedralsites/volumemismatch/fitmodelstructure.yaml +101 -0
- data/test/identifypolyhedralsites/volumemismatch/model.yaml +154 -0
- data/test/identifyscattersites/CONTCAR +17 -0
- data/test/identifyscattersites/POSCAR +12 -0
- data/test/identifyscattersites/fitmodelstructure.log +1 -0
- data/test/identifyscattersites/fitmodelstructure.yaml +0 -0
- data/test/identifyscattersites/identifyscattersites.yaml +5 -0
- data/test/identifyscattersites/model.yaml +45 -0
- data/test/minexpconfiguration/.gitignore +1 -0
- data/test/minexpconfiguration/collective/AgI/.gitignore +2 -0
- data/test/minexpconfiguration/collective/AgI/siteoperations.yaml +51265 -0
- data/test/minexpconfiguration/collective/AgI/sitesingle.yaml +15 -0
- data/test/minexpconfiguration/collective/AgI/test.sh +2 -0
- data/test/minexpconfiguration/normal/identifysites.yaml +22 -0
- data/test/minexpconfiguration/normal/minexpconfiguration.log +0 -0
- data/test/minexpconfiguration/normal/siteoperations.yaml +1793 -0
- data/test/minexpconfiguration/unidentified/identifysites.yaml +2 -0
- data/test/minexpconfiguration/unidentified/siteoperations.yaml +1793 -0
- data/test/sitecombination/initsites.yaml +7 -0
- data/test/sitecombination/initsites_test2.yaml +8 -0
- data/test/sitecombination/sitecombination.yaml +29 -0
- data/test/siteconfiguration/elements-sitenames.yaml +2 -0
- data/test/siteconfiguration/latticeaxes.yaml +3 -0
- data/test/siteconfiguration/sitenames-coordinates.yaml +4 -0
- data/test/sitemigrationsdistance/model.yaml +45 -0
- data/test/siteoperations/.gitignore +2 -0
- data/test/siteoperations/model.yaml +43 -0
- data/test/siteoperations/symmetryoperations.yaml +1441 -0
- data/test/sitesingle/.gitignore +1 -0
- data/test/sitesingle/sitecombination.yaml +29 -0
- data/test/siteuniq/minexpconfiguration.yaml +15 -0
- data/test/siteuniq/siteuniq.yaml +8 -0
- data/test/test_atom.rb +206 -0
- data/test/test_cell.rb +604 -0
- data/test/test_commands.rb +340 -0
- data/test/test_crystana.rb +7 -0
- data/test/test_frameatom.rb +22 -0
- data/test/test_frameinterstitialcell.rb +939 -0
- data/test/test_interstitialatom.rb +22 -0
- data/test/test_modelstructure.rb +807 -0
- data/test/test_optionmanager.rb +172 -0
- data/test/test_site.rb +40 -0
- data/test/test_siteconfiguration.rb +29 -0
- data/test/test_sitenamelabeledcell.rb +528 -0
- data/test/test_siteoperation.rb +79 -0
- data/test/test_sitewithposition.rb +20 -0
- data/test/test_transitionfinder.rb +432 -0
- data/test/transitcell/.gitignore +2 -0
- data/test/transitcell/collectcells.yaml +51 -0
- data/test/transitcell/sitemigrations.yaml +8 -0
- data/test/transitcell/siteoperations.yaml +17 -0
- data/test/transitcell/transitcell.log +1342 -0
- data/test/transitionfinder/collectcells.yaml +81 -0
- data/test/transitionfinder/sitemigrations.yaml +33 -0
- data/test/transitionfinder/siteoperations.yaml +16 -0
- data/test/transitionfinder/test_cell.rb +287 -0
- data/test/transitionfinder/test_cellmanager.rb +185 -0
- data/test/transitionfinder/test_edge.rb +49 -0
- data/test/uniquesitesgenerator/elements-sitenames.yaml +1 -0
- data/test/uniquesitesgenerator/siteoperations.yaml +9 -0
- 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
|
+
|