Commit 2d9b8b1b authored by Michele Compostella's avatar Michele Compostella
Browse files

Initial commit

parents
#####################################################################################################
## Copyright (C) 2020 Udo von Toussaint, F. J. Dominguez-Gutierrez, Markus Rampp, Michele Compostella
## Max-Planck-Institut für Plasmaphysik, Boltzmannstrasse 2, 85748 Garching, Germany
## Max-Planck Computing and Data Facility, Giessenbachstrasse 2, 85748 Garching, Germany
##
## This program 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 2, or (at your option)
## any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
##
#####################################################################################################
##
## General Notes:
## Docker file for Fingerprinting and Visualizing defects in damaged crystal structures
## Version: 1.0
## This software provides a workflow for fingerprinting and visualizing defects in damaged crystal
## structures. The theoretical background is presented in: paper_ID
##
#####################################################################################################
# Importing Ubuntu image
FROM ubuntu:18.04
# Build arguments
ARG PREFIX
# Environment variables
ENV DEBIAN_FRONTEND noninteractive
ENV QUIP_ARCH linux_x86_64_gfortran
ENV QUIP_STRUCTS_DIR $PREFIX/QUIP/structs
ENV QUIP_INSTALLDIR $PREFIX/QUIP/bin
USER root
WORKDIR /root/
# Updating distro
RUN \
apt-get update && \
apt-get upgrade -y
# Installing basic packages
RUN \
apt-get install -y apt-utils unzip git cpio && \
apt-get install -y gcc gfortran libblas-dev liblapack-dev python python-pip python3 python3-pip ffmpeg imagemagick && \
apt-get install -y libsm6 libgl1 libgl1-mesa-dri libgl1-mesa-glx libpcre3-dev libxt6 && \
apt-get autoclean && \
apt-get autoremove
# Copying software source files
COPY ./software /tmp/software
# Creating installation folder
RUN mkdir -p $PREFIX
# Installing Python3 modules
RUN pip3 install numpy matplotlib vtk
RUN pip3 install mayavi
# Installing QUIP
RUN \
tar xvzf /tmp/software/QUIP.tar.gz -C $PREFIX/. && \
cd $PREFIX/QUIP/ && \
tar xvzf /tmp/software/GAP.tar.gz -C $PREFIX/QUIP/src/. && \
(echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo y ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ) | make config && \
make && \
make install
# Installing VORO++
RUN \
mkdir -p $PREFIX/voro++ && \
tar xvzf /tmp/software/voro++-0.4.6.tar.gz -C $PREFIX/voro++ --strip-components 1 && \
cd $PREFIX/voro++/ && \
sed -i "21s|.*|PREFIX=$PREFIX/voro++|" ./config.mk && \
make && \
make install
# Installing KDTREE2
RUN \
tar xvzf /tmp/software/kdtree2.tar.gz -C $PREFIX/. && \
cd $PREFIX/kdtree2/ && \
gfortran -c kdtree2.f90 && \
gfortran -o kdtree2_iaea_v03.x kdtree2_iaea_v03.f90 kdtree2.o
# Installing VisIt
RUN \
mkdir -p $PREFIX/visit/ && \
cd /tmp/software/ && \
chmod 755 /tmp/software/visit-install2_13_3 && \
(echo 1) | bash ./visit-install2_13_3 2.13.3 linux-x86_64-ubuntu18-wmesa $PREFIX/visit/
# Removing installation packages
RUN rm -rf /tmp/software/
# Copying sample files
COPY ./sample /root/sample
# Run bash when the container launches
CMD ["/bin/bash"]
# A software workflow for fingerprinting and visualizing defects in damaged crystal structures
---
#### Udo von Toussaint, F. J. Domı́nguez-Gutiérrez, Markus Rampp, Michele Compostella
###### Max-Planck-Institut für Plasmaphysik, Boltzmannstrasse 2, 85748 Garching, Germany
###### Max-Planck Computing and Data Facility, Giessenbachstrasse 2, 85748 Garching, Germany
---
## Introduction
This repository contains the recipe to create a Docker container where users can test the workflow for fingerprinting and visualizing defects in damaged crystal structures.
Together with the required software, data for the analysis of point defects in a bcc Fe sample are provided. This dataset was obtained by performing MD simulations to emulate neutron bombardment at a primary-knock on-atom of 10 keV.
## Requirements
In order to build the Docker image, the following software is required on the local machine:
* tar
* curl
* wget
* git
* docker
#### Important:
The workflow presented in this repository uses the GAP library for the software QUIP. When installing this software, you are accepting the [GAP license agreement](http://www.libatoms.org/gap/gap_download.html).
## Installation
After cloning this repository, run the following command to create the Docker image
```shell
./build.sh /root/software/
```
The parameter for the build.sh script is the installation path of the software stack inside the Docker image.
Additional optional parameters can be provided to automatically accept the GAP license agreement:
```shell
./build.sh /root/software/ "I accept" "FULL NAME" "EMAIL ADDRESS" "ORGANIZATION"
```
If these optional parameters are not specified, the build process will ask for them during runtime.
## How to run the Docker image
Once the Docker image has been created, use the following command to shell into the container:
```shell
docker run -t -i --volume /local_folder/:/root/sample/output/ favad /bin/bash
```
The ouput files generated inside the Docker container will be stored in the specified /local_folder/.
Please note that the content of this folder will be overwritten, if the folder is not empty.
At this point you can run the workflow for fingerprinting and visualizing defects on the sample dataset inside the Docker container:
```shell
cd /root/sample/
python3 FaVaD.py -p /root/sample/parameters.txt
```
---
## Local Installation
In the 'assets' folder we provide a script for the installation of the entire software stack on a local machine (instead of inside a Docker container) running Ubuntu 18.04 LTS.
In this case, you can run the installer using
```shell
./assets/installer.sh /local_installation_path/ "FULL NAME" "EMAIL ADDRESS" "ORGANIZATION"
```
By running the installer, you are accepting the [GAP license agreement](http://www.libatoms.org/gap/gap_download.html).
## How to run locally
If you installed the software stack locally, you can run the workflow for fingerprinting and visualizing defects on the sample dataset using
```shell
cd ./sample
python3 FaVa.py -p ./parameters.txt
```
Note however that you are required to change the paths in the parameter.txt file to match the current location of the files and software executables.
#########################################################################
# This installer works on Ubuntu 18.04 LTS
#
# It installs for the user all requirement for running
# the fingerprinting and visualization of defects in
# damages crystal structures
#
# Run as root with:
# ./installer.sh /installation_path/ full_name email_address organization
#
# For example:
# ./installer.sh /home/marco/software/ "Marcus Aurelius" marcus.aurelius@email.com "Imperium Romanum"
#
# Note that "full_name", "email_address" and "organization" are required
# to accept the GAP suite license.
#
#########################################################################
# Updating distro and installing packages
echo "Updating LINUX distribution..."
apt update
apt upgrade -y
echo "Installing LINUX packages..."
apt install -y gcc gfortran libblas-dev liblapack-dev python python-pip python3 python3-pip ffmpeg imagemagick
apt install -y libsm6 libgl1 libgl1-mesa-dri libgl1-mesa-glx libpcre3-dev libxt6
# Creating software folder
mkdir -p $1
pushd $1
# Installing Python 3 packages
echo "Installing Python 3 packages..."
pip3 install numpy
pip3 install matplotlib
pip3 install vtk
pip3 install mayavi
# Installing QUIP with GAP
echo "Installing QUIP with GAP..."
git clone --recursive https://github.com/libAtoms/QUIP.git
cd QUIP
curl -X POST -F "name=$2" -F "email=$3" -F "org=$4" -F "agree=I accept" --output GAP.tar.gz http://www.libatoms.org/gap/cgi-bin/script.cgi
tar xvzf ./GAP.tar.gz -C $1/QUIP/src/.
# Installing
export QUIP_ARCH=linux_x86_64_gfortran
(echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo y ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ) | make config
make
export QUIP_STRUCTS_DIR=$1/QUIP/structs
export QUIP_INSTALLDIR=$1/QUIP/bin
make install
cd ..
# Installing voro++
wget http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz
mkdir -p $1/voro++
tar xvzf ./voro++-0.4.6.tar.gz -C $1/voro++ --strip-components 1
cd voro++/
sed -i "21s|.*|PREFIX=${1}voro++|" ./config.mk
make
make install
cd ..
# Installing KDTREE
echo "Installing KDTREE..."
tar xvzf ~/kdtree2.tar.gz -C $1/.
cd kdtree2/
gfortran -c kdtree2.f90
gfortran -o kdtree2_iaea_v03.x kdtree2_iaea_v03.f90 kdtree2.o
cd ..
# Installing VisIt
echo "Installing VISIT..."
wget https://portal.nersc.gov/project/visit/releases/2.13.3/visit2_13_3.linux-x86_64-ubuntu18-wmesa.tar.gz
wget https://portal.nersc.gov/project/visit/releases/2.13.3/visit-install2_13_3
chmod 755 ./visit-install2_13_3
mkdir -p $1/visit/
(echo 1) | bash ./visit-install2_13_3 2.13.3 linux-x86_64-ubuntu18-wmesa $1/visit/
# Archiving not required files
mkdir archive/
mv ./QUIP/GAP.tar.gz archive/
mv ./voro++-0.4.6.tar.gz archive/
mv ~/kdtree2.tar.gz archive/
mv ./visit2_13_3.linux-x86_64-ubuntu18-wmesa.tar.gz archive/
mv ./visit-install2_13_3 archive/
popd
echo
echo "Installation complete"
echo
exit 0
#!/bin/bash
###############################################################################################################
## Copyright (C) 2020 Udo von Toussaint, F. J. Dominguez-Gutierrez, Markus Rampp, Michele Compostella
## Max-Planck-Institut für Plasmaphysik, Boltzmannstrasse 2, 85748 Garching, Germany
## Max-Planck Computing and Data Facility, Giessenbachstrasse 2, 85748 Garching, Germany
##
## This program 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 2, or (at your option)
## any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
##
###############################################################################################################
##
## General Notes:
## Docker container builder for Fingerprinting and Visualizing defects in damaged crystal structures
## Version: 1.0
## This software provides a workflow for fingerprinting and visualizing defects in damaged crystal
## structures. The theoretical background is presented in: paper_ID
##
## Run as root with:
## ./build.sh /installation_path/ "I agree" full_name email_address organization
##
## For example:
## ./build.sh /home/aurelius/software/ "I agree" "Marcus Aurelius" marcus.aurelius@email.com "Imperium Romanum"
##
###############################################################################################################
# echo an error message if any command fails
set -e
set -o pipefail
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
trap 'echo "\"${last_command}\" command filed with exit code $?."' EXIT
# Reading input parameters
PREFIX=$1
GAP=$2
NAME=$3
EMAIL=$4
ORGANIZATION=$5
# Requiring at least the PREFIX parameter
if [ "$#" -lt 1 ]; then
echo
echo "Please provide the installation directory for the software in the Docker container"
echo "E.g: ./build.sh /root/software/"
exit
fi
# GAP license
if [ ! -f ./software/GAP.tar.gz ] && [ "$GAP" != "I accept" ]; then
echo
echo "You need to accept the GAP license to create this Docker container"
echo "The GAP suite — Non-commercial License Agreement is available at:"
echo " http://www.libatoms.org/gap/gap_download.html"
echo
echo "Read the Agreement at the link in full."
echo "Only if you accept the Agreement, type 'I accept' followed by [ENTER]."
read GAP
if [ "$GAP" != "I accept" ]; then
echo "You did not accept the GAP license. Leaving installation process.."
exit
fi
echo "Enter your name for the GAP license"
read NAME
echo "Enter your email address for the GAP license"
read EMAIL
echo "Enter your organization name for the GAP license"
read ORGANIZATION
# Downloading GAP in ./software/
echo
echo "Downloading GAP.."
curl -X POST -F "name=$NAME" -F "email=$EMAIL" -F "org=$ORGANIZATION" -F "agree=$GAP" --output ./software/GAP.tar.gz http://www.libatoms.org/gap/cgi-bin/script.cgi
fi
# Downloading required software
if [ ! -f ./software/kdtree2.tar.gz ]; then
echo
echo "kdtree2.tar.gz archive is missing from the ./software/ folder. Leaving installation.."
exit
fi
if [ ! -f ./software/voro++-0.4.6.tar.gz ]; then
echo
echo "Downloading VORO++.."
wget -P ./software/ http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz
fi
if [ ! -f ./software/QUIP.tar.gz ]; then
echo
echo "Downloading QUIP.."
git clone --recursive https://github.com/libAtoms/QUIP.git ./QUIP/
tar -czvf ./software/QUIP.tar.gz ./QUIP/*
rm -rf ./QUIP/
fi
if [ ! -f ./software/visit-install2_13_3 ]; then
echo
echo "Downloading VisIt.."
wget -P ./software/ https://portal.nersc.gov/project/visit/releases/2.13.3/visit-install2_13_3
wget -P ./software/ https://portal.nersc.gov/project/visit/releases/2.13.3/visit2_13_3.linux-x86_64-ubuntu18-wmesa.tar.gz
fi
# Build the Docker container "favad" from the definition file 'Dockerfile' in the current directory
sudo docker build --tag favad:v1.0 --build-arg PREFIX=$PREFIX -t favad .
echo
echo
echo
echo "Build complete!"
echo
echo "You can run the image interactively mounting an ouput folder (use the full path) with:"
echo " sudo docker run -t -i --volume /local_folder/:/root/sample/output/ favad /bin/bash"
echo "and, once in the container"
echo " cd /root/sample/"
echo " python3 FaVaD.py -p /root/sample/parameters.txt"
echo
exit 0
#####################################################################################################
## Copyright (C) 2019 Udo von Toussaint, F. J. Dominguez-Gutierrez, Markus Rampp, Michele Compostella
##
## This program 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 2, or (at your option)
## any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
##
#####################################################################################################
##
## General Notes:
## FaVa: Fingerprint And VisuAlization. Version: 1.0
## This software provides a workflow for fingerprinting and visualizing defects in damaged crystal
## structures. The theoretical background is presented in: paper_ID
##
#####################################################################################################
##########
# Preamble
##########
import sys, argparse
import os, subprocess
import gc
os.system('clear')
print()
print(" ------------------------------------------------- ")
print("| Fingerprint and visualization of defects |")
print("| in damaged crystal structures |")
print(" ------------------------------------------------- ")
print()
# Check Python version
if sys.version_info[0] < 3:
print("\nRequires Python version 3 or greater\n")
sys.exit()
# This is used in order to read negative numbers, without seeing them as other parameters
for i, arg in enumerate(sys.argv):
if (arg[0] == '-') and arg[1].isdigit(): sys.argv[i] = ' ' + arg
# Reading and setting the different arguments
parser = argparse.ArgumentParser(description='This is a Python 3 script for fingerprinting and visualizing defects in damaged crystal structures.')
parser.add_argument('-p','--parameters', help="Path to the file with the parameters",required=True)
args = parser.parse_args()
# Cheching if input parameter file exists
if (not os.path.exists(args.parameters)):
print("Parameter file does not exist.")
quit()
# Creating dictionary with entries from the parameter file
param = {}
with open(args.parameters) as f:
lines = filter(None, (line.rstrip() for line in f))
for line in lines:
if line.startswith("#"):
continue
(key, temp ,val) = line.split()
param[key] = val
# Adding / to output folder, if missing
if (param['OUTPUT_PATH'][-1]!='/'):
param['OUTPUT_PATH']=param['OUTPUT_PATH']+'/'
# Checking for output folder
try:
os.makedirs(param['OUTPUT_PATH'])
except FileExistsError:
# directory already exists
print("\nWarning: output directory exists. Files will be overwritten.")
input(" Press Enter to continue.")
print()
# Cheching if input files exist
if (not os.path.exists(param['QUIP_XYZ'])):
print("QUIP xyz input file does not exist.")
quit()
if (not os.path.exists(param['BCC_VEC'])):
print("bcc reference descriptor vector file does not exist.")
quit()
if (not os.path.exists(param['INT_VEC'])):
print("Interstitial reference descriptor vector file does not exist.")
quit()
if (not os.path.exists(param['VAC_VEC'])):
print("Next-to-vacancy reference descriptor vector file does not exist.")
quit()
if (not os.path.exists(param['TYPA_VEC'])):
print("Type-a reference descriptor vector file does not exist.")
quit()
# Cheching if commands exist
if (not os.path.exists(param['QUIP_PATH'])):
print("Path to QUIP executable does not exist.")
quit()
if (not os.path.exists(param['KDTREE_PATH'])):
print("Path to KDTREE executable does not exist.")
quit()
if (not os.path.exists(param['VISIT_PATH'])):
print("Path to VISIT executable does not exist.")
quit()
##############################
# Calculation of DVs with QUIP
##############################
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
import linecache
num_lines = sum(1 for line in open(param['QUIP_XYZ']))
num_atom = int(linecache.getline(param['QUIP_XYZ'],1))
print('Checking xyz input file')
num_lines = num_lines-2
if ( num_lines == num_atom):
print('Input xyz is in good shape')
else:
sys.exit("Input xyz file corrupted, please check its format")
print()
# Computing descriptor vectors of damaged sample
print('Computing descriptor vectors of damaged material with QUIP')
# command line for hundreds to thousands of atoms
cmd = str(param['QUIP_PATH'])+' atoms_filename='+str(param['QUIP_XYZ'])+' descriptor_str="soap cutoff=2.75 l_max=4 n_max=4 atom_sigma=0.5 n_Z=1 Z={26} n_species=1 species_Z={26}" > '+str(param['OUTPUT_PATH'])+'vectors.dat'
# command line for million of atoms
#cmd = 'mpirun -n 24 '+str(param['QUIP_PATH'])+'_openmpi atoms_filename='+str(param['QUIP_XYZ'])+' descriptor_str="soap cutoff=2.75 l_max=4 n_max=4 atom_sigma=0.5 n_Z=1 Z={26} n_species=1 species_Z={26}" > '+str(param['OUTPUT_PATH'])+'vectors.dat'
#
subprocess.call(cmd,shell=True)
print('DVs are given in '+str(param['OUTPUT_PATH'])+'vectors.dat file')
print()
# Reading descriptor vectors
print('Reading reference descriptor vector the atoms are compared with')
print('Reading reference DV for defect-free atom.')
ref_dfa = np.array([np.loadtxt(param['BCC_VEC'])])
print('Reading reference DV for self-interstitial atom.')
ref_sia = np.array([np.loadtxt(param['INT_VEC'])])
print('Reading reference DV for next-to-a-vacancy atom.')
ref_ntv = np.array([np.loadtxt(param['VAC_VEC'])])
print('Reading reference DV for type-a atom.')
ref_tpa = np.array([np.loadtxt(param['TYPA_VEC'])])
i = 0
arr = []
dist_diff_dfa = []
dist_diff_sia = []
dist_diff_ntv = []
dist_diff_tpa = []
# Cleaning quip output file
# Start reading DV at line 11
for i in range(11,11+num_atom):
dv_1 = np.array(linecache.getline(str(param['OUTPUT_PATH'])+'vectors.dat',i)[7::].split())
dv = dv_1.astype(np.float)
arr.append(dv)
# Computing difference distance
print('Computing distance differences')
diff_dfa = arr-ref_dfa
diff_sia = arr-ref_sia
diff_ntv = arr-ref_ntv
diff_tpa = arr-ref_tpa
# Printing out results
ddiff = open(str(param['OUTPUT_PATH'])+'dist_difference.dat','w')
ddiff.write("# atom DFA SIA ANtV Type_a\n")
for i in range(0,num_atom):
dist_diff_dfa.append(math.sqrt(sum(yi**2 for yi in diff_dfa[i,:])))
dist_diff_sia.append(math.sqrt(sum(yi**2 for yi in diff_sia[i,:])))
dist_diff_ntv.append(math.sqrt(sum(yi**2 for yi in diff_ntv[i,:])))
dist_diff_tpa.append(math.sqrt(sum(yi**2 for yi in diff_tpa[i,:])))
ddiff.write("{0:<3} {1:.10f} {1:.10f} {1:.10f} {1:.10f} \n".format(i+1, dist_diff_dfa[i], dist_diff_sia[i], dist_diff_ntv[i], dist_diff_tpa[i]))
ddiff.close()
print('Results are given in: '+str(param['OUTPUT_PATH'])+'dist_difference.dat')
print()
# Creating image with histogram
print('Creating histogram of the distance difference between DVs')
plt.hist(dist_diff_dfa,bins=1000,facecolor='white',edgecolor='black', linewidth=1.0, histtype='stepfilled', density=False)
plt.ylabel('Counts')
#Limits for the Y and X axes
plt.text(0.07,1e+3,r'DFA', fontsize=10)
plt.text(0.175,1e+3,r'Distorted', fontsize=10)
plt.text(0.175,0.2e+3,r'area', fontsize=10)
plt.text(0.275,1e+3,r'Frenkel pairs', fontsize=10)
plt.ylim(0.1,)
plt.xlim(0.0,)
plt.yscale('log', nonposy='clip')
plt.axvline(x=0.238, color='r')
plt.axvline(x=0.165, color='b',linestyle='--')
plt.annotate("", xy=(0.3, 1e+2), xytext=(0.2375, 1e+2),arrowprops=dict(arrowstyle="->"))
plt.savefig(str(param['OUTPUT_PATH'])+'DV_histogram.png', format='png', dpi=1000)
plt.close()
# Deleting support variables
del arr, dist_diff_dfa, dist_diff_sia, dist_diff_ntv, dist_diff_tpa
del ref_dfa, ref_sia, ref_ntv, ref_tpa
gc.collect()
# Moving idx file in output folder
cmd = 'mv '+str(param['QUIP_XYZ'])+'.idx '+str(param['OUTPUT_PATH'])