From 88436fabdf885dbec46f5c633e5dbcb4706f7482 Mon Sep 17 00:00:00 2001 From: Sylvain Tricot Date: Thu, 3 Mar 2022 18:42:55 +0100 Subject: [PATCH] Added python support for writing input file. --- src/Makefile | 74 +++-- src/fortran/_dfm.f90 | 8 +- src/python/msspec_dfm/cli.py | 48 ++- src/python/msspec_dfm/input_file.py | 492 ++++++++++++++++++++++++++++ src/python/msspec_dfm/plotting.py | 172 ++++++++++ 5 files changed, 764 insertions(+), 30 deletions(-) create mode 100644 src/python/msspec_dfm/input_file.py create mode 100644 src/python/msspec_dfm/plotting.py diff --git a/src/Makefile b/src/Makefile index 36e6daf..aa8943f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,10 +37,6 @@ AUTHORS = Didier Sébilleau , \ # CORE CONFIGURATION # ################################################################################ SHELL = bash -PYTHON_PKG_NAME = msspec_dfm -VERSION = $(shell cd python && python -c 'from $(PYTHON_PKG_NAME) import __version__; print(__version__)') -SRCDIR = fortran/DFM_library -PYPKG = python/$(PYTHON_PKG_NAME) ifeq ($(DEBUG),0) FFLAGS = @@ -48,13 +44,41 @@ else FFLAGS = -g -fbounds-check -fbacktrace -ffpe-trap=zero,overflow,underflow,invalid,denormal endif -# Use f2py of the virtualenv if possible +# Make sure to use binaries of the of the virtualenv ifdef VIRTUAL_ENV + PYTHON = $(VIRTUAL_ENV)/bin/python F2PY = $(VIRTUAL_ENV)/bin/f2py + PIP = $(VIRTUAL_ENV)/bin/pip else + PYTHON = $(shell which python) F2PY = $(shell which f2py) + PIP = $(shell which pip) endif -F2PY += --f77exec=$(FC) --f90exec=$(FC) +F2PYFLAGS = --f77exec=$(FC) --f90exec=$(FC) + + +# Ensure FC exists +ifeq (,$(shell which $(FC))) + $(error Missing $(FC) compiler) +endif + +# Ensure python exists +ifeq (,$(shell which $(PYTHON))) + $(error Missing Python executable) +endif + +# Ensure pip is installed +ifeq (,$(shell which $(PIP))) + $(error pip was not found) +endif + + + +PYTHON_PKG_NAME = msspec_dfm +VERSION = $(shell cd python && $(PYTHON) -c 'from $(PYTHON_PKG_NAME) import __version__; print(__version__)') +SRCDIR = fortran/DFM_library +PYPKG = python/$(PYTHON_PKG_NAME) + # Source files MANPAGE := man/eps.1 @@ -240,37 +264,44 @@ SRCS:=$(read_SRCS) $(io_SRCS) $(calc_DEPS) $(calc_SRCS) $(calc_TEST) $(calc_POST OBJS:=$(addprefix $(BUILDDIR)/,$(patsubst %.f90,%.o,$(SRCS))) -.PHONY: all obj so pypkg install uninstall man clean help +.PHONY: all obj so pypkg required_python_packages install uninstall man clean help -all: so +all: required_python_packages so + obj: $(OBJS) + so: python/$(PYTHON_PKG_NAME)/$(SO) + pypkg: python/dist/$(PYTHON_PKG_NAME)-$(VERSION).tar.gz +required_python_packages: + @$(PIP) install numpy click-man + + python/VERSION: @cat $(VERSION) > $@ install: python/dist/$(PYTHON_PKG_NAME)-$(VERSION).tar.gz @echo "Installing $^" - @pip install $^ + @$(PIP) install $^ python/dist/$(PYTHON_PKG_NAME)-$(VERSION).tar.gz: python/$(PYTHON_PKG_NAME)/$(SO) python/dist/$(PYTHON_PKG_NAME)-$(VERSION).tar.gz: man python/dist/$(PYTHON_PKG_NAME)-$(VERSION).tar.gz: python/MANIFEST.in python/setup.py python/pip.freeze $(shell find python/$(PYTHON_PKG_NAME) -name '*.py') - @cd python && python setup.py sdist + @cd python && $(PYTHON) setup.py sdist python/$(PYTHON_PKG_NAME)/$(SO): $(OBJS) $(SRCDIR)/../_dfm.f90 @echo "Building $@ shared object..." @mkdir -p $(BUILDDIR) - @$(F2PY) -I$(BUILDDIR) -m $(BUILDDIR).$(basename $(@F)) -c $(filter-out $(lastword $^), $^) $(SRCDIR)/../_dfm.f90 && mv $(BUILDDIR)/*.so $@ + @$(F2PY) $(F2PYFLAGS) -I$(BUILDDIR) -m $(BUILDDIR).$(basename $(@F)) -c $(filter-out $(lastword $^), $^) $(SRCDIR)/../_dfm.f90 && mv $(BUILDDIR)/*.so $@ $(BUILDDIR)/%.o: %.f90 @@ -280,30 +311,25 @@ $(BUILDDIR)/%.o: %.f90 man: python/man/inputfile.spec - @cd python && python setup.py --command-packages=click_man.commands man_pages --target ./man/pages + @cd python && $(PYTHON) setup.py --command-packages=click_man.commands man_pages --target ./man/pages @cd python/man/pages && cat ../inputfile.spec >> *-generate.1 @cd python/man/pages && echo -e ".SH AUTHORS\n.PP\n$(AUTHORS)" | tee -a *.1 > /dev/null @cd python/man/pages && gzip -f *.1 uninstall: - @pip uninstall -y $(PYTHON_PKG_NAME) + @$(PIP) uninstall -y $(PYTHON_PKG_NAME) clean: - @rm -rf $(BUILDDIR) - @rm -f python/$(PYTHON_PKG_NAME)/*.so - @rm -rf python/dist - @rm -rf python/*.egg-info - @rm -f python/VERSION + @rm -rf $(BUILDDIR) + @rm -f python/$(PYTHON_PKG_NAME)/*.so + @rm -rf python/dist + @rm -rf python/*.egg-info + @rm -f python/VERSION @rm -rf python/man/pages help: - @echo "Type 'make' or 'make all' to build the executable and the Python shared library" + @echo "Type 'make' or 'make all' to build." @echo "Type 'make install' to install the code." - @echo "By default, this installation is located in $(PREFIX)." - @echo "The installation prefix can be changed with the 'PREFIX' variable" - @echo "It is also possible to add debugging symbols with the 'DEBUG' variable." - @echo "For example, to install in another (writable) location with debugging options:" - @echo " make DEBUG=1 && make install PREFIX=/opt" diff --git a/src/fortran/_dfm.f90 b/src/fortran/_dfm.f90 index be2c825..d895b3a 100644 --- a/src/fortran/_dfm.f90 +++ b/src/fortran/_dfm.f90 @@ -110,8 +110,8 @@ SUBROUTINE EPSILON(MYINFILE, MYOUTDIR) CHARACTER (LEN = 100) :: INPDATA(999) CHARACTER (LEN = 100) :: LOGFILE(999) ! - CHARACTER (LEN = 100) :: MYINFILE - CHARACTER (LEN = 100) :: MYOUTDIR + CHARACTER (LEN = 100) :: MYINFILE + CHARACTER (LEN = 80) :: MYOUTDIR ! OUTDIR = MYOUTDIR CALL SYSTEM('mkdir -p '//TRIM(OUTDIR)) @@ -339,7 +339,7 @@ SUBROUTINE EPSILON(MYINFILE, MYOUTDIR) ! Formats: ! 10 FORMAT(' ') - 15 FORMAT(I3) - 25 FORMAT(A50) +! 15 FORMAT(I3) +! 25 FORMAT(A50) ! END SUBROUTINE diff --git a/src/python/msspec_dfm/cli.py b/src/python/msspec_dfm/cli.py index 3eb99e3..f9d03f0 100644 --- a/src/python/msspec_dfm/cli.py +++ b/src/python/msspec_dfm/cli.py @@ -22,8 +22,11 @@ import click import logging +import os +from msspec_dfm.input_file import InputFile from msspec_dfm.version import __version__ from msspec_dfm.eps import epsilon +from msspec_dfm import plotting @click.group(invoke_without_command=True, no_args_is_help=True) @click.option('--version', is_flag=True, @@ -52,7 +55,9 @@ def generate(input_file): An input file with default parameters will be written to INPUT_FILE. """ logging.debug("Generating the input file \'{:s}\'...".format(input_file)) - print(input_file) + input_data = InputFile(input_file) + input_data.write() + logging.info("Input file with default values generated in: {}".format(input_file)) @main.command() @@ -67,9 +72,10 @@ def compute(input_file, folder): See help of the 'generate' command for a full reference of the file format and all the options. """ - logging.debug("Computing...") + logging.info("Computing...") logging.debug(" Input file : \'{:s}\'".format(input_file)) logging.debug(" Output folder: \'{:s}\'".format(folder)) + epsilon(input_file, folder) @main.command() @@ -115,6 +121,44 @@ def plot(plot_type, folder, img, bounds, plot3d, contour, pdeh, levels, Ef, stri logging.debug("Plotting...") for key, value in locals().items(): logging.debug(" {}: {}".format(key, value)) + + # data = plotting.Data(os.path.join(folder, plot_type + ".dat")) + # data.load(imag=img) + + # pw = plotting.PlotWindow3d(data) + # pw.plot() + # pw.show() + + # start by loading data + df_file = os.path.join(folder, 'diel_func.dat') + pd_file = os.path.join(folder, 'plas_disp.dat') + eh_file = os.path.join(folder, 'elec_hole.dat') + X, Y, ReZ, ImZ, pd, eh = plotting.load_data(df_file, pd_file, eh_file) + + vmin, vmax = bounds + Z = ReZ + if img: + Z = ImZ + + fig = ax = None + + if not(plot3d): + fig, ax = plotting.plot_2d(X, Y, Z, cmap=plotting.cmap, vmin=vmin, vmax=vmax, fig=fig, ax=ax) + else: + fig, ax = plotting.plot_3d(X, Y, Z, cmap=plotting.cmap, vmin=vmin, vmax=vmax, fig=fig, ax=ax, strides=strides) + + if contour: + fig, ax = plotting.plot_contour(X, Y, ReZ, levels=levels, vmin=vmin, vmax=vmax, + cmap=None, colors='black', fig=fig, ax=ax) + + if pdeh: + fig, ax = plotting.plot_pdeh(pd, eh, Ef=Ef, fig=fig, ax=ax) + + plotting.entitle(fig, ax, img=img) + plotting.plt.show() + + + if __name__ == '__main__': main() diff --git a/src/python/msspec_dfm/input_file.py b/src/python/msspec_dfm/input_file.py new file mode 100644 index 0000000..085cbda --- /dev/null +++ b/src/python/msspec_dfm/input_file.py @@ -0,0 +1,492 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# Copyright © 2022 - Rennes Physics Institute +# +# This file is part of MsSpec-DFM. +# +# MsSpec-DFM is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# MsSpec-DFM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with MsSpec-DFM. If not, see . +# +# Source file : src/python/msspec_dfm/version.py +# Last modified: Fri, 25 Feb 2022 17:27:32 +0100 +# Committed by : Sylvain Tricot 1645806435 +0100 + +import os + +class InputFile: + defaults = { + # GENERAL PARAMETERS + # (q, omega, r) + 'Q_MIN' : (0.010, '13.3f'), + 'Q_MAX' : (4.000, '13.3f'), + 'N_Q' : (1000, '10d'), + 'E_MIN' : (0.010, '13.3f'), + 'E_MAX' : (4.000, '13.3f'), + 'N_E' : (2000, '10d'), + 'R_MIN' : (0.010, '13.3f'), + 'R_MAX' : (4.000, '13.3f'), + 'N_R' : (2000, '>10d'), + # Material's properties + 'RS' : (2.079, '13.3f'), + 'MSOM' : (1.000, '13.3f'), + 'MAT_TYP' : ('SCHRO', '>10s'), + 'EPS_B' : (1.000, '13.3f'), + # External fields + 'T' : (1.00, '12.2f'), + 'E' : (0.000, '13.3f'), + 'H' : (0.000, '13.3f'), + 'FLD' : ('NO', '>10s'), + # System's dimension + 'DIM' : ('3D', '>10s'), + # Confinement + 'R0' : (0.000, '13.3f'), + 'L' : (0.000, '13.3f'), + 'OM0' : (0.00, '12.2f'), + 'CONFIN' : ('NO-CONF', '>10s'), + # Multilayer structure + 'DL' : (0.000, '13.3f'), + 'D1' : (0.000, '13.3f'), + 'N_DEP' : (0.00, '12.2f'), + 'N_INV' : (0.00, '12.2f'), + 'H_TYPE' : ('NONE', '>10s'), + 'EPS_1' : (12.000, '13.3f'), + 'EPS_2' : (12.000, '13.3f'), + # Units + 'UNIT' : ('SIU', '>10s'), + 'UNIK' : ('SI', '>10s'), + # Screening + 'SC_TYPE' : ('NO', '>10s'), + # Plasma type + 'PL_TYPE' : ('OCP', '>10s'), + 'ZION' : (1.000, '13.3f'), + 'ZION2' : (0.000, '13.3f'), + # Calculation type + 'CAL_TYPE' : ('QUANTUM', '>10s'), + # DIELECTRIC FUNCTION + 'ESTDY' : ('DYNAMIC', '>10s'), + 'EPS_T' : ('LONG', '>10s'), + 'D_FUNC' : ('NEV3', '>10s'), + 'I_T' : (0, '>10d'), + 'NEV_TYPE' : ('STA2', '>10s'), + 'MEM_TYPE' : ('COCO', '>10s'), + 'ALPHA' : (0.500, '13.3f'), + 'BETA' : (0.600, '13.3f'), + # Analytical plasmon dispersion + 'PL_DISP' : ('RP2_MOD', '>10s'), + # Local-field corrections + 'GSTDY' : ('STATIC', '>10s'), + 'GQ_TYPE' : ('ICUT', '>10s'), + 'IQ_TYPE' : ('IKP', '>10s'), + 'LANDAU' : ('NONE', '>10s'), + 'GQO_TYPE' : ('NONE', '>10s'), + 'G0_TYPE' : ('EC', '>10s'), + 'GI_TYPE' : ('EC', '>10s'), + # Damping + 'DAMPING' : ('RELA', '>10s'), + 'LT_TYPE' : ('NONE', '>10s'), + 'RT_TYPE' : ('EX1', '>10s'), + 'DR_TYPE' : ('NONE', '>10s'), + 'DC_TYPE' : ('EXTE', '>10s'), + 'VI_TYPE' : ('NONE', '>10s'), + 'EE_TYPE' : ('NONE', '>10s'), + 'EP_TYPE' : ('NONE', '>10s'), + 'EI_TYPE' : ('NONE', '>10s'), + 'IP_TYPE' : ('NONE', '>10s'), + 'PD_TYPE' : ('NONE', '>10s'), + 'QD_TYPE' : ('LORE', '>10s'), + 'ZETA' : (1.250, '13.3f'), + 'D_VALUE_1': (0.500, '13.3f'), + 'POWER_1' : ('FEMTO', '>10s'), + 'EK' : (50.00, '12.2f'), + 'D_VALUE_2': (5.000, '13.3f'), + 'POWER_2' : ('FEMTO', '>10s'), + 'PCT' : (0.80, '12.2f'), + # Electron-electron interaction + 'INT_POT' : ('COULO', '>10s'), + 'S' : (2.590, '13.3f'), + 'EPS' : (470.000, '13.3f'), + 'DELTA' : (1.500, '13.3f'), + 'RC' : (1.500, '13.3f'), + 'ALF' : (5.000, '13.3f'), + 'M' : (7, '10d'), + 'N' : (28, '10d'), + 'A1' : (1.000, '13.3f'), + 'A2' : (1.000, '13.3f'), + 'A3' : (1.000, '13.3f'), + 'A4' : (1.000, '13.3f'), + # Electron-phonon interaction + 'EP_C' : (1500.000, '13.3f'), + 'DEBYE_T' : (1500.000, '13.3f'), + 'NA' : (12.000, '13.3f'), + 'MA' : (0.000, '13.3f'), + 'RA' : (0.000, '13.3f'), + # Electron-impurity interaction + 'NI' : (0.000, '13.3f'), + 'EI_C' : (0.000, '13.3f'), + # Classical fluid parameters + 'CF_TYPE' : ('SHS', '>10s'), + 'PF_TYPE' : ('HSM', '>10s'), + 'SL_TYPE' : ('HSP', '>10s'), + # STRUCTURE FACTOR + 'SSTDY' : ('DYNAMIC', '>10s'), + 'SQ_TYPE' : ('PKA', '>10s'), + 'SQO_TYPE' : ('EPS', '>10s'), + # PAIR CORRELATION FUNCTION + 'GR_TYPE' : ('SHA', '>10s'), + 'GR0_MODE' : ('KIMB', '>10s'), + # PAIR DISTRIBUTION FUNCTION + 'RH_TYPE' : ('CEG', '>10s'), + # SPECTRAL FUNCTION + 'SPF_TYPE' : ('NAIC', '>10s'), + # ENERGY CALCULATIONS + 'EC_TYPE' : ('GGSB_G', '>10s'), + 'FXC_TYPE' : ('NO', '>10s'), + 'EXC_TYPE' : ('NO', '>10s'), + 'EX_TYPE' : ('HEG', '>10s'), + 'EK_TYPE' : ('HEG', '>10s'), + # SPIN POLARIZATION + 'IMODE' : (1, '10d'), + 'XI' : (0.000, '13.3f'), + # THERMODYNAMIC PROPERTIES + 'TH_PROP' : ('QUAN', '>10s'), + 'GP_TYPE' : ('IK0', '>10s'), + # ELECTRON MEAN FREE PATH + 'EK_INI' : (150.00, '12.2f'), + 'EK_FIN' : (200.00, '12.2f'), + # CALCULATIONS OF MOMENTS + 'N_M' : (1, '10d'), + 'M_TYPE' : ('SQO', '>10s'), + # INCOMING ION BEAM + 'Z_BEAM' : (1.00, '12.2f'), + 'EK_BEAM' : (15000.00, '12.2f'), + # OUTPUT CALCULATIONS/PRINTING + 'I_DF' : (1, '10d'), + 'I_PZ' : (0, '10d'), + 'I_SU' : (0, '10d'), + 'I_CD' : (0, '10d'), + 'I_PD' : (1, '10d'), + 'I_EH' : (1, '10d'), + 'I_E2' : (0, '10d'), + 'I_CK' : (0, '10d'), + 'I_CR' : (0, '10d'), + 'I_PK' : (0, '10d'), + 'I_LF' : (0, '10d'), + 'I_IQ' : (0, '10d'), + 'I_SF' : (0, '10d'), + 'I_PC' : (0, '10d'), + 'I_P2' : (0, '10d'), + 'I_VX' : (0, '10d'), + 'I_DC' : (0, '10d'), + 'I_MD' : (0, '10d'), + 'I_LD' : (0, '10d'), + 'I_DP' : (0, '10d'), + 'I_LT' : (0, '10d'), + 'I_BR' : (0, '10d'), + 'I_PE' : (0, '10d'), + 'I_QC' : (0, '10d'), + 'I_RL' : (0, '10d'), + 'I_KS' : (0, '10d'), + 'I_OQ' : (0, '10d'), + 'I_ME' : (0, '10d'), + 'I_MS' : (0, '10d'), + 'I_ML' : (0, '10d'), + 'I_MC' : (0, '10d'), + 'I_DE' : (0, '10d'), + 'I_ZE' : (0, '10d'), + 'I_SR' : (0, '10d'), + 'I_CW' : (0, '10d'), + 'I_CF' : (0, '10d'), + 'I_EM' : (0, '10d'), + 'I_MF' : (0, '10d'), + 'I_SP' : (0, '10d'), + 'I_SE' : (0, '10d'), + 'I_SB' : (0, '10d'), + 'I_ES' : (0, '10d'), + 'I_GR' : (0, '10d'), + 'I_FD' : (0, '10d'), + 'I_BE' : (0, '10d'), + 'I_MX' : (0, '10d'), + 'I_SC' : (0, '10d'), + 'I_DS' : (0, '10d'), + 'I_NV' : (0, '10d'), + 'I_MT' : (0, '10d'), + 'I_GP' : (0, '10d'), + 'I_PR' : (0, '10d'), + 'I_CO' : (0, '10d'), + 'I_CP' : (0, '10d'), + 'I_BM' : (0, '10d'), + 'I_SH' : (0, '10d'), + 'I_S0' : (0, '10d'), + 'I_S1' : (0, '10d'), + 'I_DT' : (0, '10d'), + 'I_PS' : (0, '10d'), + 'I_IE' : (0, '10d'), + 'I_EI' : (0, '10d'), + 'I_FH' : (0, '10d'), + 'I_EY' : (0, '10d'), + 'I_EF' : (1, '10d'), + 'I_KF' : (1, '10d'), + 'I_VF' : (1, '10d'), + 'I_TE' : (1, '10d'), + 'I_DL' : (1, '10d'), + 'I_TW' : (0, '10d'), + 'I_VT' : (0, '10d'), + 'I_TC' : (0, '10d'), + 'I_EG' : (0, '10d'), + 'I_EX' : (0, '10d'), + 'I_XC' : (0, '10d'), + 'I_EC' : (0, '10d'), + 'I_HF' : (0, '10d'), + 'I_EK' : (0, '10d'), + 'I_EP' : (0, '10d'), + 'I_VI' : (0, '10d'), + 'I_DI' : (0, '10d'), + 'I_FP' : (0, '10d'), + 'I_EL' : (0, '10d'), + 'I_PO' : (0, '10d'), + 'I_RF' : (0, '10d'), + 'I_VC' : (0, '10d'), + 'I_FN' : (0, '10d'), + 'I_WR' : (2, '10d'), + 'I_TI' : (0, '10d'), + } + + def __init__(self, filename): + self.filename = filename + + + def _stack(self, *keys, comments=""): + params = [] + for key in keys: + value, fmt = self.defaults[key] + params.append((key, value, fmt)) + line = [' ',] * 49 + labels = [] + for i, (label, value, fmt) in enumerate(params): + labels.append(label) + fmts = ' ' * (10 * i) + '{{:{}}}'.format(fmt) + line_ = fmts.format(value) + for ichar, char in enumerate(line_): + if char != ' ': + line[ichar] = char + + # add labels + labels = list(','.join(labels)) + line += labels + + # Pad with spaces if needed + line += ' ' * max(78 - len(line), 0) + + # Add stars + line[1] = '*' + line += '*' + + # Add comments + line += comments + + # Add CR + line += '\n' + + return ''.join(line) + + + def write(self, **kwargs): + content = "" + content += " ******************************************************************************\n" + content += " * MsSpec DIELECTRIC FUNCTION MODULE *\n" + content += " ******************************************************************************\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * GENERAL PARAMETERS : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * (q,omega,r) : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('Q_MIN', 'Q_MAX', 'N_Q', comments=" in units of k_F") + content += self._stack('E_MIN', 'E_MAX', 'N_E', comments=" in units of E_F") + content += self._stack('R_MIN', 'R_MAX', 'N_R', comments=" in units of 1/k_F") + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Material's properties : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('RS', 'MSOM', 'MAT_TYP', 'EPS_B') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * External fields : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('T', 'E', 'H', 'FLD') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * System's dimension : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('DIM') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Confinement : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('R0', 'L', 'OM0', 'CONFIN') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Multilayer structure : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('DL', 'D1', 'N_DEP', 'N_INV', comments=" --- EPS_1 ---") + content += self._stack('H_TYPE', 'EPS_1', 'EPS_2', comments=" EPS_2") + content += " *-------+---------+---------+---------+---------+----------------------------* --- EPS_1 ---\n" + content += " * Units : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('UNIT', 'UNIK') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Screening : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('SC_TYPE') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Plasma type : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('PL_TYPE', 'ZION', 'ZION2') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Calculation type : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('CAL_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * DIELECTRIC FUNCTION : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('ESTDY', 'EPS_T', 'D_FUNC', 'I_T') + content += self._stack('NEV_TYPE', 'MEM_TYPE', 'ALPHA', 'BETA') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Analytical plasmon dispersion : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('PL_DISP') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Local-field corrections *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('GSTDY', 'GQ_TYPE', 'IQ_TYPE') + content += self._stack('LANDAU', 'GQO_TYPE', 'G0_TYPE', 'GI_TYPE') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Damping : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('DAMPING', 'LT_TYPE', 'RT_TYPE') + content += self._stack('DR_TYPE', 'DC_TYPE', 'VI_TYPE') + content += self._stack('EE_TYPE', 'EP_TYPE', 'EI_TYPE') + content += self._stack('IP_TYPE', 'PD_TYPE', 'QD_TYPE', 'ZETA') + content += self._stack('D_VALUE_1', 'POWER_1', 'EK') + content += self._stack('D_VALUE_2', 'POWER_2', 'PCT') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Electron-electron interaction : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('INT_POT','S','EPS','DELTA') + content += self._stack('RC','ALF','M','N') + content += self._stack('A1','A2','A3','A4') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Electron-phonon interaction : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('EP_C','DEBYE_T') + content += self._stack('NA','MA','RA') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Electron-impurity interaction : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('NI','EI_C') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += " * Classical fluid parameters : *\n" + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('CF_TYPE','PF_TYPE','SL_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * STRUCTURE FACTOR : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('SSTDY','SQ_TYPE','SQO_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * PAIR CORRELATION FUNCTION : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('GR_TYPE','GR0_MODE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * PAIR DISTRIBUTION FUNCTION : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('RH_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * SPECTRAL FUNCTION : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('SPF_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * ENERGY CALCULATIONS : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('EC_TYPE','FXC_TYPE','EXC_TYPE') + content += self._stack('EX_TYPE','EK_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * SPIN POLARIZATION : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('IMODE','XI') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * THERMODYNAMIC PROPERTIES : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('TH_PROP','GP_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * ELECTRON MEAN FREE PATH : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('EK_INI','EK_FIN') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * CALCULATION OF MOMENTS : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('N_M','M_TYPE') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * INCOMING ION BEAM : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('Z_BEAM', 'EK_BEAM') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * OUTPUT CALCULATIONS/PRINTING : *\n" + content += " *=======+=========+=========+=========+=========+============================*\n" + content += self._stack('I_DF','I_PZ','I_SU','I_CD') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_PD','I_EH','I_E2','I_CK') + content += self._stack('I_CR','I_PK') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_LF','I_IQ','I_SF','I_PC') + content += self._stack('I_P2','I_VX','I_DC','I_MD') + content += self._stack('I_LD','I_DP','I_LT','I_BR') + content += self._stack('I_PE','I_QC','I_RL','I_KS') + content += self._stack('I_OQ','I_ME','I_MS','I_ML') + content += self._stack('I_MC','I_DE','I_ZE','I_SR') + content += self._stack('I_CW','I_CF','I_EM','I_MF') + content += self._stack('I_SP','I_SE','I_SB','I_ES') + content += self._stack('I_GR','I_FD','I_BE','I_MX') + content += self._stack('I_SC','I_DS','I_NV','I_MT') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_GP','I_PR','I_CO','I_CP') + content += self._stack('I_BM','I_SH','I_S0','I_S1') + content += self._stack('I_DT','I_PS','I_IE','I_EI') + content += self._stack('I_FH','I_EY') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_EF','I_KF','I_VF','I_TE') + content += self._stack('I_DL') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_TW','I_VT','I_TC') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_EG','I_EX','I_XC','I_EC') + content += self._stack('I_HF','I_EK','I_EP') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_VI','I_DI') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_FP','I_EL','I_PO','I_RF') + content += self._stack('I_VC') + content += " *-------+---------+---------+---------+---------+----------------------------*\n" + content += self._stack('I_FN','I_WR','I_TI') + content += " *=======+=========+=========+=========+=========+============================*\n" + content += " * INPUT FILES : *\n" + content += " *----------------------------------------------------------------------------*\n" + content += " * NAME UNIT TYPE *\n" + content += " *=======+======================+======+=========+============================*\n" + content += " * epsilon.dat 5 INPUT DATA FILE *\n" + content += " *=======+======================+======+=========+============================*\n" + content += " * OUTPUT FILES : *\n" + content += " *----------------------------------------------------------------------------*\n" + content += " * NAME UNIT TYPE *\n" + content += " *=======+======================+======+=========+============================*\n" + content += " * epsilon.lis 6 CHECK FILE *\n" + content += " *=======+======================+======+=========+============================*\n" + content += " * END OF THE DATA FILE *\n" + content += " *============================================================================*\n" + content += " ******************************************************************************\n" + + os.makedirs(os.path.dirname(self.filename), exist_ok=True) + with open(self.filename, 'w') as fd: + fd.write(content) diff --git a/src/python/msspec_dfm/plotting.py b/src/python/msspec_dfm/plotting.py new file mode 100644 index 0000000..e7972bb --- /dev/null +++ b/src/python/msspec_dfm/plotting.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# +# Copyright © 2020-2020 - Rennes Institute of Physics. +# +# This file is part of plotdf. +# +# plotdf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# plotdf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with plotdf. If not, see . +# +# Source file : src/old_plotdf.py +# Last modified: Tue, 27 Apr 2021 11:00:13 +0200 +# Committed by : Sylvain Tricot + +import sys + +try: + from matplotlib import pyplot as plt + from mpl_toolkits.mplot3d import Axes3D + from matplotlib import cm + from matplotlib.colorbar import Colorbar +except ImportError: + print('You need matplotlib to run this script!') + exit(-1) + +try: + import numpy as np +except ImportError: + print('You need NumPy to run this script!') + exit(-1) + +try: + import argparse +except ImportError as err: + print('Please, install the package \"{}\" to run that script.'.format(err.name)) + exit(-1) + +try: + import logging +except ImportError as err: + print('Please, install the package \"{}\" to run that script.'.format(err.name)) + exit(-1) + + + + + +# Choose diverging colormap +# (PiYG, PRGn, BrBG, PuOr, RdGy, RdBu, RdYlBu, RdYlGn, Spectral, coolwarm, bwr, seismic) + +# custom cmap +cmap = cm.bwr.from_list("custom_cmap", [ + (0.00, (.6, 0.8, 1.0)), + (0.48, (0.2, 0.2, .8)), + (0.50, (1, 1, 1)), + (0.52, (1., 0., 0.)), + (1.00, (1.0, 0.8, 0)), + ]) + +#cmap = cm.bwr + +def load_data(df='diel_func.dat', pd='plas_disp.dat', eh='elec_hole.dat'): + logging.info('loading data, please wait...') + # load data + logging.debug('loading {:s} file'.format(df)) + data = np.loadtxt(df) + logging.debug('loading {:s} file'.format(pd)) + pd = np.loadtxt(pd) + logging.debug('loading {:s} file'.format(eh)) + eh = np.loadtxt(eh) + + # convert to grid + logging.debug('Creating the grid') + x = np.unique(data[:,0]) + y = np.unique(data[:,1]) + + X, Y = np.meshgrid(x, y) + size = (len(x), len(y)) + ReZ = data[:,2].reshape(size).T + ImZ = data[:,3].reshape(size).T + + logging.debug('loading data done.') + + return X, Y, ReZ, ImZ, pd, eh + +def plot_2d(X, Y, Z, cmap, fig=None, ax=None, vmin=None, vmax=None): + # plotting + if fig is None: + fig = plt.figure() + if ax is None: + ax = fig.add_subplot(111) + + xmin, xmax, ymin, ymax = [np.min(X), np.max(X), np.min(Y), np.max(Y)] + extent = [xmin, xmax, ymin, ymax] + im = ax.imshow(Z, cmap=cmap, aspect='auto', origin='lower', vmin=vmin, vmax=vmax, extent=extent, + interpolation='bilinear') + ax.set_xlim(None, xmax) + ax.set_ylim(None, ymax) + + # colorbar + cb_val = np.linspace(vmin, vmax, 9, endpoint=True) + #cb_lbl = [f"{_:.1f}" for _ in cb_val] + cb_lbl = ["{:.1f}".format(_) for _ in cb_val] + cb_lbl[0] = "$\leq$ {:.1f}".format(cb_val[0]) + cb_lbl[-1] = "$\geq$ {:.1f}".format(cb_val[-1]) + cb = fig.colorbar(im, ax=ax, ticks=cb_val) + cb.ax.set_yticklabels(cb_lbl) + + return fig, ax + + +def plot_contour(X, Y, Z, colors='black', cmap=None, fig=None, ax=None, levels=8, + vmin=None, vmax=None): + # plotting + if fig is None: + fig = plt.figure() + if ax is None: + ax = fig.add_subplot(111) + + xmin, xmax, ymin, ymax = [np.min(X), np.max(X), np.min(Y), np.max(Y)] + extent = [xmin, xmax, ymin, ymax] + cset = ax.contour(X, Y, Z, zdir='z', levels=np.linspace(vmin,vmax,levels), offset=np.min(Z), + colors=colors, cmap=cmap) + ax.clabel(cset, cset.levels, inline=True, fontsize=10) + + ax.set_xlim(None, xmax) + ax.set_ylim(None, ymax) + + return fig, ax + + +# Plot the 3D surface +def plot_3d(X, Y, Z, cmap=None, fig=None, ax=None, vmin=None, vmax=None, strides=64): + # plotting + if fig is None: + fig = plt.figure() + if ax is None: + ax = fig.add_subplot(111, projection='3d') + ax.plot_surface(X, Y, Z, vmin=vmin, vmax=vmax, rstride=strides, cstride=strides, alpha=1., cmap=cmap) + + return fig, ax + + +def plot_pdeh(pd, eh, Ef=1, color='black', fig=None, ax=None): + # plotting + if fig is None: + fig = plt.figure() + if ax is None: + ax = fig.add_subplot(111) + + ax.plot(pd[:,0], pd[:,1], color=color, linestyle="--", label="Plasmon energy") + ax.plot(eh[:,0], eh[:,1]/Ef, color=color, linestyle=":", label=r"e-h pair continuum $\omega_+$") + ax.plot(eh[:,0], np.abs(eh[:,2]/Ef), color=color, linestyle="-.", label=r"e-h pair continuum $\omega_-$") + ax.legend() + + return fig, ax + + +def entitle(fig, ax, img=False): + title = r"$\Im(\epsilon)$" if img else r"$\Re(\epsilon)$" + ax.set_title(title) + ax.set_xlabel(r"$q/k_F$") + ax.set_ylabel(r"$E/E_F$")