aims_project_windows 0.3.1

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.
@@ -0,0 +1,183 @@
1
+ module AimsProject
2
+ class Inspector < Wx::Frame
3
+
4
+ include Wx
5
+
6
+ class << self
7
+ def control_value_accessor(*args)
8
+ args.each do |cb|
9
+ class_eval <<-EOS
10
+ def #{cb.to_s}
11
+ @#{cb.to_s}.get_value
12
+ end
13
+ EOS
14
+ end
15
+ end
16
+ end
17
+
18
+ control_value_accessor :bond_length
19
+ control_value_accessor :show_bonds, :show_lighting, :show_cell
20
+ control_value_accessor :show_clip_planes, :show_xclip, :show_yclip, :show_zclip
21
+ control_value_accessor :x_repeat, :y_repeat, :z_repeat
22
+ control_value_accessor :correct
23
+ control_value_accessor :transparent_bg
24
+
25
+ attr_accessor :update_unit_cell
26
+
27
+ def initialize(app, frame)
28
+
29
+ super(frame, :style => (CLOSE_BOX | CAPTION | FRAME_FLOAT_ON_PARENT))
30
+
31
+ @app = app
32
+
33
+ # Array to track the inspector windows being shown
34
+ @windows = []
35
+
36
+ self.sizer = BoxSizer.new(VERTICAL)
37
+ set_auto_layout(true)
38
+ self.sizer.set_size_hints(self)
39
+ self.sizer.fit(self)
40
+
41
+ self.update_unit_cell = false
42
+ self.evt_close {|event| self.hide }
43
+ end
44
+
45
+ # Create a window to show in the inspector. Default is to not show this window.
46
+ # call show_inspector_window() to show it
47
+ # options are Wx:Sizer options
48
+ # return the window so that caller can add controls to it
49
+ def add_inspector_window(options = {})
50
+ window = Panel.new(self)
51
+ @windows << window
52
+ self.sizer.add_item(window, options)
53
+ self.sizer.show(window, false)
54
+ return window
55
+ end
56
+
57
+ # Show the inspector window
58
+ def show_inspector_window(window)
59
+ @windows.each {|w|
60
+ self.sizer.show(w, w == window)
61
+ }
62
+ self.sizer.fit(self)
63
+ end
64
+
65
+ # The view options
66
+ def view_options_panel(parent)
67
+
68
+ # Default padding around each element
69
+ border = 5
70
+
71
+ panel = Wx::VBoxSizer.new
72
+ parent.sizer = panel
73
+
74
+ # Panel 1
75
+ panel1 = Wx::VBoxSizer.new
76
+
77
+ @show_bonds = Wx::CheckBox.new(parent, :label => 'Show Bonds')
78
+ panel1.add_item(@show_bonds, :flag => ALL,:border => border)
79
+
80
+ @show_lighting = Wx::CheckBox.new(parent, :label => 'Show Lighting')
81
+ panel1.add_item(@show_lighting, :flag => ALL, :border => border)
82
+
83
+ @show_cell = Wx::CheckBox.new(parent, :label => "Show Unit Cell")
84
+ panel1.add_item(@show_cell, :flag => ALL, :border => border)
85
+
86
+ @correct = Wx::CheckBox.new(parent, :label => "Correct Geometry")
87
+ panel1.add_item(@correct, :flag => ALL, :border => border)
88
+
89
+ @transparent_bg = Wx::CheckBox.new(parent, :label => "Transparent BG")
90
+ panel1.add_item(@transparent_bg, :flag => ALL, :border => border)
91
+
92
+ gsizer = GridSizer.new(2,1)
93
+ gsizer.add(StaticText.new(parent, :label => "Bond Length"))
94
+ @bond_length = SpinCtrl.new(parent, :min => 1, :max => 100, :value => "4")
95
+ gsizer.add_item(@bond_length, :flag => EXPAND)
96
+ panel1.add_item(gsizer)
97
+
98
+ evt_checkbox(@show_bonds) {|evt| @app.update_viewer}
99
+ evt_checkbox(@show_lighting) {|evt| @app.update_viewer}
100
+ evt_checkbox(@show_cell) {|evt| @app.update_viewer}
101
+ evt_checkbox(@transparent_bg) {|evt| @app.update_viewer}
102
+ evt_checkbox(@correct) {|evt|
103
+ self.update_unit_cell = true
104
+ @app.update_viewer
105
+ }
106
+ evt_spinctrl(@bond_length) {|evt| @app.update_viewer }
107
+
108
+ # Panel 2 : Clip Planes
109
+ panel2 = Wx::VBoxSizer.new
110
+ panel2.add_item(StaticText.new(parent, -1, "Clip Planes:", :style => ALIGN_LEFT))
111
+ @show_xclip = Wx::CheckBox.new(parent, :label => 'x')
112
+ panel2.add_item(@show_xclip, 0, Wx::ALIGN_CENTER, border)
113
+ @show_yclip = Wx::CheckBox.new(parent, :label => 'y')
114
+ panel2.add_item(@show_yclip, 0, Wx::ALIGN_CENTER, border)
115
+ @show_zclip = Wx::CheckBox.new(parent, :label => 'z')
116
+ panel2.add_item(@show_zclip, 0, Wx::ALIGN_CENTER, border)
117
+
118
+
119
+ evt_checkbox(@show_xclip) {|evt| @app.update_viewer}
120
+ evt_checkbox(@show_yclip) {|evt| @app.update_viewer}
121
+ evt_checkbox(@show_zclip) {|evt| @app.update_viewer}
122
+
123
+ # Panel 3: Repeat
124
+ panel3 = Wx::VBoxSizer.new
125
+ panel3.add_item(StaticText.new(parent, -1, "Repeat:", :style => ALIGN_LEFT), 0, EXPAND)
126
+
127
+ panel3grid = GridSizer.new(3,2, border, border)
128
+
129
+ @x_repeat = Wx::SpinCtrl.new(parent, :value => "1", :min => 1, :max => 100, :initial => 1)
130
+ @y_repeat = Wx::SpinCtrl.new(parent, :value => "1", :min => 1, :max => 100, :initial => 1)
131
+ @z_repeat = Wx::SpinCtrl.new(parent, :value => "1", :min => 1, :max => 100, :initial => 1)
132
+
133
+ evt_spinctrl(@x_repeat) {|evt|
134
+ self.update_unit_cell = true
135
+ @app.update_viewer
136
+ }
137
+ evt_spinctrl(@y_repeat) {|evt|
138
+ self.update_unit_cell = true
139
+ @app.update_viewer
140
+ }
141
+ evt_spinctrl(@z_repeat) {|evt|
142
+ self.update_unit_cell = true
143
+ @app.update_viewer
144
+ }
145
+
146
+ panel3grid.add(StaticText.new(parent, :label => "x", :style => ALIGN_RIGHT),1, EXPAND)
147
+ panel3grid.add(@x_repeat,2)
148
+
149
+ panel3grid.add(StaticText.new(parent, :label => "y",:style => ALIGN_RIGHT),1, EXPAND)
150
+ panel3grid.add(@y_repeat,2)
151
+
152
+ panel3grid.add(StaticText.new(parent, :label => "z",:style => ALIGN_RIGHT),1, EXPAND)
153
+ panel3grid.add(@z_repeat,2)
154
+
155
+ panel3.add(panel3grid, 0, EXPAND | ALIGN_CENTER)
156
+
157
+ # Add sub-panels
158
+ panel.add(panel1, 0, Wx::ALL)
159
+ panel.add_spacer(5)
160
+ panel.add(panel2, 0, Wx::EXPAND)
161
+ panel.add_spacer(5)
162
+ panel.add(panel3, 0, Wx::EXPAND)
163
+
164
+
165
+ end
166
+
167
+ # Called when a new file is loaded
168
+ def update(viewer)
169
+ @show_bonds.set_value(viewer.show_bonds)
170
+ @show_lighting.set_value(viewer.lighting)
171
+ @show_cell.set_value(viewer.show_supercell)
172
+ @correct.set_value(false)
173
+ @show_xclip.set_value(viewer.show_xclip)
174
+ @show_yclip.set_value(viewer.show_yclip)
175
+ @show_zclip.set_value(viewer.show_zclip)
176
+ @bond_length.set_value(viewer.bond_length)
177
+ @x_repeat.set_value(1)
178
+ @y_repeat.set_value(1)
179
+ @z_repeat.set_value(1)
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,30 @@
1
+ module AimsProject
2
+ class Material
3
+
4
+ include Gl
5
+
6
+ attr_accessor :r, :g, :b, :alpha
7
+
8
+ def Material.black
9
+ Material.new(0,0,0)
10
+ end
11
+
12
+ def initialize(r,g,b,alpha=1)
13
+ self.r = r
14
+ self.g = g
15
+ self.b = b
16
+ self.alpha = alpha
17
+ end
18
+
19
+ def apply(lighting = true)
20
+ if lighting
21
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, [self.r, self.g, self.b, self.alpha])
22
+ glMaterialfv(GL_FRONT, GL_SPECULAR, [self.r, self.g, self.b, self.alpha])
23
+ glMaterialf(GL_FRONT, GL_SHININESS, 50)
24
+ else
25
+ glColor3f(self.r, self.g, self.b)
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,5 @@
1
+ module AimsProject
2
+ class Octree
3
+
4
+ end
5
+ end
Binary file
@@ -0,0 +1,102 @@
1
+ require 'fileutils'
2
+
3
+ module AimsProject
4
+
5
+ class Project
6
+
7
+ # A project is a collection of calculations
8
+ # and tools for managing the execution and analysis of the calculations
9
+
10
+ # The name of this project
11
+ attr_accessor :name
12
+
13
+ # Load a Project from the serialized yaml file
14
+ def Project.load(filename)
15
+ yamlfile = [filename, filename+".yaml"].find{|f| File.exists?(f)}
16
+
17
+ File.open(yamlfile, 'r') do |f|
18
+ YAML.load(f)
19
+ end
20
+ end
21
+
22
+ # Create a new Project with the given name
23
+ # This will also create the directory structure
24
+ # for the project. Returns true if successful, false otherwise
25
+ def Project.create(name)
26
+
27
+ return nil unless name
28
+
29
+ p = Project.new(name)
30
+
31
+ # Create the project directory
32
+ FileUtils.mkdir(p.relative_path)
33
+ p.save(p.relative_path)
34
+ #
35
+ # # Create the config directory
36
+ # FileUtils.mkdir(File.join(p.relative_path, "config"))
37
+ #
38
+ # # Create the geometry directory
39
+ # FileUtils.mkdir(File.join(p.relative_path, AimsProject::GEOMETRY_DIR))
40
+ #
41
+ # # Create the control directory
42
+ # FileUtils.mkdir(File.join(p.relative_path, AimsProject::CONTROL_DIR))
43
+ #
44
+ # # Create the calculations directory
45
+ # FileUtils.mkdir(File.join(p.relative_path, AimsProject::CALCULATION_DIR))
46
+
47
+ return p
48
+ end
49
+
50
+ # Initialize a new project object with the given name.
51
+ # This does not create the project directory structure, use create for that.
52
+ def initialize(name)
53
+ self.name = name
54
+ end
55
+
56
+ # Return the binding for this project
57
+ def get_binding
58
+ binding
59
+ end
60
+
61
+ # The path of this project relative to project_root_dir
62
+ def relative_path
63
+ name
64
+ end
65
+
66
+ # The filename of the serialized yaml file representing this project
67
+ def serialized_filename
68
+ "#{self.name}.yaml"
69
+ end
70
+
71
+ # The full path to this project locally
72
+ def full_path
73
+ File.dirname(File.expand_path(serialized_filename))
74
+ end
75
+
76
+ # Serialize this project to a yaml file named after this project
77
+ # in the given directory
78
+ def save(dir = ".")
79
+ File.open(File.join(dir, "#{name}.yaml"), 'w') do |f|
80
+ f.print YAML.dump(self)
81
+ end
82
+ end
83
+
84
+ # Retreive the calcluations managed by this project.
85
+ # This array is loaded directly from serialized yaml
86
+ # files in each calculation directory
87
+ def calculations
88
+ calc_status_files = Dir.glob(File.join(AimsProject::CALCULATION_DIR, "*", AimsProject::CALC_STATUS_FILENAME))
89
+ # pick up sub-calculations
90
+ calc_status_files += Dir.glob(File.join(AimsProject::CALCULATION_DIR, "*", "*", AimsProject::CALC_STATUS_FILENAME))
91
+ calc_status_files.collect{|f|
92
+ Calculation.load(File.dirname(f))
93
+ }
94
+ end
95
+
96
+ # Retreive the geometries managed by this project.
97
+ def geometries
98
+ Dir.glob(File.join(AimsProject::GEOMETRY_DIR, "*"))
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,62 @@
1
+ module AimsProject
2
+
3
+ class ProjectTree < Wx::ScrolledWindow
4
+
5
+ include Wx
6
+
7
+ ROOT = "Root"
8
+ GEOMETRY = "Geometry"
9
+ CONTROL = "Control"
10
+ CALCULATIONS = "Calculations"
11
+
12
+
13
+ attr_accessor :app, :treeControl
14
+
15
+ def initialize(app, window)
16
+ super(window)
17
+ self.app = app
18
+
19
+ init_project_tree
20
+
21
+ sizer = BoxSizer.new(VERTICAL)
22
+ sizer.add(self.treeControl, 1, EXPAND | ALL, 5)
23
+
24
+ set_auto_layout(true)
25
+ set_sizer(sizer)
26
+ end
27
+
28
+ def init_project_tree
29
+ @treeControl = Wx::TreeCtrl.new(self)
30
+ @tree_map = {}
31
+ if self.app.project
32
+ @tree_map[ROOT] = self.treeControl.add_root(self.app.project.name)
33
+ @tree_map[GEOMETRY] = self.treeControl.append_item(@tree_map[ROOT], GEOMETRY)
34
+ @tree_map[CONTROL] = self.treeControl.append_item(@tree_map[ROOT], CONTROL)
35
+ @tree_map[CALCULATIONS] = self.treeControl.append_item(@tree_map[ROOT], CALCULATIONS)
36
+
37
+ self.app.project.geometries.each{|geom|
38
+ self.treeControl.append_item(@tree_map[GEOMETRY], geom)
39
+ }
40
+
41
+ self.app.project.calculations.each{|calc|
42
+ calcid = self.treeControl.append_item(@tree_map[CALCULATIONS], calc.name)
43
+ @tree_map[calcid] = calc
44
+ }
45
+
46
+ evt_tree_sel_changed(self.treeControl) {|evt|
47
+ itemid = evt.get_item
48
+ if @tree_map[GEOMETRY] == self.treeControl.get_item_parent(itemid)
49
+ self.app.open_file(self.treeControl.get_item_text(itemid))
50
+ elsif @tree_map[CALCULATIONS] == self.treeControl.get_item_parent(itemid)
51
+ calc = @tree_map[itemid]
52
+ self.app.show_calculation(calc)
53
+ end
54
+ }
55
+ else
56
+ @tree_map[ROOT] = self.treeControl.add_root(ROOT)
57
+ end
58
+ @treeControl.expand(@tree_map[ROOT])
59
+ end
60
+
61
+ end
62
+ end
Binary file
@@ -0,0 +1,19 @@
1
+ module AimsProject
2
+ class ThreadCallbackEvent < Wx::CommandEvent
3
+
4
+ @@event_type_id = 0
5
+
6
+ def ThreadCallbackEvent.set_event_type(id)
7
+ @@event_type_id = id
8
+ end
9
+
10
+ def ThreadCallbackEvent.event_type
11
+ @@event_type_id
12
+ end
13
+
14
+ def initialize
15
+ super(@@event_type_id)
16
+ end
17
+
18
+ end
19
+ end
Binary file
@@ -0,0 +1,158 @@
1
+
2
+ # AimsProject is an application for visualizing and managing projects for
3
+ # the FHI-AIMS package
4
+
5
+ require "rubygems"
6
+ require 'aims'
7
+ require 'yaml'
8
+
9
+ require 'aims_project/project.rb'
10
+ require 'aims_project/calculation.rb'
11
+ require 'aims_project/geometry_file.rb'
12
+ require 'aims_project/aims_project_exception.rb'
13
+
14
+ # AimsProject is a set of tools for managing and organizing
15
+ # calculations for executaion on high-performance computing clusters.
16
+ # It is designed specifically for the FHI-AIMS package published
17
+ # by the Fritz-Haber Institute (https://aimsclub.fhi-berlin.mpg.de),
18
+ # but can probably be generatlized to other codes.
19
+ #
20
+ # Author: Joshua Shapiro (email:joshua.shapiro@gmail.com)
21
+ # Copyright: 2012 Joshua Shapiro
22
+ # License: TBD
23
+ #
24
+ # = Why should I use AimsProject?
25
+ # Good organization is crucial to obtaining meaningful results with
26
+ # the FHI-AIMS package. Careful testing of convergence
27
+ # across parameters in the control and geometry files easily requires
28
+ # dozens of calculations. The novice and expert user alike can quickly
29
+ # lose track of which calculations are complete, which are still pending,
30
+ # which calculations were errors, and which calculations failed or were aborted.
31
+ # In this framework, even the most experienced user can and will make mistakes.
32
+ #
33
+ # <em>The aim of this tool is to simplify and streamline the calculation
34
+ # pipeline, so the user can focus on the results.</em>
35
+ #
36
+ # = Features
37
+ # * Automated generation of calculations from control & geometry files.
38
+ # * Automated synchronization between a workstation and the compute cluster.
39
+ # * Automated job submission of pending calculations to the queue
40
+ # * Status tracking of calculations from creation to completion.
41
+ # * Simple organizational structure with human readable metadata.
42
+ #
43
+ # = Planned Features
44
+ # * Input file validation (To catch mistakes before submitting to a queue)
45
+ # * Geometry input and output visualization
46
+ #
47
+ # = Quick Start
48
+ # == Installation
49
+ #
50
+ # gem install aims_project
51
+ #
52
+ # == Creating a Project
53
+ #
54
+ # Type:
55
+ # AimsProject myProject
56
+ #
57
+ # This will create the directory structure
58
+ # myProject
59
+ # -> calculations/
60
+ # -> config/
61
+ # -> control/
62
+ # -> geometry/
63
+ # -> Capfile
64
+ # -> myProject.yaml
65
+ #
66
+ #
67
+ # +calculations+:: Contains one subdirectory for each calculation.
68
+ # +config+:: Contains special configuration files for automation.
69
+ # +geometry+:: This is where you will place all your geometry files.
70
+ # +control+:: This is where you place all your control files.
71
+ # +Capfile+:: Location where you customize the interaction with the compute cluster
72
+ # +myProject.yaml+:: Human readable metadata related to this project.
73
+ #
74
+ # == Creating a calculation
75
+ #
76
+ # Assume you are investigating two atomic configurations _alpha_ and _beta_, and
77
+ # you want to calculate them with the _light_ and _tight_ settings.
78
+ #
79
+ # Create the FHI-AIMS formatted input files and name them
80
+ # * +geometry/alpha+
81
+ # * +geometry/beta+
82
+ # * +control/light+
83
+ # * +control/tight+
84
+ #
85
+ # Now run
86
+ # > AimsCalc create alpha light
87
+ # > AimsCalc create beta light
88
+ # > AimsCalc create alpha tight
89
+ # > AimsCalc create beta tight
90
+ #
91
+ # This will create four subdirectories inside +calculations/+.
92
+ # > ls calculations/*
93
+ # calculations/alpha.light:
94
+ # calc_status.yaml control.in geometry.in
95
+ #
96
+ # calculations/alpha.tight:
97
+ # calc_status.yaml control.in geometry.in
98
+ #
99
+ # calculations/beta.light:
100
+ # calc_status.yaml control.in geometry.in
101
+ #
102
+ # calculations/beta.tight:
103
+ # calc_status.yaml control.in geometry.in
104
+ #
105
+ # Notice that each calculation directory has the required +control.in+ and
106
+ # +geometry.in+ file. These were directly copied from the geometry and control files
107
+ # passed to AimsCalc. *Note* It is possible to embed variables inside the control
108
+ # and geometry files, see AimsCalc for more details. Each directory also contains
109
+ # a file named +calc_status.yaml+. This is a metadata file used for tracking
110
+ # the history and status of the calculation. Currently this file looks something like
111
+ # --- !ruby/object:AimsProject::Calculation
112
+ # control: light
113
+ # geometry: alpha
114
+ # status: STAGED
115
+ #
116
+ #
117
+ # Feel free to get more creative with the geometry and control file names. You should encode
118
+ # as much information in the file name as possible, as this will make it easy
119
+ # for you to identify the calculation later. For example, a geometry file
120
+ # named +alpha2x2_5layers_relaxed+ and a control file named +light_tier1_norelax_6x6x1_lomem+
121
+ # will result in a calulation directory named +alpha2x2_5layers_relaxed.light_tier1_norelax_6x6x1_lomem+
122
+ #
123
+ # == Running a Calculation
124
+ # At this point the calculation status is +STAGED+. To run the calculation, first customize
125
+ # the +Capfile+ with details necessary for running FHI-AIMS on the computing cluster.
126
+ # Check this file carefully, this is where you define the name and location of the aims executable,
127
+ # the name of the server, and the method for submitting jobs to the queue. Once this file
128
+ # is properly configured, the calculations are submitted with one line:
129
+ #
130
+ # cap aims:enqueue
131
+ #
132
+ # This command invokes custom tasks in +Capistrano+, a 3rd party tool for automated deployment,
133
+ # that will upload the calculations to the server and submit them to the queue.
134
+ #
135
+
136
+
137
+
138
+ module AimsProject
139
+ # Constants
140
+ STAGED = "STAGED"
141
+ HOLD = "HOLD"
142
+ QUEUED = "QUEUED"
143
+ RUNNING = "RUNNING"
144
+ COMPLETE = "COMPLETE"
145
+ ABORTED = "ABORTED"
146
+ CANCELED = "CANCELED"
147
+
148
+ CONFIG_DIR = "config"
149
+ CALCULATION_DIR = "calculations"
150
+ GEOMETRY_DIR = "geometry"
151
+ CONTROL_DIR = "control"
152
+ CALC_STATUS_FILENAME = "calc_status.yaml"
153
+ PROJECT_VARIABLES_FILENAME = "project_vars.rb"
154
+
155
+ GLOBAL_CONFIG_DIR = File.join(ENV["HOME"], ".aims_project")
156
+ GLOBAL_VARIABLES_FILENAME = "aims_project_vars.rb"
157
+
158
+ end
data/skeleton/Capfile ADDED
@@ -0,0 +1,37 @@
1
+ require 'aims_project'
2
+
3
+ load 'config/tasks.rb'
4
+
5
+ # The name of this project
6
+ set :project_name, '__PROJECT_NAME__'
7
+
8
+ # The following settings apply to calculations occuring on the remote host
9
+
10
+ # The base directory on the remote host
11
+ set :remote_project_dir, 'AimsProjects'
12
+
13
+ # Query the user for the number of parallel nodes when queueing calculations
14
+ set(:nodes) {Capistrano::CLI.ui.ask("How many compute nodes?: ")}
15
+
16
+ # The memory for each calculation
17
+ set :memory, 1024
18
+
19
+ # The time limit for each calculation
20
+ set :time, 24
21
+
22
+ # Set the qstat command
23
+ set :qstat_cmd, "qstat -u jns"
24
+
25
+ # The qsub command to execute
26
+ # There are some extra commands in here to forward SIGUSR1 and SIGUSR2 to aims_script
27
+ # so that the job status can be properly updated if the job is aborted
28
+ # aims_script is predefined to be 'aims.sh', if this is unsuitable
29
+ # it can be reset with: set :aims_script, 'foo'
30
+ set(:qsub) {
31
+ "parallel.q -n #{nodes} -d #{memory} -t #{time} -ns -k #{aims_script}; sed '/\\btime\\b/ i\\ trap : SIGUSR1 SIGUSR2' #{aims_script}.cmd > #{aims_script}.cmd.new; mv #{aims_script}.cmd.new #{aims_script}.cmd; qsub -notify #{aims_script}.cmd"
32
+ }
33
+
34
+ # The remote host for data transfer of large files
35
+ role :data_transfer, "Your Data Transfer Server Here"
36
+ # The remote host for job submission
37
+ role :queue_submission, "Your Compute Cluster Server Here"
@@ -0,0 +1,58 @@
1
+ #!/bin/bash
2
+
3
+ # Setup environment
4
+ export OMP_NUM_THREADS=1
5
+ export MKL_NUM_THREADS=1
6
+ export MKL_DYNAMIC=FALSE
7
+
8
+ export LD_LIBRARY_PATH=/u/local/compilers/intel/11.1/073/mkl/lib/em64t:/u/local/compilers/intel/11.1/073//lib/intel64:/u/local/compilers/intel/11.1/073/ipp/em64t/sharedlib:/u/local/compilers/intel/11.1/073/mkl/lib/em64t:/u/local/compilers/intel/11.1/073/tbb/intel64/cc4.1.0_libc2.4_kernel2.6.16.21/lib:/u/local/apps/scalapack/current/ib:/u/local/compilers/intel/11.0/current/mkl/lib/em64t/:/u/local/intel/11.1/openmpi/1.4.5/lib:/u/local/compilers/intel/11.1/080/mkl/lib/em64t:/u/local/compilers/intel/11.1/080/lib/intel64
9
+
10
+ STATUSFILE=calc_status.yaml
11
+ LOCKFILE=${STATUSFILE}.lock
12
+ MACHINEFILE=hfile
13
+
14
+ # Required by openmpi
15
+ source /u/local/Modules/default/init/modules.sh
16
+ module load intel/11.1
17
+ module load openmpi/1.4
18
+
19
+
20
+ # Set the jobid in the status file
21
+ function setJobID() {
22
+ if [ ! -f $LOCKFILE ]; then
23
+ touch $LOCKFILE;
24
+ echo "jobid: ${JOB_ID}" >> $STATUSFILE
25
+ rm $LOCKFILE;
26
+ fi
27
+ }
28
+
29
+ # Define a function for modifying the status of the calculation
30
+ function setStatus() {
31
+ if [ ! -f $LOCKFILE ]; then
32
+ touch $LOCKFILE;
33
+ status=$1;
34
+ date_str=`date +'%Y-%m-%d %T %:z'`
35
+ TMPFILE=calc_status.tmp;
36
+ sed "s/status: .*/status: ${status}/; s/updated_at: .*/updated_at: ${date_str}/" $STATUSFILE > $TMPFILE;
37
+ mv $TMPFILE $STATUSFILE;
38
+ rm $LOCKFILE;
39
+ fi
40
+ }
41
+
42
+
43
+
44
+ # setup traps for early program termination
45
+ # qsub with the -notify flag will send SIGUSR1(30) or SIGUSR2(31) before killing a job
46
+ trap 'setStatus "ABORTED"; exit;' SIGUSR1 SIGUSR2
47
+
48
+ # Set the status to running
49
+ setJobID
50
+ setStatus "RUNNING"
51
+
52
+ # Run aims
53
+ # $NSLOTS is set by the sun-grid-engine when qsub is invoked.
54
+ awk '{print $1 " slots=" $2}' $PE_HOSTFILE > $MACHINEFILE
55
+ mpiexec -n $NSLOTS -machinefile $MACHINEFILE $HOME/bin/aims.071711_6.scalapack.mpi.x
56
+
57
+ # Set the status to complete
58
+ setStatus "COMPLETE"