Tag: computational materials science

A new life for the HIVE-STM program

“Once upon a time, there was a young researcher studying the formation of Pt nanowires on Ge substrates using quantum mechanical simulations. The results of the experimental counterparts were excellent; they provided Scanning Tunneling Microscopy images of ridiculously high quality …but not really atomistic structural information or detailed electronic band structures. On the other hand, the calculation-software of the young researcher provided only ground state energies and electronic band structures…but no Scanning Tunneling Microscopy images. So the young researcher set out to resolve this discrepancy.”

About 15 years ago, when starting out as a fresh Ph.D. student, I faced this mismatch between what my calculations could do and what my experimental counterparts had on offer. High quality ground state energies are nice, but rather useless in an experimental context governed by meta-stable states and high temperature transitions (especially since DFT represents only 0K results). I had to find a way to connect my calculations directly to the available experimental data, which boiled down to simulating Scanning Tunneling Microscopy (STM) images.

Original Delphi program: Graphene

Original Delphi program: Graphene

At that time, my programming skills were still nascent, but I felt king of the world knowing both pascal/Delphi and C/C++. I had written toy-programs in both languages, going from a text based battleships in turbo-pascal over a brick-buster game in C/C++using the djgpp compiler and allegro library to create the GUI, and many GUI programs in Delphi (e.g., the programs needed to numerically calculated Bose-Eistein condensation behavior for molecular condensates during my masters thesis). Based on those experiences, I knew that writing a GUI program  was much more straight forward in Delphi. So I set out writing my STM program using Delphi in the year(s) 2005-2006**. On the right you can see an screenshot of this program, generated today 15 years later, on the electron density of graphene. The program written in windows XP, ran smoothly and without modification or required recompile on both windows 7 and the current windows 10. Not to bad, if I say so myself. Try that with a python “program” 😈 .[1]

Free-standing Pt-induced nanowire on Ge(001).

Simulated STM image of the Pt-induced nanowires on the Ge(001) surface. Green discs indicate the atomic positions of the bulk-Ge atoms; red: Pt atoms embedded in the top surface layers; yellow: Ge atoms forming the nanowire observed by STM.

The program was designed to work for my specific use-case at the time: a germanium 001 surface, with a nice rectangular surface unit cell (see figure on the left). This has the unfortunate consequence that systems with a non-rectangular unit cell appear skewed, as is seen for the graphene example above. However, as I never needed such systems myself, no fix was ever included.

After presenting STM results in my first published paper in 2008,[2] I got some questions if it was possible to share the program. I shared the program on an as-is basis: free to use, and I hope it works for you as well, but no support.

Reading the above you may wonder: “Why didn’t you put the source on GitHub, such that other people could collaborate with you on it, and extend it and fix bugs?” The answer is rather simple (and sobering at the same time): GitHub didn’t exist yet when I wrote the program, as it was founded only in February 2008. It grew rapidly since then (surpassing SourceForge in mid 2011), but as I was working on other projects there was no time to support such a setup.

The number of people asking for the program grew steadily, and there was the nagging feeling at the back of my head that I should really clean up the code and make it cross-platform. In 2011, I had a short period when I decided to start from scratch and write the program anew in Java. Unfortunately, my available time ran out, and initial tests showed the program had a hard time reading the large charge-density files fast. So the original Delphi version remained in use being distributed to new users. By September 2012, this program developed for my own purposes had been requested by 100 researchers (which is a lot considering the boundary conditions: (1) needing atomic scale STM simulations  and (2) using VASP for DFT calculations), and over 200 researchers had requested it by 2015. Currently, in January 2021, the counter indicates over 400 requests. Still the same piece of software, being used by people I never imagined would be interested on OS’s it was never designed for. Despite its simplicity, this unexpected interest makes me extremely proud. 😎 

Distribution of users over the continents and evolution of requests over the years.

Distribution of users over the continents and evolution of requests over the years.

Thorny roses: Some issues popping up

Given the original intent of the program and its eventual use, one should not be amazed that some issues popped up over the years. However, no serious bugs were encountered (which still amazes me).

  • Non-orthogonal surface units: This is the oldest known limitation of the program. It assumes a rectangular surface unit as it uses the direct grid used in the VASP CHGCAR file as a pixel grid. This suited my own purposes well, but is unfortunate for the user studying hexagonal surfaces.
  • “Smart” Antivirus software (1): In the early days, I just sent a zipfile with the program and manual to new users. Unfortunately, AVs do not like people mailing executables, leading to mails being blocked. For some time the problem could be circumvented by zipping the zipfile and later even renaming the extension of the second zip round to prevent the AV of trying to look inside. I know, one should not do this and applaud the AVs for protecting their users, as people did spread trojan horses and other viruses like this back in the days. (Who clicks on those strange attachments anyhow?) So we ended up storing the program and zip online with password protection. We are not yet safe of AVs as some still complain about the risks of downloading things of the internet…but at least we are not (yet) back at the automatic shredding of the program.
  • “Smart” Antivirus software (2):  Did I say the program was written in Delphi? Apparently so were a lot of computer viruses and worms. (Must be a sign of being a nice and easy to use language 🙂 ) With smart AVs training on pieces of code from such fraudulent software it becomes rather hard to write any code using Delphi which has not been part of a virus…and thus your program gets flagged. Some AVs are nice enough to tell the user, and even provide an option to keep the program. Others just shred it without even mentioning it (not cool). This is unfortunately becoming more of a problem. Online multi-virus-scanners give a rather bleak picture, as can be seen below.

    smart AVs giving false positives on the old HIVE executable.

    smart AVs giving false positives on the old HIVE executable.

  • Windows 10: Extending on the previous, windows 10’s anti-virus protection follows suit trowing up warnings and messages of possible security threats.
  • Mac and 64bit: Although the program was written for windows, it also runs smoothly in unix environments when using an emulator such as Wine, making the program available to Linux and Mac users as well. Unfortunately since the Mac OS version Catalina, Mac has dropped support for 32bit executables, making it no longer possible to run the 15 year old executable. [1] Remember that in 2006 64bit programs were new and not generally supported. Furthermore, 32bit executables tend to work smoothly on a 64bit system, they just “waste” half the memory.

 

The Future of HIVE-STM

Over the years, I’ve often considered it time to clean up the code, and upgrading it. Unfortunately time was always a major issue. In addition, I no longer had a working Delphi compiler so I was lured to the idea of rewriting it in a different programming language (I seriously considered reworking it in fortran, though the easy access to a GUI stopped me from doing this).

The latest issue with Macs and the zealous persecution of Delphi programs by AVs finally got me to the point of starting a full rework of the HIVE-STM program as a hobby project. The maturity of the Lazarus IDE and free-pascal compiler is an important second component. During the summer holidays of 2020, I started porting the original Delphi code to the Lazarus IDE and free-pascal. This successful port gave me the courage to continue working on it, and I am currently performing a full rewrite of the internals (so far things have gone smoothly). The new version will become available via GitHub once I am confident it is working well and a have setup a good method of keeping track of new users.

New years resolution 2021:
“Finally build a new ‘updated’ version of HIVE-STM “

 

References

[1]Challenge to scientists: does your ten-year-old code still run?“, J.M. Perkel, nature technology feature, august 24th 2020.
[2]Formation of Pt-induced Ge atomic nanowires on Pt/Ge(001)“, D.E.P. Vanpoucke & G. Brocks, Phys. Rev. B 77, 241308(R) 2008.

Gnuplot animated gifs: Visualizing Machine-Learning models

One of the most important aspects in machine-learning—in addition to the modeling itself—is undoubtedly visualization. This can be of either the data set itself or the resulting model. When dealing with small or sparse data sets and a limited number of features, visualization can be extremely helpful to get a feel for your model and data. In this tutorial, we show how you can use gnuplot to generate interesting animations of your data, such as the example above.

What do you need?

  • Install Gnuplot  version 5.2.8 (or higher) for your OS (under windows you can also install it under your Cygwin installation)
  • A data set as a simple multi-column text-file data.dat .
  • A similar text-file, model.dat, with your model calculated on a grid .

1. Starting simple: a static image

The main difference between an animation and a static image is the fact the former is just a series of such static images shown one after the other.

1.a. Basic image

Gnuplot allows both interactive and scripted command-line usage. The commands used in interactive mode can simply be placed in a text-file (e.g., myplot.gpl) and run using  the command:

> gnuplot myplot.gpl

Comments can be added in such a file by preceding them with a single “#“. In the examples below, I’m using “###” as a personal choice. It shows clearly the location of the comments, and also gives me an easy way to distinguish with script lines I commented out for testing purposes, in which case I use a single #. In the following I also indicate gnuplot commands in red, while options are indicated in turquise. Let u start by plotting the data set in a simple png:

### Set the output to a png file
set termopt enhanced
set terminal pngcairo size 300,300 font "Helvetica-Bold,6"
### The file to write to
set output 'modelplot_v1.png'
### The Title label
set title 'ML model tutor' font "Helvetica-Bold,10"

splot "data.dat" u 1:2:3
Model v1

Model v1

With this we set the output to be a png image of 300×300 pixels. (Note: pngcairo also provides png-functionality using the cairo-library. For more complex plotting, it gives much nicer images.) The default font for text is set to “Helvetical-Bold” with a font-size of 6pt. The enhanced option further allows us to use LaTeX type strings, for example indicating subscripts as A_n to print An. The resulting image is stored as ‘modelplot_v1.png‘.

The last two commands are used to create the actual plot. With set title a title can be added to the graph. The default font is replaced in this case by a slightly larger version of 10pt. The splot command  allows you to plot 3D surfaces using the same basic information as the gnuplot plot command for 2D plots. In this case, I used the first 3 columns of the data.dat file to plot 3D data, with the x:y:z giving the respective column numbers. The result is shown on the right.

NOTE: An important point to consider is the fact that the font size is absolute. So if you decide later-on to change your image size to say 500×500 pixels, your text labels may look rather small, and you will have to tweak the font-size to compensate of this behavior. Therefore, it is important to make sure you start with the right image size straight away. The 300×300 pixels used in this tutorial are too small for any scientific quality image, it was chosen to be a suitable image size to incorporate in this blog.

1.b. Pimp the axis

With the basics for the graph set up, we can start setting up the graph to our liking.

###settings for the boxplot
set xlabel "M_{n polyX} (g/mol)" offset 0,-1,0 font "Helvetica-Bold, 8" rotate parallel
set xrange[1000:10000] noreverse writeback
set xtics 2000,2000,10000 out scale 1.0 nomirror offset 0,-0.5,0

set ylabel "Graft (%)" offset 2,0,0 font "Helvetica-Bold, 8" rotate parallel
set yrange[0:30] noreverse writeback
set ytics 0,10,30 out scale 1.0 nomirror offset 0,-0.5,0

set zlabel "Particle size (nm)" offset 1,1,0 font "Helvetica-Bold, 8" rotate parallel
set zrange[0:300] noreverse writeback
set ztics 0,50,300 out scale 1.0 nomirror offset 0,-0.5,0

set xyplane at 0
set border lw 3

 

Model v2

Model v2

The label of each of the three axes can be modified individually using set {x/y/z}label followed by the same options available to any other string (such as the graph title earlier). Here you can see how the enhanced mode allows the use of a subscript using standard LaTeX formatting. The offset makes sure the axis-label does not overlap with the tick-labels. Gnuplot also allows you to define the range to be plotted using set {x/y/z}range[min:max], while set {x/y/z}tics gives you access to the specifics of the individual tics. The latter can be very useful to manually add specific tics, or, as in the current case, manually set the splitting between the different tics. The out option places the tic-marks at the outside of the graph, and their size is set by the scale option.

The command set xyplane can be used to set the intercept of the xy-plane and the z-axis, and set border gives access to the axis-line properties. Here I have set the line-width (lw) to 3.

1.c. Add the (machine-learning) model

Now that the basics properties of the 3D graph are alright*, let us add the model to the plot. This can easily be done by just adding additional input for the splot command.

splot \
     "data.dat" using 1:2:3 with points pointtype 7 pointsize 1 linecolor rgb "brown4" notitle, \
     "model.dat" u 1:2:3 w line lc rgb "sea-green" notitle
Model v3

Model v3

The “\” can be used to split the command to multiple lines. In this case, each curve/surface/data set is set on a separate line. Since the command for a single plot can become very long, gnuplot also has a shorthand for most common keywords/options it uses.  For the data the extended keywords are shown, and the shorthand is used for the model. The length of the command becomes significantly shorter, but at the same time harder to read. (Note that both shorthand as longhand keywords can be mixed in a single command.)

The data set is now being shown as points, using the 7th pointtype (which are discs). The size of these symbols is set to 1 and the linecolor is a predefined color used by gnuplot.  Finally, the notitle option removes the legend entry of this curve. The model data is presented as a line-surface. The end result is shown on the right.

1.d. A better surface-plot: Multi-plot
Model v4

Model v4

As you can see in the previous version of the plot, the model data is plotted as a surface, but this is not a very nice surface. This is because gnuplot just connected the sequential points in the file as a single very long and very complex curve. If you would rotate this plot, it would become clear, several things are very wrong. Luckily there is a very simple solution. Gnuplot has the ability to transform a point-cloud into a surface. This is done by setting a 3D grid using set dgrid3d X,Y. This creates a 3D surface for which the nodes are interpolated between the points of your point-cloud. When you set this option, it is applied on all data curves you plot (i.e., including the set of data-points, which we would like to avoid.). Using the multiplot option of gnuplot the two curves can be drawn separately, using different settings. In the script the splot command is replaced by:

### switch to a multiplot
set multiplot
set dgrid3d 50, 50 
splot \
     "model.dat" u 1:2:3 w line lc rgb "sea-green" notitle

unset dgrid3d
splot \
     "data.dat" using 1:2:3 with points pointtype 7 pointsize 1 linecolor rgb "brown4" notitle

unset multiplot

By setting the multiplot environment, we can unset dgrid3d before drawing the second data set. At the end of script we also unset multiplot to switch of the multiplot environment. At this point it become interesting to see the impact of the terminal pngcairo over png.

1.e. Surface coloring

Drawing a surface is nice, but you can also give it some color. Either by using the z-value as a color scale, or by using another metric/feature to color the surface.

###settings for the color scale
set colorbox vertical
set cblabel "Colormap\n (RGB)" font "Helvetica-Bold, 8" offset -6.75,8 rotate by 0
set pm3d at s explicit

splot \
      "model.dat" u 1:2:3 w pm3d notitle
Model v5

Model v5

Surface coloring is switched on via the command set pm3d which is set at the surface, and is used in splot at the with option. In addition to surface coloring also a color scale is added, with the label formatted using the same options as for other labels. To get the label above the color scale it needs to be shifted using the offset and the rotate option.

The result is rather fancy, but for practical purposes, the surface may actually block the view of the data points. This can be avoided by projecting the color on the xy-plane and retaining a grid representation of the surface. This is done by setting pm3d at the bottom.

Model v6

Model v6

 

 

In addition, we  also need to plot the model surface twice, once to generate the color map and once to generate the model surface as a grid-image.

set pm3d at b explicit

splot \
    "model.dat" u 1:2:3 w pm3d notitle,\
    "model.dat" u 1:2:3 w line lc rgb "sea-green" notitle

 

 

2. Creating an animation

With gnuplot it is quite easy to generate stunning 3D animated gif images. Some nice examples can be found all over the web, such as this animated Bessel function, my own (very old) molecular d-and f-orbitals, or this collection. Once you finish creating a script to generate a single image, creating an animation requires only some minor modifications. First of all we need to select the correct terminal (i.e., gif instead of png)

set terminal gif transparent animate nooptimize delay 10 size 300,300 font "Helvetica-Bold,10"
set output 'modelplot_v7.gif'

This generates a transparent animated gif with a delay of 10 ms between frames, and stores it in a gif image. In addition, a change in time/image frame needs to be implemented. This can easily be done by a simple for loop, which is wrapped around the plotting section.

n=60
do for [i=1:n]{
    set view 60, i*360/n

    ### do the multiplot plotting section 
    set multiplot 
    ...all the other plotting stuff of before
    unset multiplot
}
set output

model v7: animated

model v7: animated

In the example, the 3D graph is rotated. This is done by changing the view via the set view command which takes two angles in degrees. As you can see from “i*360/n“, gnuplot also accepts simple mathematical equations.

Once the loop is finished we need to close our gif animation. This is done via (a side-effect of) the command set output. The set output {filename} command sets the output to a file with name filename, or if a filename is omitted to the standard output. As a side-effect it closes the current output file, c.q. our animated gif.

An alternative method for creating an animation would be creating a series of images (in the image-format of your choice, e.g. pngcairo and then create an apng) and combining them yourself or via additional scripting into an animated image format using additional software, such as is done here.

3. Animated surfaces and coloring 

The example above is rather trivial in regard to animations. The ability to perform math inside a gnuplot script provides you the ability to make things a lot more interesting. In the following, we are going to construct a small imaginary solar system, to present some of the things which are possible.

The basic script for the solar system above can be downloaded here.

set termopt enhanced
set terminal gif animate nooptimize delay 10 size 300,300 font "Helvetica,10"
set output 'Solarplot_v1.gif'
set title 'Magic Solar System' font "Helvetica-Bold,10"

maxl=10
set xrange[-maxl:maxl] noreverse writeback
set yrange[-maxl:maxl] noreverse writeback
set zrange[-maxl:maxl] noreverse writeback
set xyplane at 0
set border lw 1.5

###Use parametric coordinated for plotting spheres
set parametric # enable parametric mode with angles (u,v)
set urange [0:2*pi]
set vrange [-pi/2.0:pi/2.0]
set isosample 360,180
fx(u,v)=cos(u)*cos(v)
fy(u,v)=sin(u)*cos(v)
fz(v)=sin(v)

### Surface coloring
set colorbox vertical
set cblabel "Planet\n colors" font "Helvetia, 8" offset -4.75,5 rotate by 0
set pm3d depthorder base nohidden3d
unset hidden3d

### The animated drawing
n = 60
do for [i=1:n]{
    # The star
    x=0.0
    y=0.0
    z=0.0
    r=3.0

    # The first planet
    x1=5.0*sin(i*2*pi/n)
    y1=5.0*cos(i*2*pi/n)
    z1=0.0
    r1=0.50
    color1(u,v)=0.5

    # The second planet
    x2=6.5*sin(i*2*pi/n)
    y2=7.0*cos(i*2*pi/n)
    z2=1.0*cos(i*2*pi/n)
    r2=1.0
    color2(u,v)=sin(v)*2*pi

    splot \
         "++" using (x+r*fx(u,v)):(y+r*fy(u,v)):(z+r*fz(v)):(6.5) w pm3d notitle,\
         "++" using (x1+r1*fx(u,v)):(y1+r1*fy(u,v)):(z1+r1*fz(v)):(color1(u,v)) w pm3d notitle,\
         "++" using (x2+r2*fx(u,v)):(y2+r2*fy(u,v)):(z2+r2*fz(v)):(color2(u,v)) w pm3d notitle 
}
set output

Most of the commands and options have already been covered above. To draw our spherical planets, we introduce a set of parametric coordinates (u,v) via the command set parametric. Next we set their ranges, just as you would do for the x,y, and z coordinates via set {u|v}range. The command set isosample is used to define the grid over the parametric space.  With this setup, you can now define any parametric surface you want. In our case, we want to have a sphere. For this we define three transformation functions. With u and v representing the θ and φ angles of a sphere, the transformation to Cartesian coordinates is given by the functions fx(u,v),fy(u,v), and fz(v).

In the main loop of the gif we define the center position (x,y,z) and the radius (r) of our planets and star, with the latter nicely fixed at the origin, and our planets having an orbit around it. To have a nice periodic gif, you should make sure that any periodic behavior ends up where it started, hence the 2pi factor in the sines and cosines.  Everything is drawn with a single splot command where we use a pseudo 4-column input style:

(x-coord):(y-coord):(z-coord):(color-coord)

Note that the brackets ‘(‘ & ‘)‘ are important to include as gnuplot will throw errors otherwise. The selected color, can be either a real value in the color scale or a function. The resulting solar system is shown below on the left.

Solar v1, no depth

Solar v1, depth

Not that bad for a first attempt. There is however a small snag: the 3D effect is somehow off when the planets move behind the star. This is due to the depth-buffering. The newest versions of gnuplot (≥5.2.8) provide the option depthorder for the set pm3d command. Using the value base for the depthorder option results in the depthorder to be decided based on the z-projected position of the object. This is sufficient to fix our little solar system, as you can see on the right.

3.a. Some cleanup work: removing the box and complex coloring 

As we are creating an imaginary (magical) solar system, we should maybe get rid of the x-,y-, and z-axis. This is done via the commands unset border to get rid of the axis-bars and unset {x|y|z}tics to remove the tic-marks and-labels.

unset border
unset xtics
unset ytics
unset ztics
set palette defined (0 "red", 1 "yellow",1 "brown", 2 "brown4",3 "dark-green", 4 "blue", 5 "white")
set cbrange[0:10]
#unset cbtics

Solar v2

And although the color palette provided is nice, if we want different color schemes on each of the planets, we quickly run into a small problem: you can only have 1 color palette per splot. In case of a static image, you might be able to get around this problem by using a multiplot (as before) and have overlapping splots with each their own palette. But…in that case you will also be responsible for getting the 3D order of your objects correct yourself. And although this may be doable for a single frame, in case of an animated 3D solar system this will be a hassle nearly impossible to overcome**. For this you need to tackle the problem in a different way: create your own color palette consisting of sub-palettes. This can be done via the command set palette defined. The pairs give the color at the endpoints of gradient ranges, with the overall range (here 0-5) representing the entire color scale. The intermediate points are placed equidistant, so for a color range from 0:10 the red-to-yellow gradient is linked to color values in the range 0:2, while the blue-to-white gradient is linked to the color values in the range 8:10. Applying this to our solar system we can give nice individual color palettes to each of the objects. I changed the size and position of the three objects a bit, and as you can see, the outer planet moves outside of the x/y/z-ranges. Now that we know how to add different color palettes to each of our planets, we can also remove the color-bar on the right using the command unset colorbox, remove the tics via unset cbtics, and remove the label via unset cblabel.

3.b. time-dependent colors 

We have motion of objects and different color palettes, what about changing the colors during the animation? As we saw earlier, the color component can be defined as a function, which means we can make this time-dependent as well. Let’s imagine that our outer planet is traveling on a rather elliptic orbit, making it heat up when it approaches our star.

# The first planet
    color1(u,v)=0.5*(cos(u)**5+sin(v)**3)+sin(i*6*pi/n) +8.0 
	
# The second planet
    x2=8+15*sin((i+20)*2*pi/n)
    y2=6.0*cos((i+20)*2*pi/n)
    z2=3.0*cos((i+20)*2*pi/n)
    color2(u,v)=0.99*sin((i+20)*2*pi/n+pi)+1

By making the color dependent on the frame number, the (uniform) coloring of our second planet will now cycle through the red-yellow gradient. The first planet experiences a variation at 3x the speed but have a non-uniform surface coloring.

Solar v3

3.c. time-dependent colors and shapes 

Once you have time dependent coloring, and time dependent motion, you can also have time dependent shapes and combine all three. This is all possible within the same basic framework set up above. For example, we can make our star a bit more active, letting it bulge and swirl. Adding another planet and some moons the magic solar system below is created by this gnuplot script.

Solar v4

4. Conclusion 

Gnuplot provides a versatile tool for creating animated gifs of your machine learning data and models, or anything else you could imagine. It has an extensive number of options which allow you to tweak each single property of your graph. The ability to perform simple arithmetic within a gnuplot-script further increases the potential.

 


* Ignore the rather crummy quality of the embedded images. This is an artifact of only having a 300×300 pixel image, the animation at the top of the page has an 1000×1000 pixel resolution and shows a much better quality.

** Of course with enough persistence you may find a way to  get it done…but there are less sadomasochistic ways of doing this 😉

Impact of methane concentration on surface morphology and boron incorporation of heavily boron-doped single crystal diamond layers

Authors:  Rozita Rouzbahani, Shannon S.Nicley, Danny E.P.Vanpoucke, Fernando Lloret, Paulius Pobedinskas, Daniel Araujo, Ken Haenen
Journal: Carbon 172, 463-473 (2021)
doi: 10.1016/j.carbon.2020.10.061
IF(2019): 8.821
export: bibtex
pdf: <Carbon>

 

Graphical Abstract B doped diamond
Graphical Abstract: Artist impression of B incorporation during CVD growth of diamond.

Abstract

The methane concentration dependence of the plasma gas phase on surface morphology and boron incorporation in single crystal, boron-doped diamond deposition is experimentally and computationally investigated. Starting at 1%, an increase of the methane concentration results in an observable increase of the B-doping level up to 1.7×1021 cm−3, while the hole Hall carrier mobility decreases to 0.7±0.2 cm2 V−1 s−1. For B-doped SCD films grown at 1%, 2%, and 3% [CH4]/[H2], the electrical conductivity and mobility show no temperature-dependent behavior due to the metallic-like conduction mechanism occurring beyond the Mott transition. First principles calculations are used to investigate the origin of the increased boron incorporation. While the increased formation of growth centers directly related to the methane concentration does not significantly change the adsorption energy of boron at nearby sites, they dramatically increase the formation of missing H defects acting as preferential boron incorporation sites, indirectly increasing the boron incorporation. This not only indicates that the optimized methane concentration possesses a large potential for controlling the boron concentration levels in the diamond, but also enables optimization of the growth morphology. The calculations provide a route to understand impurity incorporation in diamond on a general level, of great importance for color center formation.

Small Data Materials Design with Machine Learning: When the Average Model Knows Best

Authors:  Danny E. P. Vanpoucke, Onno S. J. van Knippenberg, Ko Hermans, Katrien V. Bernaerts, and Siamak Mehrkanoon
Journal: Journal of Applied Physics 128, 054901 (2020)
doi: 10.1063/5.0012285
IF(2019): 2.286
export: bibtex
pdf: <JApplPhys>   (Open Access)
github: <Amadeus>

 

Vulcanoplot
Graphical Abstract: Correlation plot of the RMSE of the validation set and the intercept value for linear model instances trained on 1000 subsets of a 25 point data set. The distribution of the correlation data is indicated by the black curve.

Abstract

Machine Learning is quickly becoming an important tool in modern materials design. Where many of its successes are rooted in huge data sets, the most common applications in academic and industrial materials design deal with data sets of at best a few tens of data points. Harnessing the power of Machine Learning in this context is therefore of considerable importance. In this work, we investigate the intricacies introduced by these small data sets. We show that individual data points introduce a significant chance factor in both model training and quality measurement. This chance factor can be mitigated by the introduction of an ensemble-averaged model. This model presents the highest accuracy while at the same time it is robust with regard to changing data set size. Furthermore, as only a single model instance needs to be stored and evaluated, it provides a highly efficient model for prediction purposes, ideally suited for the practical materials scientist.

Partitioning the vibrational spectrum: Fingerprinting defects in solids

Authors:  Danny E. P. Vanpoucke
Journal: Computational Materials Science 181, 109736 (2020)
doi: 10.1016/j.commatsci.2020.109736
IF(2019): 2.863
export: bibtex
pdf: <ComputMaterSci>   (Open Access)
github: <Hive-toolbox>

 

Graphical abstract Computational Materials Science 181, 109736 (2020)
Graphical Abstract: Finger printing defects in diamond through the creation of the vibrational spectrum of a defect.

Abstract

Vibrational spectroscopy techniques are some of the most-used tools for materials
characterization. Their simulation is therefore of significant interest, but commonly
performed using low cost approximate computational methods, such as force-fields.
Highly accurate quantum-mechanical methods, on the other hand are generally only used
in the context of molecules or small unit cell solids. For extended solid systems,
such as defects, the computational cost of plane wave based quantum mechanical simulations
remains prohibitive for routine calculations. In this work, we present a computational scheme
for isolating the vibrational spectrum of a defect in a solid. By quantifying the defect character
of the atom-projected vibrational spectra, the contributing atoms are identified and the strength
of their contribution determined. This method could be used to systematically improve phonon
fragment calculations. More interestingly, using the atom-projected vibrational spectra of the
defect atoms directly, it is possible to obtain a well-converged defect spectrum at lower
computational cost, which also incorporates the host-lattice interactions. Using diamond as
the host material, four point-defect test cases, each presenting a distinctly different
vibrational behaviour, are considered: a heavy substitutional dopant (Eu), two intrinsic
point-defects (neutral vacancy and split interstitial), and the negatively charged N-vacancy
center. The heavy dopant and split interstitial present localized modes at low and high
frequencies, respectively, showing little overlap with the host spectrum. In contrast, the
neutral vacancy and the N-vacancy center show a broad contribution to the upper spectral range
of the host spectrum, making them challenging to extract. Independent of the vibrational behaviour,
the main atoms contributing to the defect spectrum can be clearly identified. Recombination of
their atom-projected spectra results in the isolated spectrum of the point-defect.

UV-Curable Biobased Polyacrylates Based on a Multifunctional 2 Monomer Derived from Furfural

Authors: Jules Stouten, Danny E. P. Vanpoucke, Guy Van Assche, and Katrien V. Bernaerts
Journal: Macromolecules 53(4), 1388-1404 (2020)
doi: 10.1021/acs.macromol.9b02659
IF(2019): 5.918
export: bibtex
pdf: <Macromolecules> (Open Access)

 

 

Grapgical abstract ACS Macromolecules 2020
Graphical Abstract: The formation of biobased polyacrylates.

Abstract

The controlled polymerization of a new biobased monomer, 4-oxocyclopent-2-en-1-yl acrylate (4CPA), was
established via reversible addition−fragmentation chain transfer (RAFT) (co)polymerization to yield polymers bearing pendent cyclopentenone units. 4CPA contains two reactive functionalities, namely, a vinyl group and an internal double bond, and is an unsymmetrical monomer. Therefore, competition between the internal double bond and the vinyl group eventually leads to gel formation. With RAFT polymerization, when aiming for a degree of polymerization (DP) of 100, maximum 4CPA conversions of the vinyl group between 19.0 and 45.2% were obtained without gel formation or extensive broadening of the dispersity. When the same conditions were applied in the copolymerization of 4CPA with lauryl acrylate (LA), methyl acrylate (MA), and isobornyl acrylate, 4CPA conversions of the vinyl group between 63 and 95% were reached. The additional functionality of 4CPA in copolymers was demonstrated by model studies with 4-oxocyclopent-2-en-1-yl acetate (1), which readily dimerized under UV light via [2 + 2] photocyclodimerization. First-principles quantum mechanical simulations supported the experimental observations made in NMR. Based on the calculated energetics and chemical shifts, a mixture of head-to-head and head-to-tail dimers of (1) were identified. Using the dimerization mechanism, solvent-cast LA and MA copolymers containing 30 mol % 4CPA were cross-linked under UV light to obtain thin films. The cross-linked films were characterized by dynamic scanning calorimetry, dynamic mechanical analysis, IR, and swelling experiments. This is the first case where 4CPA is described as a monomer for functional biobased polymers that can undergo additional UV curing via photodimerization.

Influence of diamond crystal orientation on the interaction with biological matter

Authors: Viraj Damle, Kaiqi Wu, Oreste De Luca, Natalia Ortí-Casañ, Neda Norouzi, Aryan Morita, Joop de Vries, Hans Kaper, Inge Zuhorn, Ulrich Eisel, Danny E.P. Vanpoucke, Petra Rudolf, and Romana Schirhagl,
Journal: Carbon 162, 1-12 (2020)
doi: 10.1016/j.carbon.2020.01.115
IF(2019): 8.821
export: bibtex
pdf: <Carbon> (Open Access)

 

Graphical Abstract Carbon paper with Romana
Graphical Abstract: The preferential adsorption of biological matter on oriented diamond surfaces.

Abstract

Diamond has been a popular material for a variety of biological applications due to its favorable chemical, optical, mechanical and biocompatible properties. While the lattice orientation of crystalline material is known to alter the interaction between solids and biological materials, the effect of diamond’s crystal orientation on biological applications is completely unknown. Here, we experimentally evaluate the influence of the crystal orientation by investigating the interaction between the <100>, <110> and <111> surfaces of the single crystal diamond with biomolecules, cell culture medium, mammalian cells and bacteria. We show that the crystal orientation significantly alters these biological interactions. Most surprising is the two orders of magnitude difference in the number of bacteria adhering on <111> surface compared to <100> surface when both the surfaces were maintained under the same condition. We also observe differences in how small biomolecules attach to the surfaces. Neurons or HeLa cells on the other hand do not have clear preferences for either of the surfaces. To explain the observed differences, we theoretically estimated the surface charge for these three low index diamond surfaces and followed by the surface composition analysis using x-ray photoelectron spectroscopy (XPS). We conclude that the differences in negative surface charge, atomic composition and functional groups of the different surface orientations lead to significant variations in how the single crystal diamond surface interacts with the studied biological entities.

Investigation of structural, electronic and magnetic properties of breathing metal–organic framework MIL-47(Mn): a first principles approach

Authors: Mohammadreza Hosseini, Danny E. P. Vanpoucke, Paolo Giannozzi, Masoud Berahman  and Nasser Hadipour
Journal: RSC Adv. 10, 4786-4794 (2020)
doi: 10.1039/C9RA09196C
IF(2019): 3.119
export: bibtex
pdf: <RSC Adv.> (Open Access)

 

Graphical abstract: MIL-47(Mn) paper
Graphical Abstract: The breathing MIL-47(Mn) Metal-Organic Framework. Upon breathing, the electronic structure of this MOF undergoes a transition from an anti-ferromagnetic semiconductor, to a ferromagnetic semi-metal.

Abstract

The structural, electronic and magnetic properties of the MIL-47(Mn) metal–organic framework are investigated using first principles calculations. We find that the large-pore structure is the ground state of this material. We show that upon transition from the large-pore to the narrow-pore structure, the magnetic ground-state configuration changes from antiferromagnetic to ferromagnetic, consistent with the computed values of the intra-chain coupling constant. Furthermore, the antiferromagnetic and ferromagnetic configuration phases have intrinsically different electronic behavior: the former is semiconducting, the latter is a metal or half-metal. The change of electronic properties during breathing posits MIL-47(Mn) as a good candidate for sensing and other applications. Our calculated electronic band structure for MIL-47(Mn) presents a combination of flat dispersionless and strongly dispersive regions in the valence and conduction bands, indicative of quasi-1D electronic behavior. The spin coupling constants are obtained by mapping the total energies onto a spin Hamiltonian. The inter-chain coupling is found to be at least one order of magnitude smaller than the intra-chain coupling for both large and narrow pores. Interestingly, the intra-chain coupling changes sign and becomes five times stronger going from the large pore to the narrow pore structure. As such MIL-47(Mn) could provide unique opportunities for tunable low-dimensional magnetism in transition metal oxide systems.

Parallel Python?

As part of my machine learning research at AMIBM, I recently ran into the following challenge: “Is it possible to do parallel computation using python.” It sent me on a rather long and arduous journey, with the final answer being something like: “very reluctantly“.

Python was designed with one specific goal in mind; make it easy to implement small test programs to see if an idea is worth pursuing. This gave rise to a scripting language with a lot of flexibility, but also with significant limitations, most of which the “intended” user would never meet. However, as a consequence of its success, many are using it going far beyond this original scope (yours truly as well 🙂 ).

Python offers various libraries to parallelize your scripts…most of them wrappers adding minor additional functionality. However, digging down to the bottom one generally ends up at one of the following two libraries: the threading module and the multiprocessing module.

Of course, as with many things python, there is a huge amount of tutorials available with many of great quality.

import threading

Programmers experienced in a programming language such as C/C++, Pascal, or Fortran, may be familiar with the concept of multi-threading. With multi-threading, a CPU allows a program to distribute its work over multiple program-threads which can be performed in parallel by the different cores of the CPU (or while a core is idle, e.g., since a thread is waiting for data to be fetched).  One of the most famous API’s for writing multi-threaded applications is OpenMP. In the past I used it to parallelize my Hirshfeld-I implementation and the phonon-module of HIVE.

For Python, there is no implementation of the OpenMP API, instead there is the threading module. This provides access to the creation of multiple threads, each able to perform their own tasks while sharing data-objects. Unfortunately, python has also the Global Interpreter Lock, GIL for short, which allows only a single thread to access the interpreter at a time. This effectively reduces thread-based parallelization to a complex way of running a code in a serial way.

For more information on “multi-threading” in python, you can look into this tutorial.

import multiprocessing

In addition to the threading module, there is also the multiprocessing module. This module side-steps the GIL by creating multiple processes, each having its own interpreter. This however comes at a cost. Firstly, there is a significant computational cost starting the different processes. Secondly, objects are not shared between processes, so additional work is needed to collect and share data.

Using the “Pool” class, things are somewhat simplified, as can be seen in the code-fragment below.  With the pool class one creates a set of threads/processes available for your program. Then through the function apply_async function it is possible to run processes in parallel. (Note that you need to use the “async” version of the function, as otherwise you end up with running things serial …again)

  1. import multiprocessing as mp
  2.  
  3. def doOneRun(id:int): #trivial function to run in parallel
  4. return id**3
  5.  
  6.  
  7.  
  8. num_workers=10 #number of processes
  9. NRuns=1000 #number of runs of the function doOneRun
  10.  
  11. pool=mp.Pool(processes=num_workers) # create a pool of processes
  12. drones=[pool.apply_async(doOneRun, args=nr) for nr in range(NRuns)] #and run things in parallel
  13.  
  14. for drone in drones: #and collect the data
  15. Results.collectData(drone.get()) #Results.collectData is a function you write to recombine the separate results into a single result and is not given here.
  16.  
  17. pool.close() #close the pool...no new tasks can be run on any of the processes
  18. pool.join() #collapse all threads back into the main thread

 

how many cores does my computer have?

If you are used to HPC applications, you always want to get as much out of your machine as possible. With regard to parallelization this often means making sure no CPU cycle is left unused. In the example above we manually selected the number of processes to spawn. However, would it not be nice if the program itself could just set this value to be equal to the number of physical cores accessible?

Python has a large number of functions claiming to do just that. A few of them are given below.

  •  multiprocessing.cpu_count(): returns the number of logical cores it can find. So if you have a modern machine with hyper-threading technology, this will return a multiple of the number of physical cores (and you will be over-subscribing your CPU.
  • os.cpu_count(): same as multiprocessing.cpu_count().
  • psutil.cpu_count(logical=False): This implementation gives the same default behavior, however, the parameter logical allows for this function to return the correct number of cores in a single CPU. Indeed a single CPU. HPC architectures which contain multiples CPUs per node will again return an incorrect number, as the implementation makes use of a python “set”, and as such doesn’t increment for the same index core on a different CPU.

In conclusion, there seems to be no simple way to obtain the correct number of physical cores using python, and one is forced to provide this number manually. (If you do have knowledge of such a function which works in both windows and unix environments and both desktop and HPC architectures feel free to let me know in the comments.)

All in all, it is technically possible to run code in parallel using python, but you have to deal with a lot of python quirks such as GIL.

Casting Keynotes: The Virtual Lab

Last Tuesday? I had the pleasure of competing in the casting keynotes competition of the TEDx UHasselt chapter. An evening filled with interesting talks on subjects ranging from the FAIR principles of open-data (by Liebet Peeters)  to the duty not stay silent in the face of “bad ideas” and leading a life of purpose. An interesting presentation was the one by Ann Bessemans on visual prosody to improve reading skills in young children as well as reading experience, more specifically the transfer of non-literal-content, for non-native speakers. There was also time for some humor, with the dangerous life of Tim Biesmans, who suffers from peanut-allergies. For him, death lurks around every corner, even in a first-date’s kiss. During my talk, I traced the evolution of computational research as the third paradigm of scientific discovery, showing you can find computational research in every field, and why it is evolving at its break-neck speed.

During the event, both the public and a jury voted on the best presentation, which would then have to present at the TEDx UHasselt in 2020.

And the Winner is …drum roll… Danny Vanpoucke!

So this story will continue during the 2020 TEDx event at UHasselt, and I hope to see you there 🙂

Casting Keynotes

top: Full action shots of my presentation. Moore’s Law as driving force behind computational research, and pondering the meaning of Artificial Intelligence. Bottom: Yes, I won 🙂