Category: blog

Materiomics Chronicles: week 2

After the more gentle introductions last week during the first lectures at UHasselt, this week we dove into the deep end.

For the students of the second bachelor chemistry  the course introduction to quantum chemistry dove into the postulates of quantum chemistry. They learned about the wave-function and operators, had their first contact with the mystics notation of quantum chemistry: the bra-ket notation. For the third bachelor chemistry, the course quantum and computational chemistry was centered around perturbation theory. In addition to the theory, we applied the method to the simple system of the infinite square potential.

The electron density in the primitive diamond unit cell.

In the master materiomics the course fundamentals of materials modeling was kicked into high gear, not only did the students learn the theory behind quantum mechanical modelling, they also had their fist experience on the supercomputers of the VSC. So in addition to the road from the standard Schrödinger equation to the Hohenberg-Kohn-Sham equations of DFT, they also traveled their first steps along the road from their somewhat familiar windows OS to the bash command-line environment of the HPC unix system.

Finally, as the course introduction into quantum chemistry is part of the preparatory program of the master materiomics, I started creating the narrated versions of those lectures as well (2h worth recording, corresponding to 4h of live lectures). As the available time is limited, we are going for single shot recordings which makes things exciting in that department as well.

At the end of this week, we have added another 7h of live lectures and 2h of video lectures, putting our semester total at 19h of lectures. Upwards and onward to week 3.

Materiomics Chronicles: week 1

The first week of the academic year at UHasselt has come to an end, while colleagues at UGent and KULeuven are still preparing for the start of their academic year next week. Good luck to all of you.

This week started full throttle for me, with classes for each of my six courses. After introductions in classes with new students (for me) in the second bachelor chemistry and first master materiomics, and a general overview in the different courses, we quickly dove into the subject at hand.

The second bachelor students (introduction to quantum chemistry) got a soft introduction into (some of) the historical events leading up to the birth of quantum mechanics such as the black body radiation, the atomic model and the nature of light. They encountered the duck-rabbit of particle-wave duality and awakened their basic math skills with the standing wave problem. For the third bachelor students, the course on quantum and computational chemistry started with a quick recap of the course introduction to quantum mechanics, making sure they are all again up to speed with concepts like braket-notation and commutator relations.

For the master materiomics it was also a busy week. We kicked of the 1st Ma course Fundamentals of materials modeling, which starts of calm and easy with a general picture of the role of computational research as third research paradigm. We discussed in which fields computational research can be found (flabbergasting students with an example in Theology: a collaboration between Sylvia Wenmackers & Helen De Cruz),  approximation vs idealization, examples of materials research at different scales, etc. As a homework assignment the students were introduced into the world of algorithms through the lecture of Hannah Fry (Should computers run the world). For the  2nd Ma, the courses on Density Functional Theory and Machine learning and artificial intelligence in modern materials science both started. The lecture of the former focused on the nuclear wave function and how we (don’t) deal with it in DFT, but still succeed in optimizing structures. During the lecture on AI we dove into the topics of regularization and learning curves, and extended on different types of ensemble models.

At the end of week 1, this brings me to a total of 12h of lectures. Upwards and onward to week 2.

Countdown to Materiomics: Year 2

Last year, we started a new masters program at Hasselt University called “Materiomics“. It is aimed at bachelor students in chemistry and physics who want to become the materials researchers of the future: interdisciplinary team players with experimental, theoretical, and computational skills ready to build anything made of atoms. There are four specialization tracks developed: Health, Energy, Quantum and Circularity. But passionate students can also develop their own line of study (in consultation with the mentor). The start of this new program was also a new start for myself, as I started as a new tenure track professor materiomics (specialized in computational materials science) assigned to the chemistry department. As a result, I spend most of my time creating new courses for the new first year of the masters program. This year, the second year is launched for the first time, and also here I have a significant contribution. Together with the courses I’m teaching in the bachelor Chemistry program, my first semester will be packed. I’ll be teaching & coordinating 6 courses (25 ECTS), three of them new,  and contributing to others as well:

  1. Introduction to quantum chemistry (2nd Ba. Chemistry)
  2. Quantum and computational chemistry (3rd Ba. Chemistry, new)
  3. Fundamentals of materials modeling (1st Ma. Materiomics)
  4. Properties of functional materials (1st Ma. Materiomics)
  5. Density functional theory: the workhorse of first principles modelling of solids and molecules (2nd Ma. Materiomics, new)
  6. Machine learning and artificial intelligence in modern materials science (2nd Ma. Materiomics, new)

As you can see, the central theme in these courses will be to introduce students into the realm of computational research, often at the quantum mechanical/chemical level.

On top of that, one of the first generation materiomics students will be performing a master thesis in my group, studying the GeV-defect in diamond. Bachelor students in chemistry and physics may join as well later with computational bachelor projects, but that is beyond my personal event horizon of the end of the first semester.

In the following weeks, you will be able to find a weekly review of my endeavors in this regard, providing some insights into what the students in chemistry and the master materiomics (Physics & Chemistry) are learning at Hasselt University.

E-MRS Spring meeting 2023

In march 2019, Belgium went into COVID-lock down while I attended the yearly diamond conference (SBDD25). Since then, I have been in a bit of a conference lock down myself as well. By visiting the 2023 spring meeting of E-MRS, this lock down has been lifted for international conferences (outside Belgium). Inside Belgium, there was already the DFT-2022 in Brussels, where I was also part of the National Scientific Committee, and of course SBDD26 & SBDD27, which as a diamond researcher you can not miss.

Coming back to Strassbourg for E-MRS brings back some memories, and generated some nice new ones. This year there was a nice Symposium called “Computations for materials – discovery, design and the role of data“[program] which got my full attention. During the first session on AI-accelerated Materials discovery, I had the pleasure to present some of my own work on the Machine Learning of small data sets (cf. papers on the average model, and UV-curable inks). The symposium was nicely coinciding with much of my interest, and showed two (not unexpected, and maybe symposium biased) trends:

  1.  There is an important evolution toward lab-automation and use of robotics (people don’t want to manually build dozens of battery cells or perform hundreds of repetitive synthesis experiments for materials optimization. This shows the future materials scientist, be it a chemist, physicist or engineer will have to become a robotics and/or programming expert as well. This only strengthens me in my vision for our materiomics [NL] students at UHasselt. These skills will be essential for their future scientific career development.
  2. Machine Learning and Artificial Intelligence will play an important role in future materials design. However, we need a better understanding of what we are doing, and not just use any method and accept it as “excellent” because the R² value is high. For now, we can still get away with the latter, but this will not last much longer. It will become more important to have a simple but interpretable model, rather than a complex (over-fitting) Deep Learning Neural Network without understanding of the underlying physics and chemistry. Also here we will have to put in some effort within the materiomics program.

 

So after an interesting International conference, and making some new contacts…it is time to return home, four more courses need to be prepared from scratch for coming academic year.

Review of 2022

Happy New Year

2022 has been a year of many firsts. Most importantly, it is the year I started as a tenure track professor (i.e. assistant professor) starting the QuATOMs group at Hasselt University. In addition, this is the first year the new master materiomics program at UHasselt was provided. In this program, I’m responsible for the theoretical and computational components of materials research, and thus teaching several new classes which are unique in the world. Next year, the second master year will start, with more classes to create.

But before we launch into these new and interesting times, lets look back at 2022 one last time, keeping up with  tradition. What have I done during the last year of academic merit.

1. Publications: +4 (and currently a handful in progress)

2. Cover publication: +1

Cover Polymer International: Machine learning on small data sets, application on UV curable inks.

Cover Polymer International: Machine learning on small data sets, application on UV curable inks.

  • Danny E.P. Vanpoucke, Marie A.F. Delgove, Jules Stouten, Jurrie Noordijk, Nils De Vos, Kamiel Matthysen, Geert G.P. Deroover, Siamak Mehrkanoon, and Katrien V. Bernaerts,
    Polymer International 71(8), i-i (2022),
    doi: 10.1002/pi.6434 {IF(2021)=3.213}

3. Project proposals accepted: +1

  • Digitization of lignin polyurethane development (DigiLignin), in a consortium with Maastricht University and VITO.

4. Completed refereeing tasks: +12

  • Optical Materials
  • Journal of Applied Physics (2x)
  • Frontiers in Physics
  • Journal of Physics: Condensed Matter (2x)
  • Diamond and Related Materials (6x)

5. Conferences & seminars: +3/+1 (Attended & Organised)

With regard to conferences, 2022 was the year everyone wanted to go back to “normalcy”, though COVID is still very much present.

  • SBDD XXVI, Hasselt University, Belgium, March 9th-11th, 2022 [poster presentation, PhD student]
  • BPS-2022, Tabloo Science expo (SCK-CEN), Belgium, May 18th, 2022 [oral presentation]
  • DFT-2022: 19th International Conference on Density Functional Theory and its Applications, Brussels, Belgium, August 28th-September 2nd, 2022. [member of National Organization Committee; poster]
  • VUB-virtual seminar @ALGC group (F. De Proft), Online, November 29th, 2022 [invited seminar presentation]

6. Current size of HIVE:

  • 62K lines of program (code: 69 %)
  • ~100 files
  • 50 (command line) options

7. Hive-STM program:

And now, upward and onward, a new year, a fresh start.

Elucidating the optimized P2 type Na0.67Mn1−xCuxO2 cathode active material via operando XAS

Authors: S. Altin, S. Altundag, E. Altin, D. E. P. Vanpoucke, S. Avci, and M. N. Ates
Journal: Journal of Alloys and Compounds 936, 168138 (2023)
doi: 10.1016/j.jallcom.2022.168138
IF(2021): 6.371
export: bibtex
pdf: <J. Alloys Compd.>

Abstract

Here we report on the structural and electrochemical properties of P2-type Na0.67Mn1−xCuxO2 (where x = 0.20–0.50) via various techniques. X-ray diffraction (XRD) reveals a reduction of the unit cell volume upon substitution of Cu elucidated through detailed Rietveld analysis. The cyclic voltammetry (CV) behavior is also affected by the Cu substitution indicating new redox reactions stemming from Cu substitution. Galvanostatic cycling measurements at room temperature show that when x = 0.35 in a P2-type Na0.67Mn1−xCuxO2 cathode active material, the best electrochemical performance is obtained. The Na-ion diffusion rate is found to be strongly dependent upon the environmental temperature. Changes in the
valence state and the local structures of P2-type Na0.67Mn1−xCuxO2 during the charge/discharge are investigated through the operando X-ray absorption spectroscopy (XAS) technique.

 

Python Tutorial: Child Classes

In the previous tutorial of the wordle-mania-series, we had a quick overview of how to construct a basic class in Python. Here we take our class adventure a step further and implement a child class. As before, the full source of this project can be found in our GitHub repo.

1. Building a child class.

The construction of a child class is near identical to the construction of a non-child class. The only difference being we need to somehow indicate the class is derived from another class. During our previous tutorial, we created the WordleAssistant class, so let’s use it as a parent for the WordleAssistant2 child class.

from .WordleAssistant import WordleAssistant

class WordleAssistant2(WordleAssistant):
    pass

First, note that we need to import the WordleAssistant class, which is stored in a file WordleAssistant.py, contained in the same folder as the file containing our child class (hence the “.” in front of WordleAssistant). At this point, most python developers will hate me for using the same name for what is considered a module and a class, as you could put multiple classes in a single file. Then again, once you start writing object oriented code, it is good practice to put only one class in a single file, which makes it rather strange to use different names.

Second, we put parent class between the brackets of the child class. Through this simple action, and the magic of inheritance, we just created an entirely new class containing all functions and functionality of the parent class. The keyword pass is used to indicate no further methods and attributes will be added.

2. Child class individuality.

Of course, we want our child class to not be just a wrapper of the parent class. The choice to use a child class can be twofold:

    1.  Extension of an existing class. This can either be because you are not the developer of the parent class, or (in case you are the developer) because you don’t want to accidentally destroy a working piece of software (c.q. parent class) while trying out some new features, or …
    2. Modification/implementation of specific class behavior. The standard (trivial) examples involve drawing classes, which in one child class draw circles, while in another it draws squares.
    3. Both of the above.

In our case, we are going to ‘upgrade‘ our WordleAssistant class by considering the prevalence of every letter at the specific position in the 5-letter word. This in contrast to our original implementation which only considered the prevalence of a letter anywhere in the word. Adding new functionality with “new” methods and attributes, happens as for the parent class. You just define the new methods and attributes, which should have names that differ from the names for methods and attributes already used by the parent class.

However, sometimes, you may want or have to modify existing methods. You can either replace the entire functionality overwriting that of the parent method, or you may extend that functionality.

2.1. Extending methods.

When you still want to make use of the functionality of the method of the parent class you could just copy that code, and add your own code to extend it. This however makes your code hard to maintain, as each time the parent class code is modified, you would need to modify your child class as well. This increases the risk of breaking the code. Luckily, similar as programming languages like C++ and Object Pascal,  there is a useful trick which allows you to wrap the parent class code in your overwritten child class method. A location where this trick is most often used is the initialization method. Below you can see the __init__ function of the  WordleAssistant2 child class.

def __init__(self, size: int = 5, dictionary : str = None ):
    super().__init__(size, dictionary)
    self.FullLettPrevSite = self._letterDistSite(self.FullWorddict)
    self.CurLettPrevSite = copy.deepcopy(self.FullLettPrevSite)

The super() function indicates we are going to access the methods of the parent of the class we are working in at the moment. The super().__init__() method therefor refers to the __init__ method of the WordleAssistant class. This means the __init__ method of the WordleAssistant2 child class will first perform the __init__ method of the WordleAssistant class and then execute the following two statements which initialize our new attributes. Pretty simple, and very efficient.

2.2. Overwriting methods.

In some cases, you don’t want to retain anything of the parent method. By overwriting a method, your child class will now use a totally new code which does not retain any functionality of the parent method. Note that in the previous section we were also overwriting the __init__ method, but we retained some functionality via the call using super(). An example case of a full overwrite is found in the _calcScore method:

def _calcScore(self, WD: dict, LP: list):
    for key in WD:
        WD[key]['score'] = 0
        for i in range(self.WordleSize):
            WD[key]['score'] += self.CurLettPrevSite[i][WD[key]['letters'][i]]

Although this method can still make use of attributes (self.WordleSize) and methods of the parent class, the implementation is very different and unrelated to that of the parent class. This is especially true in case of the python scripting language. Where a programming language like C++ or Object Pascal will require you to return the same type of result (e.g. the parent class returns an integer, then the child class can not return a string, or even a float.), python does not care.  It places the burden of checking this downstream: i.e. with the user. As a developer, it is therefore good practice to be better than standard python and take away as much of this burden from the future users of your code (which could be your future self.)

Finally, a small word of caution with regard to name mangling. Methods with two leading underscores can not be overwritten in the child class in the sense that these methods are not accessible outside the parent class. This means also inside a child class these methods are out of scope. If we had a __calcScore method instead, creating an additional __calcScore in our child class would give rise to a lot of confusion (for python and yourself) and unexpected behavior.

3. Additional sources:

Python Tutorial: Classes

Python, as any other scripting language allows you to define variables and functions. These are very basic entities when it comes to programming. However, sometimes it is useful to keep variables and functions that are related to one-another close together. This is the main idea behind Object Oriented programming and is present in programming languages such as C++ and fortran, but also in scripting languages like java and python. In this tutorial, you can find a first brief introduction into this topic, focusing on the concept of a class. 

This tutorial is part of a series of tutorials and the code is available via GitHub. As a real life example, used throughout this series, we consider a class for solving a wordle-puzzle.

1. The Python class

A class is a complex variable type, which contains specific methods (or functions) and attributes (or properties). An instance of such a complex variable is called an object, and different objects can have different values for their attributes (and even methods).

To create a class in python the class keyword is used followed by the name you want to assign your class. In our case this is the WordleAssistant class.

class WordleAssistant():

Defining attributes

This WordleAssistant contains the attributes relevant to our puzzle solver. For example, if we want to make a generic solver, two useful attributes would be the wordle word length (WordleSize) and a dictionary of possible words (FullWordset). Unlike fortran or C++, attributes are not defined in the class definition, but can be dynamically created for a class-object. This a feature (or design flaw) gives rise to some dangerous practices such as the runtime (accidental) addition of attributes to an object. For good practices, one should refrain from this and create all attributes by initializing them during the initialization of the class instance. This is done using the __init__() method of the class:

class WordleAssistant():
    def __init__(self, size: int = 5, dictionary: str = None):
        self.WordleSize = size
        if dictionary is None:
            dictionary = "Mydict.txt"
        self.FullWordset = self.readDictionary(dictionary)

Here the WordleSize attribute is defined by setting it to the size parameter of the __init__ method, while the FullWordset attribute is defined by assigning it the result of the readDictionary method of the WordleAssistant class. As is common (and good) practice in OO langues we use the self variable to indicate the instance of the class, binding attributes and methods to the instance. You may also have noted python uses a dot-notation to indicate attributes/methods of a class, similar as C++ (while fortran uses the % symbol with the same effect).

!! NOTE: There also exist “class attributes” which are defined the way one would define instance attributes in fortran or C++. However, in python these attributes are shared by all instances of the class, as such changing them in one object will change them in all objects, creating a mess.

Defining methods

In the previous section, we already defined a first method, the initialization method. As a method is a function, it is constructed as any other function in python using the def keyword, with the body indented. The method itself is indented one level with respect to the class level. Similar as for a usual function, one can indicate the expected type and default value for each function parameter, and if a result is returned the type can be indicated as well, as can be seen in the example below for the readDictionary method.

class WordleAssistant():
    def __init__(self, size: int = 5, dictionary: str = None):
        ...

    def readDictionary(self, wordlist: str = None)->list:
        ...
        return wordlist 

Privacy

Although private attributes and methods don’t technically exist in Python, it is convention that attributes and methods prefixed with a single underscore are to be treated as non-public parts of the API. In addition, using two or more underscores gives rise to name mangling, which gives a practical behavior akin to making attributes and methods private. The __init__ method above is an example. We will come back to this when discussing inheritance and child classes.

2. The Python Object

Once the class is implemented, it can be used in a script by creating instances of the class. These instances are called Objects.

WA = WordleAssistant()

The above command creates an object WA which is of the class WordleAssistant. The object is initialized through a call to the __init__ method, which is performed by the assignment above. If defaults are provided for all parameters of the __init__ method, then no variables need to be passed to the WordleAssistant class call. Otherwise the creation of an instance could look like this:

wordleSize = 5
WA = WordleAssistant(size=wordleSize,dictionary='MyWords.txt')

Access to the attributes and methods of the WA object s gained using the dot-notation:

wordsize = WA.WordleSize 
wordlist = WA.FullWordset
Top10Guess = WA.getTop(top = 10)

Within the context of data-encapsulation one should never access attributes directly but use get and set methods instead.

3. Additional sources:

Wordle-mania: an opportunity for python programming and artificial intelligence.

Over that last few months the wordle game has become increasingly popular, with people sharing their daily feats on Twitter. Currently the game is hosted by the NY times which bought it the end of January 2022 from its creator.  The game is rather straightforward: you have 6 guesses to find a 5-letter English word. Every guess, the game tells you if a letter is (1) not in the word [grey], (2) in the word at a different position [yellow/orange], or (3) in the word at the exact same position [green].

Wordle 242 4/6
⬛⬛🟨⬛⬛
⬛🟨⬛⬛⬛
⬛⬛🟩🟨🟩
🟩🟩🟩🟩🟩
An example of the result (as it looks when shared on Twitter). My first guess was the word “PIANO”, which means the A is in the word but at a different position. My second word, “QUERY”, adds the U to the list of letters that are present. With my third guess, “STUCK”, the position of the U and the K are fixed and we now also know the letter C is involved. At this point, I was also stuck, so I got some help of my wordle-assistant program, which taught me there could only be 1 word matching all the information we had: “CAULK“.

This seamlessly brings me to the central topic of this post: writing a program to help win this game as efficiently as possible. Not terribly original, but it’s a means to an end, as this simple project allows us to explore some more advanced topics in programming in python as well as artificial intelligence.

During this exploration I’ll  be including and updating a set of tutorials as well as this post. The python side of the project will focus on efficiency and easy of use and distribution, while the AI side will focus on smart ways predicting the best possible next guess. For the latter, an important caveat is that this means that the program should also work if you’re the last player living on earth, or if you decide to play wordle in a different language or a different number of letters. This means that creating a distribution of the  tweeted results of other players and comparing this with the complete set of brute-forced distributions to guess the wordle of the day in a single guess, would not satisfy my definition of AI. It is an interesting Big-data kaggle competition though.

Python Tutorials

  • Classes in Python. This tutorial provides a simple introduction in the concept of classes in python.
  • Child Classes. Continuing on the previous we deal now with child classes and the intricacies of function overriding and accessibility.
  • Python Library on Github.
  • Jupyter Notebook examples.
  • Slow Python: Profiling python in Jupyter. We look into profiling a Jupyter notebook script, to find the bottlenecks.
  • Slow Python: speeding up copying.

 

Artificial Intelligence

  • Distributions of words and letters.
  • Information theory of wordle?

 

The WordleAssistant Library and notebooks.

All tutorial code and jupyter notebooks can be found in this github repository.

TEDx Talk: The Virtual Lab

Happy to announce my TEDxUHasselt talk is officially part of the TEDx universe:  https://www.ted.com/talks/danny_vanpoucke_the_virtual_lab .

I enjoyed talking about the VirtualLab. Showed examples from atoms to galaxies, from computer-chips to drug-design and from to opinion-dynamics to epidemiology. I looked at the past and and glanced towards the future, where machine learning and artificial intelligence are the new kids on the block.