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,96 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "rubygems"
5
+ require "crysna"
6
+ require "yaml"
7
+ require "pp"
8
+ require "optparse"
9
+
10
+ TOLERANCE = 1.0E-10
11
+ PROGRAM_NAME = File.basename __FILE__
12
+ LOG_FILE = "#{PROGRAM_NAME}.log"
13
+
14
+ ## option analysis
15
+ om = Crysna::OptionManager.new([:model, :fitted, :occupied])
16
+ om.parser.banner += "\n" + <<HERE
17
+ Find site names of occupied interstitial sites.
18
+ Default output: #{Crysna::OptionManager::DEFAULT_OCCUPIED_SITES_FILE}
19
+ HERE
20
+ om.parser.parse!(ARGV)
21
+ options = om.options
22
+
23
+ unless ARGV.size == 2
24
+ puts om.parser.banner, "Exit."
25
+ exit
26
+ end
27
+
28
+
29
+ model_cell_00 = Crysna::ModelStructure.load_file(ARGV[0])
30
+ optimized_ficell = YAML.load_file(ARGV[1])
31
+
32
+ ## If not identified structure
33
+ if optimized_ficell.class == String
34
+ results = optimized_ficell
35
+ result_io = File.open(options[:occupied], "w")
36
+ YAML.dump(results, result_io)
37
+ exit
38
+ end
39
+
40
+ ## Normal process.
41
+ results = {}
42
+ optimized_ficell["frame_atoms"].each do |name, atom|
43
+ elem = atom["element"]
44
+ results[elem] ||= []
45
+ results[elem] << name
46
+ end
47
+
48
+ frame_sites = {}
49
+ optimized_ficell["frame_atoms"].each do |name, atom|
50
+ frame_sites[name] = Mageo::Vector3DInternal[*atom["coordinates"]]
51
+ end
52
+
53
+ hash = {
54
+ "frame_elements" => model_cell_00.frame_elements,
55
+ "symmetry_operations" => model_cell_00.symmetry_operations,
56
+ "octahedral_sites" => model_cell_00.octahedral_sites,
57
+ "tetrahedral_sites" => model_cell_00.tetrahedral_sites,
58
+ "frame_sites" => frame_sites
59
+ }
60
+
61
+ begin
62
+ model_cell = Crysna::ModelStructure.new(hash)
63
+ rescue Crysna::ModelStructure::SiteVolumeError
64
+ results = "Volume mismatch."
65
+ result_io = File.open(options[:occupied], "w")
66
+ YAML.dump(results, result_io)
67
+ exit
68
+ end
69
+
70
+ log_io = File.open(LOG_FILE, "w")
71
+ i_atoms = optimized_ficell["interstitials"]
72
+
73
+ pbar = ProgressBar.new( __FILE__, i_atoms.size)
74
+ i_atoms.each_with_index do |atom, index|
75
+ log_io.puts " atom #{index}; element #{atom["element"]}, coordinates #{atom["coordinates"].to_s}"
76
+ pbar.inc
77
+
78
+ elem = atom["element"]
79
+ coord = atom["coordinates"]
80
+ results[elem] ||= []
81
+ begin
82
+ results[elem] << model_cell.find_interstitial_site(coord, TOLERANCE, log_io)
83
+ rescue Crysna::ModelStructure::SiteDetectionError
84
+ results = "Interstitial site detection error."
85
+ result_io = File.open(options[:occupied], "w")
86
+ YAML.dump(results, result_io)
87
+ exit
88
+ end
89
+ end
90
+ pbar.finish
91
+ log_io.close
92
+
93
+ results.each { |elem, sites| sites.sort! }
94
+
95
+ result_io = File.open(options[:occupied], "w")
96
+ YAML.dump(results, result_io)
@@ -0,0 +1,77 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "rubygems"
5
+ require "crysna"
6
+ require "yaml"
7
+ require "pp"
8
+ require "optparse"
9
+
10
+ TOLERANCE = 1.0E-10
11
+ PROGRAM_NAME = File.basename __FILE__
12
+ LOG_FILE = "#{PROGRAM_NAME}.log"
13
+
14
+ ## option analysis
15
+ om = Crysna::OptionManager.new([:model, :fitted, :occupied])
16
+ om.parser.banner += "\n Identify occupied interstitial sites in fitted_structure using model_structure."
17
+ om.parser.parse!(ARGV)
18
+ options = om.options
19
+
20
+ unless ARGV.size == 0
21
+ puts om.parser.banner, "Exit."
22
+ exit
23
+ end
24
+
25
+ model_cell_00 = Crysna::ModelStructure.load_file(options[:model])
26
+ optimized_ficell = YAML.load_file(options[:fitted])
27
+
28
+ ## Normal process.
29
+ results = {}
30
+ optimized_ficell["frame_atoms"].each do |name, atom|
31
+ elem = atom["element"]
32
+ results[elem] ||= []
33
+ results[elem] << name
34
+ end
35
+
36
+ frame_sites = {}
37
+ optimized_ficell["frame_atoms"].each do |name, atom|
38
+ frame_sites[name] = Mageo::Vector3DInternal[*atom["coordinates"]]
39
+ end
40
+
41
+ hash = {
42
+ "frame_elements" => model_cell_00.frame_elements,
43
+ "symmetry_operations" => model_cell_00.symmetry_operations,
44
+ "scatter_sites" => model_cell_00.scatter_sites,
45
+ "frame_sites" => frame_sites
46
+ }
47
+
48
+ begin
49
+ model_cell = Crysna::ModelStructure.new(hash)
50
+ rescue Crysna::ModelStructure::SiteVolumeError
51
+ results = "Volume mismatch."
52
+ result_io = File.open(options[:occupied], "w")
53
+ YAML.dump(results, result_io)
54
+ exit
55
+ end
56
+
57
+ log_io = File.open(LOG_FILE, "w")
58
+ i_atoms = optimized_ficell["interstitials"]
59
+ s_sites = model_cell.scatter_sites
60
+
61
+ pbar = ProgressBar.new( PROGRAM_NAME, i_atoms.size)
62
+ i_atoms.each_with_index do |atom, index|
63
+ log_io.puts " atom #{index}; element #{atom["element"]}, coordinates #{atom["coordinates"].to_s}"
64
+ pbar.inc
65
+
66
+ elem = atom["element"]
67
+ coord = atom["coordinates"]
68
+ results[elem] ||= []
69
+ results[elem] << model_cell.find_site(coord, s_sites)[0]
70
+ end
71
+ pbar.finish
72
+ log_io.close
73
+
74
+ results.each { |elem, sites| sites.sort! }
75
+
76
+ result_io = File.open(options[:occupied], "w")
77
+ YAML.dump(results, result_io)
data/bin/site2poscar ADDED
@@ -0,0 +1,66 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ # Generate POSCAR from sitename info and coordinates.
5
+ #
6
+ require "optparse"
7
+ require "pp"
8
+ require "crysna"
9
+ require "vasputils"
10
+
11
+ ## option analysis
12
+ om = Crysna::OptionManager.new([:cells, :model])
13
+ om.parser.banner = <<HERE
14
+ #{om.parser.banner}
15
+ Example: #{File.basename("#{__FILE__}")} --model=model.yaml --lattice='4.0,5.0,6.0,90.0,90.0,120.0' --cells=cells.yaml",
16
+ --model, --lattice, and --cells options are necessary.",
17
+ string parts in --lattice option correspond to 'a,b,c,alpha,beta,gama'.",
18
+ HERE
19
+
20
+ om.parser.on("-m val", "--model=val", "model.yaml"){|str|
21
+ om.options[:model] = Crysna::ModelStructure.load_file(str)
22
+ }
23
+ om.parser.on("-l val", "--lattice=val", "Lattice constants of 6 values."){|str|
24
+ lc = str.split(",").map{|digit| digit.to_f}
25
+ om.options[:axes] = CrystalCell::LatticeAxes.lc_to_axes( lc )
26
+ }
27
+ om.parser.parse!(ARGV)
28
+ options = om.options
29
+
30
+ unless options[:model] && options[:axes] && options[:cells]
31
+ # if any is empty
32
+ puts om.parser.banner
33
+ exit
34
+ end
35
+
36
+ mc = options[:model]
37
+ sitenames_coordinates =mc.frame_sites.merge(mc.ideal_interstitial_sites).merge(mc.scatter_sites)
38
+
39
+ dirs_confs = YAML.load_file options[:cells]
40
+
41
+ dirs_confs.each do |key, sites|
42
+ hash = {}
43
+ hash[:comment ] = key
44
+ hash[:scale ] = 1.0
45
+ hash[:axes ] = options[:axes]
46
+ hash[:direct ] = true
47
+ hash[:selective_dynamics] = false
48
+ hash[:elements ] = sites.keys
49
+ hash[:nums_elements ] = sites.values.map{|i| i.size}
50
+ hash[:positions ] = sites.values.flatten.map do |site|
51
+ sitenames_coordinates[site]
52
+ end
53
+ poscar = VaspUtils::Poscar.new(hash)
54
+
55
+ if File.exist? key
56
+ puts "Already exist: #{key}"
57
+ next
58
+ else
59
+ Dir.mkdir key
60
+ File.open("#{key}/POSCAR", "w") do |io|
61
+ poscar.dump(io)
62
+ end
63
+ end
64
+
65
+ end
66
+
data/bin/site2pov ADDED
@@ -0,0 +1,30 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ # サイトを描画するための pov 形式を標準出力に書き出す。
5
+ # オプション以外の最初の引数は POSCAR/CONTCAR
6
+ # それ以外の引数は書き出すサイト名。
7
+
8
+
9
+ #require "pp"
10
+ #require "yaml"
11
+ #require "optparse"
12
+ #require "crysna/modelcell.rb"
13
+ #require "povrayutils/povrayobject.rb"
14
+
15
+ unless ARGV.size >= 2
16
+ puts "Usage: site2pov model.yaml SITE_A [SITE_B...]"
17
+ exit
18
+ end
19
+
20
+ model_cell_file = ARGV.shift
21
+ site_names = ARGV
22
+
23
+ model_cell = ModelStructure::Cell.load_file(model_cell_file, false)
24
+ model_cell.polyhedra.each do |name, polyhedron|
25
+ if site_names.include?(name)
26
+ polyhedron.triangles.each do |triangle|
27
+ puts triangle.to_pov([1.0, 0.0, 0.0])
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,69 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "pp"
5
+ require "yaml"
6
+ require "crysna"
7
+
8
+ #IN_FILE = Crysna::OptionManager::DEFAULT_SITE_CANDIDATE_FILE
9
+ #OUT_FILE = Crysna::OptionManager::DEFAULT_SITE_COMBINATION_FILE
10
+
11
+ ## option analysis
12
+ om = Crysna::OptionManager.new([:candidate, :combination])
13
+ om.parser.banner += "\n" +
14
+ <<HERE
15
+ Default input #{Crysna::OptionManager::DEFAULT_SITE_CANDIDATE_FILE}
16
+ Default output #{Crysna::OptionManager::DEFAULT_SITE_COMBINATION_FILE}
17
+ HERE
18
+ om.parser.parse!(ARGV)
19
+ options = om.options
20
+
21
+ def combination_array(ary)
22
+ if ary.size == 1
23
+ return ary[0].map{|item| [item]}
24
+ end
25
+
26
+ item_1st = ary.shift
27
+ sub_ary = combination_array(ary)
28
+ result = []
29
+ item_1st.each do |item|
30
+ sub_ary.each do |sub_item|
31
+ result << [item, *sub_item]
32
+ end
33
+ end
34
+ return result
35
+ end
36
+
37
+ elem_sites = YAML.load_file(options[:candidate]) # パース
38
+
39
+ elems = {}
40
+ elem_sites.each do |elem, atoms|
41
+ elems[elem] = atoms.size
42
+ end
43
+
44
+ sites_combinations = []
45
+ elem_sites.each do |elem, combinations|
46
+ combinations.each do |combi|
47
+ sites_combinations << combi
48
+ end
49
+ end
50
+ # [[["1A", "2A"], ["1B", "2B"], ["1C", "2C"]], [["IA"], ["IB", "2X"]]]
51
+
52
+ combinations = combination_array( sites_combinations )
53
+
54
+ max = combinations.size
55
+ num_figure = max.to_s.size
56
+
57
+ results = {}
58
+ combinations.size.times do |i|
59
+ name = sprintf("%0#{num_figure}d", i )
60
+ combi = combinations[i]
61
+ elems_sitenames = Crysna::Cell.new_elems_sitenames(elems, combi).sites
62
+ results[name] = elems_sitenames
63
+ end
64
+ pp results
65
+
66
+ File.open(options[:combination], "w") do |io|
67
+ YAML.dump(results, io)
68
+ end
69
+
data/bin/sitemigration ADDED
@@ -0,0 +1,80 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ # 結晶中のサイト同士の位置関係を解析し、
5
+ # 移動可能な組を yaml 形式で出力する。
6
+
7
+ require "optparse"
8
+ require "rubygems"
9
+ require "progressbar"
10
+ require "crysna"
11
+
12
+
13
+ TOLERANCE = 1.0E-10
14
+
15
+ ## option analysis
16
+ om = Crysna::OptionManager.new([:model, :fitted, :migration])
17
+ om.parser.banner += "\n" +
18
+ <<HERE
19
+ Default output sitemigration.yaml and sitemigration.dot .
20
+ HERE
21
+ om.parser.on("-n val", "--number=val", "Indicate the least number of shared vertices."){|v| om.options[:number] = v.to_i}
22
+ om.parser.parse!(ARGV)
23
+ options = om.options
24
+
25
+ unless options[:number]
26
+ puts om.parser.banner
27
+ exit
28
+ end
29
+
30
+ unless ARGV.size == 0
31
+ puts om.parser.banner
32
+ exit
33
+ end
34
+
35
+ model_cell = Crysna::ModelStructure.load_file(options[:model])
36
+ polyhedra = model_cell.polyhedra
37
+ names = polyhedra.keys
38
+
39
+ dot_io = File.open("sitemigration.dot", "w")
40
+ dot_io.puts "graph sample {"
41
+ bi_results = {}
42
+
43
+ pbar = ProgressBar.new("sitemigration", names.size * (names.size - 1) / 2)
44
+
45
+ names.combination(2).each do |name0, name1|
46
+ pbar.inc
47
+
48
+ ## finding
49
+ (-1).upto(1) do |a|
50
+ (-1).upto(1) do |b|
51
+ (-1).upto(1) do |c|
52
+ p0 = polyhedra[name0]
53
+ p1 = polyhedra[name1].translate(Mageo::Vector3D[-a, -b, -c])
54
+ if p0.shared_vertices(p1, TOLERANCE).size >= options[:number]
55
+ #for yaml
56
+ bi_results[name0] ||= []
57
+ bi_results[name0] << [name1, [a,b,c]]
58
+ bi_results[name1] ||= []
59
+ bi_results[name1] << [name0, [-a,-b,-c]]
60
+
61
+ #for dot
62
+ g_vec = [a, b, c].to_s
63
+ #g_vec = "" if [a, b, c] == [0, 0, 0]
64
+
65
+ #dot_io.puts " #{name0} -- #{name1}[headlabel = \"#{g_vec}\"];"
66
+ dot_io.print " #{name0} -- #{name1}"
67
+ dot_io.print " [headlabel = \"#{g_vec}\"];" unless [a, b, c] == [0, 0, 0]
68
+ dot_io.puts
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ dot_io.puts "}"
75
+
76
+ File.open(options[:migration], "w") do |io|
77
+ YAML.dump(bi_results, io)
78
+ end
79
+
80
+ puts
@@ -0,0 +1,87 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "optparse"
5
+ require "rubygems"
6
+ require "progressbar"
7
+ #require "mageo"
8
+ require "crysna"
9
+
10
+
11
+
12
+ #TOLERANCE = 1.0E-10
13
+
14
+ ## option analysis
15
+ #om = Crysna::OptionManager.new([:model, :fitted, :migration])
16
+ om = Crysna::OptionManager.new([:model, :migration])
17
+ om.parser.banner += "\n" + <<HERE
18
+ Analyse relationship between sites in crystal,
19
+ and output combination of movable sites with yaml format.
20
+ HERE
21
+
22
+ om.parser.on("-d val", "--distance=val", "Maximum distance."){|v| om.options[:distance] = v.to_f}
23
+ om.parser.on("-l val", "--lattice=val", "Lattice constants."){|v| om.options[:lattice] = v}
24
+ om.parser.parse!(ARGV)
25
+ options = om.options
26
+
27
+ if options[:lattice]
28
+ latticeconstants = options[:lattice].split(",").map{|str| str.to_f}
29
+ #pp latticeconstants
30
+ axes = CrystalCell::LatticeAxes.new_lc(latticeconstants)
31
+ else
32
+ puts "No lattice constants."
33
+ puts "Indicate, e.g., --lattice='1.0,2.0,3.0,90.0,90.0,90.0'"
34
+ exit
35
+ end
36
+
37
+ if ARGV.size != 0 || (! options[:distance])
38
+ puts om.parser.banner
39
+ exit
40
+ end
41
+
42
+ model_cell = Crysna::ModelStructure.load_file(options[:model])
43
+ s_sites = model_cell.scatter_sites
44
+
45
+ names = s_sites.keys
46
+
47
+ dot_io = File.open("sitemigration.dot", "w")
48
+ dot_io.puts "graph sample {"
49
+ bi_results = {}
50
+
51
+ pbar = ProgressBar.new("sitemigration", names.size * (names.size - 1) / 2)
52
+
53
+ names.combination(2).each do |name0, name1|
54
+ pbar.inc
55
+ ## finding
56
+ (-1).upto(1) do |a|
57
+ (-1).upto(1) do |b|
58
+ (-1).upto(1) do |c|
59
+ p0 = s_sites[name0].to_v3di.to_v3d(axes)
60
+ p1 = (s_sites[name1].to_v3di + (Mageo::Vector3DInternal[a, b, c])).to_v3d( axes)
61
+
62
+ distance = (p0 - p1).r
63
+ if distance < options[:distance]
64
+ bi_results[name0] ||= []
65
+ bi_results[name0] << [name1, [a,b,c]]
66
+ bi_results[name1] ||= []
67
+ bi_results[name1] << [name0, [-a,-b,-c]]
68
+ #for dot
69
+ g_vec = [a, b, c].to_s
70
+ #g_vec = "" if [a, b, c] == [0, 0, 0]
71
+
72
+ #dot_io.puts " #{name0} -- #{name1}[headlabel = \"#{g_vec}\"];"
73
+ dot_io.print " #{name0} -- #{name1}"
74
+ dot_io.print " [headlabel = \"#{g_vec}\"];" unless [a, b, c] == [0, 0, 0]
75
+ dot_io.puts
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ dot_io.puts "}"
82
+
83
+ File.open(options[:migration], "w") do |io|
84
+ YAML.dump(bi_results, io)
85
+ end
86
+
87
+ puts