add files for public distribution
based on internal repository 0a462b6 2017-11-22 14:41:39 +0100
This commit is contained in:
1
projects/twoatom/__init__.py
Normal file
1
projects/twoatom/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__author__ = 'muntwiler_m'
|
249
projects/twoatom/twoatom.py
Normal file
249
projects/twoatom/twoatom.py
Normal file
@ -0,0 +1,249 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
@package projects.twoatom
|
||||
Two-atom demo scattering calculation project
|
||||
|
||||
this file is specific to the project and the state of the data analysis,
|
||||
as it contains particular parameter values.
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
import sys
|
||||
import os
|
||||
import math
|
||||
import numpy as np
|
||||
import periodictable as pt
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
# adjust the system path so that the main PMSCO code is found
|
||||
base_dir = os.path.dirname(__file__) or '.'
|
||||
package_dir = os.path.join(base_dir, '../..')
|
||||
package_dir = os.path.abspath(package_dir)
|
||||
sys.path.append(package_dir)
|
||||
|
||||
import pmsco.pmsco
|
||||
import pmsco.cluster as mc
|
||||
import pmsco.project as mp
|
||||
import pmsco.data as md
|
||||
from pmsco.helpers import BraceMessage as BMsg
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TwoatomProject(mp.Project):
|
||||
"""
|
||||
two-atom calculation project class.
|
||||
|
||||
the cluster contains a nitrogen in the top layer,
|
||||
and a nickel atom in the second layer.
|
||||
The layer distance and the angle can be adjusted by parameters.
|
||||
|
||||
the model parameters are:
|
||||
@arg @c model['dNNi'] : vertical distance N - Ni in Angstrom.
|
||||
@arg @c model['pNNi'] : polar angle of axis N - Ni in degrees. 0 = on top geometry.
|
||||
@arg @c model['V0'] : inner potential
|
||||
@arg @c model['Zsurf'] : position of surface
|
||||
"""
|
||||
def __init__(self):
|
||||
super(TwoatomProject, self).__init__()
|
||||
self.scan_dict = {}
|
||||
|
||||
def create_cluster(self, model, index):
|
||||
"""
|
||||
calculate a specific set of atom positions given the optimizable parameters.
|
||||
|
||||
the cluster contains a nitrogen in the top layer,
|
||||
and a nickel atom in the second layer.
|
||||
The layer distance and the angle can be adjusted by parameters.
|
||||
|
||||
@param model: (dict) optimizable parameters
|
||||
"""
|
||||
clu = mc.Cluster()
|
||||
clu.comment = "{0} {1}".format(self.__class__, index)
|
||||
clu.set_rmax(10.0)
|
||||
|
||||
a_N = np.array((0.0, 0.0, 0.0))
|
||||
rad_pNNi = math.radians(model['pNNi'])
|
||||
a_Ni1 = np.array((0.0,
|
||||
-model['dNNi'] * math.sin(rad_pNNi),
|
||||
-model['dNNi'] * math.cos(rad_pNNi)))
|
||||
|
||||
clu.add_atom(pt.N.number, a_N, 1)
|
||||
clu.add_atom(pt.Ni.number, a_Ni1, 0)
|
||||
|
||||
return clu
|
||||
|
||||
def create_params(self, model, index):
|
||||
"""
|
||||
set a specific set of parameters given the optimizable parameters.
|
||||
|
||||
@param model: (dict) optimizable parameters
|
||||
"""
|
||||
params = mp.Params()
|
||||
|
||||
params.title = "two-atom demo"
|
||||
params.comment = "{0} {1}".format(self.__class__, index)
|
||||
params.cluster_file = ""
|
||||
params.output_file = ""
|
||||
params.initial_state = self.scans[index.scan].initial_state
|
||||
params.spherical_order = 2
|
||||
params.polarization = "H"
|
||||
params.scattering_level = 5
|
||||
params.fcut = 15.0
|
||||
params.cut = 15.0
|
||||
params.angular_broadening = 0.0
|
||||
params.lattice_constant = 1.0
|
||||
params.z_surface = model['Zsurf']
|
||||
params.atom_types = 3
|
||||
params.atomic_number = [7, 28]
|
||||
params.phase_file = ["hbn_n.pha", "ni.pha"]
|
||||
params.msq_displacement = [0.01, 0.01, 0.00]
|
||||
params.planewave_attenuation = 1.0
|
||||
params.inner_potential = model['V0']
|
||||
params.work_function = 3.6
|
||||
params.symmetry_range = 360.0
|
||||
params.polar_incidence_angle = 60.0
|
||||
params.azimuthal_incidence_angle = 0.0
|
||||
params.vibration_model = "P"
|
||||
params.substrate_atomic_mass = 58.69
|
||||
params.experiment_temperature = 300.0
|
||||
params.debye_temperature = 356.0
|
||||
params.debye_wavevector = 1.7558
|
||||
params.rme_minus_value = 0.0
|
||||
params.rme_minus_shift = 0.0
|
||||
params.rme_plus_value = 1.0
|
||||
params.rme_plus_shift = 0.0
|
||||
# used by EDAC only
|
||||
params.emitters = []
|
||||
params.lmax = 15
|
||||
params.dmax = 5.0
|
||||
params.orders = [25]
|
||||
|
||||
return params
|
||||
|
||||
def create_domain(self):
|
||||
"""
|
||||
define the domain of the optimization parameters.
|
||||
"""
|
||||
dom = mp.Domain()
|
||||
|
||||
if self.mode == "single":
|
||||
dom.add_param('dNNi', 2.109, 2.000, 2.250, 0.050)
|
||||
dom.add_param('pNNi', 15.000, 0.000, 30.000, 1.000)
|
||||
dom.add_param('V0', 21.966, 15.000, 25.000, 1.000)
|
||||
dom.add_param('Zsurf', 1.449, 0.500, 2.000, 0.250)
|
||||
elif self.mode == "swarm":
|
||||
dom.add_param('dNNi', 2.109, 2.000, 2.250, 0.050)
|
||||
dom.add_param('pNNi', 15.000, 0.000, 30.000, 1.000)
|
||||
dom.add_param('V0', 21.966, 15.000, 25.000, 1.000)
|
||||
dom.add_param('Zsurf', 1.449, 0.500, 2.000, 0.250)
|
||||
elif self.mode == "grid":
|
||||
dom.add_param('dNNi', 2.109, 2.000, 2.250, 0.050)
|
||||
dom.add_param('pNNi', 15.000, 0.000, 30.000, 1.000)
|
||||
dom.add_param('V0', 21.966, 15.000, 25.000, 1.000)
|
||||
dom.add_param('Zsurf', 1.449, 0.500, 2.000, 0.250)
|
||||
else:
|
||||
dom.add_param('dNNi', 2.109, 2.000, 2.250, 0.050)
|
||||
dom.add_param('pNNi', 15.000, 0.000, 30.000, 1.000)
|
||||
dom.add_param('V0', 21.966, 15.000, 25.000, 1.000)
|
||||
dom.add_param('Zsurf', 1.449, 0.500, 2.000, 0.250)
|
||||
|
||||
return dom
|
||||
|
||||
|
||||
def create_project():
|
||||
"""
|
||||
create a new TwoatomProject calculation project.
|
||||
|
||||
the default experimental data file is @c twoatom_hemi_scan_250e.etpi
|
||||
in the same directory as this Python module.
|
||||
it defines a classic hemispherical angle scan grid
|
||||
but does not include measured data for optimization.
|
||||
|
||||
@return project instance.
|
||||
"""
|
||||
|
||||
project = TwoatomProject()
|
||||
|
||||
project_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
project.data_dir = project_dir
|
||||
|
||||
# scan dictionary
|
||||
# to select any number of scans, add their dictionary keys as scans option on the command line
|
||||
project.scan_dict['ea'] = {'filename': os.path.join(project_dir, "twoatom_energy_alpha.etpai"),
|
||||
'emitter': "N", 'initial_state': "1s"}
|
||||
project.scan_dict['et0p'] = {'filename': os.path.join(project_dir, "twoatom_energy_theta_0p.etpi"),
|
||||
'emitter': "N", 'initial_state': "1s"}
|
||||
project.scan_dict['et180p'] = {'filename': os.path.join(project_dir, "twoatom_energy_theta_180p.etpi"),
|
||||
'emitter': "N", 'initial_state': "1s"}
|
||||
project.scan_dict['tp215e'] = {'filename': os.path.join(project_dir, "twoatom_hemi_215e.etpi"),
|
||||
'emitter': "N", 'initial_state': "1s"}
|
||||
project.scan_dict['tp250e'] = {'filename': os.path.join(project_dir, "twoatom_hemi_250e.etpi"),
|
||||
'emitter': "N", 'initial_state': "1s"}
|
||||
|
||||
return project
|
||||
|
||||
|
||||
def set_project_args(project, project_args):
|
||||
"""
|
||||
set the project-specific arguments.
|
||||
|
||||
@param project: project instance
|
||||
|
||||
@param project_args: (Namespace object) project arguments.
|
||||
"""
|
||||
|
||||
scans = ['tp250e']
|
||||
try:
|
||||
if project_args.scans:
|
||||
scans = project_args.scans
|
||||
else:
|
||||
logger.warning(BMsg("missing scan argument, using {0}", scans[0]))
|
||||
except AttributeError:
|
||||
logger.warning(BMsg("missing scan argument, using {0}", scans[0]))
|
||||
|
||||
for scan_key in scans:
|
||||
scan_spec = project.scan_dict[scan_key]
|
||||
project.add_scan(**scan_spec)
|
||||
logger.info(BMsg("add scan {filename} ({emitter} {initial_state})", **scan_spec))
|
||||
|
||||
project.add_symmetry({'default': 0.0})
|
||||
|
||||
|
||||
def parse_project_args(_args):
|
||||
"""
|
||||
parse project-specific command line arguments.
|
||||
|
||||
@param _args: list of project-specific arguments from the command line.
|
||||
this is typically the unknown_args return value from argparse.ArgumentParser.parse_known_args().
|
||||
|
||||
@return: namespace object containing the specified arguments as attributes.
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# main arguments
|
||||
parser.add_argument('-s', '--scans', nargs="*", default=['tp250e'],
|
||||
help="nick names of scans to use in calculation (see create_project function)")
|
||||
|
||||
parsed_args = parser.parse_args(_args)
|
||||
|
||||
return parsed_args
|
||||
|
||||
|
||||
def main():
|
||||
args, unknown_args = pmsco.pmsco.parse_cli()
|
||||
if unknown_args:
|
||||
project_args = parse_project_args(unknown_args)
|
||||
else:
|
||||
project_args = None
|
||||
|
||||
project = create_project()
|
||||
pmsco.pmsco.set_common_args(project, args)
|
||||
set_project_args(project, project_args)
|
||||
pmsco.pmsco.run_project(project)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
sys.exit(0)
|
36019
projects/twoatom/twoatom_energy_alpha.etpai
Normal file
36019
projects/twoatom/twoatom_energy_alpha.etpai
Normal file
File diff suppressed because it is too large
Load Diff
36019
projects/twoatom/twoatom_energy_theta_0p.etpi
Normal file
36019
projects/twoatom/twoatom_energy_theta_0p.etpi
Normal file
File diff suppressed because it is too large
Load Diff
36019
projects/twoatom/twoatom_energy_theta_180p.etpi
Normal file
36019
projects/twoatom/twoatom_energy_theta_180p.etpi
Normal file
File diff suppressed because it is too large
Load Diff
16376
projects/twoatom/twoatom_hemi_215e.etpi
Normal file
16376
projects/twoatom/twoatom_hemi_215e.etpi
Normal file
File diff suppressed because it is too large
Load Diff
16376
projects/twoatom/twoatom_hemi_250e.etpi
Normal file
16376
projects/twoatom/twoatom_hemi_250e.etpi
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user