116 lines
4.6 KiB
Python
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
|