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.
- 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
|
+
|