116 lines
4.6 KiB
Python

"""
@package pmsco.msc_calculator
Kaduwela MSC program interface.
This module is currently not maintained.
@author Matthias Muntwiler
@copyright (c) 2015 by Paul Scherrer Institut @n
Licensed under the Apache License, Version 2.0 (the "License"); @n
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import pmsco.calculators.calculator as calculator
import pmsco.data as md
import pmsco.msc.msc as msc
import logging
logger = logging.getLogger(__name__)
class MscCalculator(calculator.Calculator):
def write_input_file(self, params, filepath):
with open(filepath, "w") as f:
f.write(" %s\n" % (params.title) )
f.write(" %s\n" % (params.comment) )
l_init = "spdf".index(params.initial_state[1])
f.write(" %4u\n" % (l_init) )
f.write(" %4u\n" % (params.spherical_order) )
f.write(" %s\n" % (params.polarization) )
f.write(" %4u\n" % (params.scattering_level) )
f.write(" %7.2f%7.2f\n" % (params.fcut, params.cut) )
f.write(" %12.6f\n" % (params.angular_resolution) )
f.write(" %12.6f\n" % (params.lattice_constant) )
f.write(" %12.6f\n" % (params.z_surface) )
f.write(" %4u\n" % (params.atom_types) )
for iat in range(params.atom_types):
f.write(" %4u %s\n" % (params.atomic_number[iat], "..."))
f.write(" %4u %s\n" % (params.atomic_number[iat], params.phase_file[iat]))
f.write(" %12.6f\n" % (params.msq_displacement[iat]) )
f.write(" %12.6f\n" % (params.planewave_attenuation) )
f.write(" %12.6f\n" % (params.inner_potential) )
f.write(" %12.6f\n" % (params.symmetry_range) )
f.write(" %12.6f\n" % (params.polar_incidence_angle) )
f.write(" %12.6f\n" % (params.azimuthal_incidence_angle) )
f.write(" %s\n" % (params.vibration_model) )
f.write(" %12.6f\n" % (params.substrate_atomic_mass) )
f.write(" %12.6f\n" % (params.experiment_temperature) )
f.write(" %12.6f\n" % (params.debye_temperature) )
f.write(" %12.6f\n" % (params.debye_wavevector) )
f.write(" %12.6f%7.3f\n" % (params.rme_minus_value, params.rme_minus_shift) )
f.write(" %12.6f%7.3f\n" % (params.rme_plus_value, params.rme_plus_shift) )
f.write(" %4u\n" % (1) )
f.write(" %4u %12.6f\n" % (1, 1.0) )
def run(self, params, cluster, scan, output_file):
"""
run the MSC program with the given parameters and cluster.
@param params: a project.CalculatorParams() object with all necessary values except cluster and output files set.
@param cluster: a cluster.Cluster(format=FMT_MSC) object with all atom positions set.
@param scan: a project.Scan() object with all relevant parameters set.
in particular, a scan file is required.
@param output_file: base name for all intermediate and output files
@return: result_file, files_cats
the scan file must be in ETP(IS) format:
* column 0: kinetic energy in eV
* column 1: polar angle in degrees
* column 2: azimuthal angle in degrees
* further columns are ignored
"""
# generate file names
base_filename = output_file
clu_filename = base_filename + ".clu"
out_filename = base_filename + ".list"
par_filename = base_filename + ".par"
dat_filename = base_filename + ".plt1"
etpi_filename = base_filename + ".etpi"
# fix MSC particularities
# singularity at theta == polar_incidence_angle
if params.polar_incidence_angle == 60.0:
params.polar_incidence_angle += 0.1
# save parameter files
cluster.save_to_file(clu_filename)
self.write_input_file(params, par_filename)
if logger.isEnabledFor(logging.INFO):
options = "11"
else:
options = "00"
revision = ""
# run MSC
msc.mscmain(par_filename, clu_filename, scan.filename, base_filename, revision, options)
# load results
result_etpi = md.load_plt(dat_filename)
md.save_data(etpi_filename, result_etpi)
files = {clu_filename: 'input', par_filename: 'input', dat_filename: 'output', base_filename: 'log',
out_filename: 'log', etpi_filename: 'energy'}
return etpi_filename, files