""" @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