aims_project_windows 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"