Some tests with GFN2-xTB

GFN2-xTB [10.1021/acs.jctc.8b01176] is a strange model. I have been testing GFN1 and GFN2 on OOH adsorption on Pt(111). GFN1 from TBLITE with ASE works well. It converges and optimizes to meaningful structures. GFN2 however behaves odd in terms of convergence and optimization. For instance, O–H bond becomes broken. I have tested GFN2 also with xtb, for which the input is quite complicated in comparison to ASE inputs. Anyway, it worked only when I specified the periodic conditions in both xtb.inp and Pt-OOH.coord files. Then I executed xtb like this:

xtb Pt-OOH.coord --gfn2 --tblite --opt --periodic --input xtb.inp
Optimization of Pt(111)–OOH with GFN2-xTB (xtb) resulting in O–H bond dissociation.

P.S. You can see that Pt(111) surface corrugates in case of my 2×2 model. For wider models, the surface remains flat.

Zotero + chatGPT via pdfGEAR

Some time ago (in 2023), I linked Zotero with chatGPT by creating an environment with paper-qa and pyzotero like this:
conda create -n Zotero
conda activate Zotero
conda install pip
pip install paper-qa
pip install pyzotero
pip install bs4

That worked but felt way too complicated … like I am not going to use it on a daily basis. It also reminded me the very first experience with the Meta AI in late 2022 (which everyone already forgot).

Here is a much simpler recipe:

  1. Install Zotero add-on from github.com/retorquere/zotero-open-pdf to enable opening with external pdf viewers.
  2. Install pdfGEAR as your default pdf viewer (external to Zotero).

See how it works on my YouTube channel: youtu.be/4JSy2RsBLDE?si=Hbj7oq7gaOiq6END

Fonts for grant proposals

The reference font for the body text of European proposals is Times New Roman (Windows platforms), Times/Times New Roman (Apple platforms) or Nimbus Roman No. 9 L (Linux distributions). The Roman family is from a pre-digital age and has well-recognizable features.

Is it the best font in terms of readability? On the one hand, there is a tendency to move from Times-type fonts to plainer fonts, like Calibri. On the other hand, many studies (with controversial results) account for aspects like Dyslexia, typeface anatomy, and Display vs. Print. The effect of font choice on readability and compression on big numbers seems small or insignificant. However, my point is that a proposal must be clear to a few reviewers, who might have difficulties understanding the proposal due to age, Dyslexia, and colour vision deficiency. These few people will have some feelings about how the text is formatted. For that reason and also because of my artistic education in caligraphy, I have been looking for and playing with font combinations for a long time. Here is what I have tried and liked.

1. STIX two and Source Sans form a pair of Serif and Sans fonts. STIX two resulted from a collaborative effort from the most prominent academic publishing companies. Its predecessor (STIX one) has exactly the same metrics as Times New Roman. STIX two is somewhat bigger, which is not prohibited by the EU funding agencies. The main benefit of using STIX fonts is that these are mathematical fonts and, thus, can be natively used in MS Equation Editor (instead of Cambria) and LaTeX (as XITS or STIX2).

2. An excellent substitution for Times New Roman is Zilla Slab – a unique font by the Mozilla foundation – which has the same metrics as Times New Roman, is a Sans font, yet looks like a monospace one, does have features of a Dyslexia-friendly typeface, and looks great in print and on screen. It is freely available from Google fonts. It can be used with Times New Roman (or similar) as a pair of Serif and Sans fonts.

3. Libertinus Serif + Gill Sans is my favourite Serif and Sans pair. You can see Linux Libertine in the Wikipedia logo. Gill Sans Nova is commonly fond in the University of Tartu (Estonia) press. Although Libertinus Serif has an original Sans counterpart, its combination with Gill Sans looks most natural. I love Libertinus because of its amazingly looking ligatures, and it is also compatible with MS Equation Editor and LaTeX.

PS One can play with fonts in the EU projects to make their proposal more appealing. Like Estonian grants, I prefer calls, where applicants fill out online forms without changing the text appearance. Of course, the text looks ugly due to nasty line breaks, horrible chemical formulas and mathematical equations, and poor typography. Still, the competition is more fair because everyone is in the same conditions. 

Reference style for an MSCA proposal

Dani Bodor created a nice reference style that is suitable for writing an MSCA proposal:

marie-sklodowska-curie-actions.csl

See forums.zotero.org/discussion/73275/foot-notes-for-a-marie-curie-application.

This style is similar to what I used in my LaTeX template:

www.overleaf.com/latex/templates/msca-template/dskmdjpzbhkg

Here is the code for that style:

<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="note" version="1.0" demote-non-dropping-particle="never" page-range-format="chicago" default-locale="en-GB">
  <!-- This style was edited with the Visual CSL Editor (http://editor.citationstyles.org/visualEditor/) -->
  <info>
    <title>Marie Skłodowska-Curie actions</title>
    <id>http://www.zotero.org/styles/marie-sklodowska-curie-actions</id>
    <link href="http://www.zotero.org/styles/marie-sklodowska-curie-actions" rel="self"/>
    <link href="https://forums.zotero.org/discussion/comment/262041/#Comment_262041" rel="documentation"/>
    <author>
      <name>Dani Bodor</name>
      <email>d.bodor@ucl.ac.uk</email>
    </author>
    <category citation-format="note"/>
    <category field="generic-base"/>
    <summary>For use in application to H2020 Marie Skłodowska-Curie Actions fellowship</summary>
    <updated>2017-07-31T17:37:20+00:00</updated>
    <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
  </info>
  <locale xml:lang="en">
    <terms>
      <term name="editor" form="verb-short">ed.</term>
      <term name="translator" form="verb-short">trans.</term>
      <term name="editortranslator" form="verb-short">
        <single>ed. and trans.</single>
        <multiple>ed. and trans.</multiple>
      </term>
      <term name="editortranslator" form="verb">
        <single>Edited and translated by</single>
        <multiple>Edited and translated by</multiple>
      </term>
      <term name="translator" form="short">trans.</term>
    </terms>
  </locale>
  <macro name="secondary-contributors">
    <choose>
      <if type="chapter paper-conference" match="none">
        <names variable="editor translator" delimiter=". ">
          <label form="verb" text-case="capitalize-first" suffix=" "/>
          <name and="text" delimiter=", "/>
        </names>
      </if>
    </choose>
  </macro>
  <macro name="container-contributors">
    <choose>
      <if type="chapter paper-conference" match="any">
        <group delimiter=", ">
          <choose>
            <if variable="author">
              <choose>
                <if variable="container-author" match="any">
                  <names variable="container-author">
                    <label form="verb-short" text-case="lowercase" suffix=" "/>
                    <name and="text" delimiter=", "/>
                  </names>
                </if>
              </choose>
              <choose>
                <if variable="container-author author" match="all">
                  <group delimiter=". ">
                    <text variable="page"/>
                    <names variable="editor translator" delimiter=", ">
                      <label form="verb" suffix=" "/>
                      <name and="text" delimiter=", "/>
                    </names>
                  </group>
                </if>
                <else>
                  <names variable="editor translator" delimiter=", ">
                    <label form="verb" text-case="lowercase" suffix=" "/>
                    <name and="text" delimiter=", "/>
                  </names>
                </else>
              </choose>
            </if>
          </choose>
        </group>
      </if>
    </choose>
  </macro>
  <macro name="recipient-note">
    <names variable="recipient" delimiter=", ">
      <label form="verb" text-case="lowercase" suffix=" "/>
      <name and="text" delimiter=", "/>
    </names>
  </macro>
  <macro name="editor">
    <names variable="editor">
      <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
      <label form="short" prefix=", "/>
    </names>
  </macro>
  <macro name="translator">
    <names variable="translator">
      <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
      <label form="verb-short" prefix=", "/>
    </names>
  </macro>
  <macro name="recipient">
    <group delimiter=" ">
      <choose>
        <if type="personal_communication">
          <choose>
            <if variable="genre">
              <text variable="genre" text-case="capitalize-first"/>
            </if>
            <else>
              <text term="letter" text-case="capitalize-first"/>
            </else>
          </choose>
        </if>
      </choose>
      <text macro="recipient-note"/>
    </group>
  </macro>
  <macro name="contributors">
    <group delimiter=". ">
      <names variable="author">
        <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
        <substitute>
          <text macro="editor"/>
          <text macro="translator"/>
        </substitute>
      </names>
      <text macro="recipient"/>
    </group>
  </macro>
  <macro name="recipient-short">
    <names variable="recipient">
      <label form="verb" text-case="lowercase" suffix=" "/>
      <name form="short" and="text" delimiter=", "/>
    </names>
  </macro>
  <macro name="contributors-short">
    <group delimiter=" ">
      <names variable="author">
        <name form="short" and="symbol"/>
        <substitute>
          <names variable="editor"/>
          <names variable="translator"/>
        </substitute>
      </names>
      <text macro="recipient-short"/>
    </group>
  </macro>
  <macro name="interviewer">
    <names variable="interviewer" delimiter=", ">
      <label form="verb" text-case="capitalize-first" suffix=" "/>
      <name and="text" delimiter=", "/>
    </names>
  </macro>
  <macro name="title">
    <choose>
      <if variable="title" match="none">
        <choose>
          <if type="personal_communication" match="none">
            <text variable="genre" text-case="capitalize-first"/>
          </if>
        </choose>
      </if>
      <else-if type="bill book graphic legislation motion_picture song" match="any">
        <text variable="title" text-case="title" font-style="italic"/>
        <group prefix=" (" suffix=")" delimiter=" ">
          <text term="version"/>
          <text variable="version"/>
        </group>
      </else-if>
      <else-if variable="reviewed-author">
        <group delimiter=", ">
          <text variable="title" font-style="italic" prefix="Review of "/>
          <names variable="reviewed-author">
            <label form="verb-short" text-case="lowercase" suffix=" "/>
            <name and="text" delimiter=", "/>
          </names>
        </group>
      </else-if>
      <else-if type="legal_case interview patent" match="any">
        <text variable="title"/>
      </else-if>
      <else>
        <text variable="title" text-case="title" quotes="true"/>
      </else>
    </choose>
  </macro>
  <macro name="description">
    <group delimiter=", ">
      <group delimiter=". ">
        <text macro="interviewer"/>
        <text variable="medium" text-case="capitalize-first"/>
      </group>
      <choose>
        <if variable="title" match="none"/>
        <else-if type="thesis speech" match="any"/>
        <else-if type="patent">
          <group delimiter=" ">
            <text variable="authority"/>
            <text variable="number"/>
          </group>
        </else-if>
        <else>
          <text variable="genre" text-case="capitalize-first"/>
        </else>
      </choose>
    </group>
  </macro>
  <macro name="container-title">
    <group delimiter=" ">
      <choose>
        <if type="chapter paper-conference" match="any">
          <text term="in" text-case="capitalize-first"/>
        </if>
      </choose>
      <choose>
        <if type="legal_case" match="none">
          <text variable="container-title" text-case="title" font-style="italic"/>
        </if>
      </choose>
    </group>
  </macro>
  <macro name="collection-title">
    <choose>
      <if match="none" type="article-journal">
        <choose>
          <if match="none" is-numeric="collection-number">
            <group delimiter=", ">
              <text variable="collection-title" text-case="title"/>
              <text variable="collection-number"/>
            </group>
          </if>
          <else>
            <group delimiter=" ">
              <text variable="collection-title" text-case="title"/>
              <text variable="collection-number"/>
            </group>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="collection-title-journal">
    <choose>
      <if type="article-journal">
        <group delimiter=" ">
          <text variable="collection-title"/>
          <text variable="collection-number"/>
        </group>
      </if>
    </choose>
  </macro>
  <macro name="edition-note">
    <choose>
      <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
        <choose>
          <if is-numeric="edition">
            <group delimiter=" ">
              <number variable="edition" form="ordinal"/>
              <text term="edition" form="short"/>
            </group>
          </if>
          <else>
            <text variable="edition"/>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="edition">
    <choose>
      <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
        <choose>
          <if is-numeric="edition">
            <group delimiter=" ">
              <number variable="edition" form="ordinal"/>
              <text term="edition" form="short"/>
            </group>
          </if>
          <else>
            <text variable="edition" text-case="capitalize-first" suffix="."/>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="locators-note">
    <choose>
      <if type="article-journal">
        <group delimiter=", ">
          <text macro="collection-title-journal"/>
          <number variable="volume"/>
          <group delimiter=" ">
            <text term="issue" form="short"/>
            <number variable="issue"/>
          </group>
        </group>
      </if>
      <else-if type="legal_case">
        <group delimiter=", ">
          <group delimiter=" ">
            <number variable="volume"/>
            <text variable="container-title"/>
            <text variable="page"/>
          </group>
          <text variable="locator"/>
        </group>
      </else-if>
      <else-if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
        <group delimiter=", ">
          <text macro="edition-note"/>
          <group delimiter=" ">
            <text term="volume" form="short"/>
            <number variable="volume" form="numeric"/>
          </group>
          <choose>
            <if variable="locator" match="none">
              <group delimiter=" ">
                <number variable="number-of-volumes" form="numeric"/>
                <text term="volume" form="short" plural="true"/>
              </group>
            </if>
          </choose>
        </group>
      </else-if>
    </choose>
  </macro>
  <macro name="locators-join-with-space">
    <choose>
      <if type="article-journal" variable="volume" match="all">
        <choose>
          <if match="none" variable="collection-title">
            <text macro="locators"/>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="locators-join-with-comma">
    <choose>
      <if type="legal_case chapter paper-conference" match="any">
        <text macro="locators"/>
      </if>
      <else-if type="article-journal">
        <choose>
          <if variable="volume" match="none">
            <text macro="locators"/>
          </if>
          <else-if match="any" variable="collection-title">
            <text macro="locators"/>
          </else-if>
        </choose>
      </else-if>
    </choose>
  </macro>
  <macro name="locators-join-with-period">
    <choose>
      <if type="legal_case article-journal chapter paper-conference" match="none">
        <text macro="locators"/>
      </if>
    </choose>
  </macro>
  <macro name="locators">
    <choose>
      <if type="article-journal">
        <group delimiter=", ">
          <text macro="collection-title-journal"/>
          <number variable="volume"/>
          <group delimiter=" ">
            <text term="issue" form="short"/>
            <number variable="issue"/>
          </group>
        </group>
      </if>
      <else-if type="legal_case">
        <group delimiter=" ">
          <number variable="volume"/>
          <text variable="container-title"/>
          <text variable="page"/>
        </group>
      </else-if>
      <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
        <group delimiter=". ">
          <text macro="edition"/>
          <group delimiter=" ">
            <text term="volume" form="short" text-case="capitalize-first"/>
            <number variable="volume" form="numeric"/>
          </group>
          <group delimiter=" ">
            <number variable="number-of-volumes" form="numeric"/>
            <text term="volume" form="short" plural="true"/>
          </group>
        </group>
      </else-if>
      <else-if type="chapter paper-conference" match="any">
        <group delimiter=". ">
          <text macro="edition"/>
          <choose>
            <if variable="page" match="none">
              <group delimiter=" ">
                <text term="volume" form="short" text-case="capitalize-first"/>
                <number variable="volume" form="numeric"/>
              </group>
            </if>
          </choose>
        </group>
      </else-if>
    </choose>
  </macro>
  <macro name="locators-newspaper">
    <choose>
      <if type="article-newspaper">
        <group delimiter=", ">
          <group delimiter=" ">
            <number variable="edition"/>
            <text term="edition"/>
          </group>
          <group delimiter=" ">
            <text term="section" form="short"/>
            <text variable="section"/>
          </group>
        </group>
      </if>
    </choose>
  </macro>
  <macro name="event">
    <choose>
      <if variable="title">
        <group delimiter=" ">
          <text term="presented at"/>
          <text variable="event"/>
        </group>
      </if>
      <else>
        <group delimiter=" ">
          <text term="presented at" text-case="capitalize-first"/>
          <text variable="event"/>
        </group>
      </else>
    </choose>
  </macro>
  <macro name="originally-published">
    <group delimiter=", ">
      <group delimiter=": ">
        <text variable="original-publisher-place"/>
        <text variable="original-publisher"/>
      </group>
      <date variable="original-date" form="text" date-parts="year"/>
    </group>
  </macro>
  <macro name="reprint">
    <choose>
      <if variable="original-date issued" match="all">
        <text value="reprint" text-case="capitalize-first"/>
      </if>
    </choose>
  </macro>
  <macro name="publisher">
    <choose>
      <if type="thesis">
        <text variable="publisher"/>
      </if>
      <else-if type="speech">
        <text variable="event-place"/>
      </else-if>
      <else>
        <group delimiter=": ">
          <text variable="publisher-place"/>
          <text variable="publisher"/>
        </group>
      </else>
    </choose>
  </macro>
  <macro name="issued">
    <choose>
      <if variable="issued">
        <choose>
          <if type="graphic report" match="any">
            <date variable="issued" form="text"/>
          </if>
          <else-if type="legal_case">
            <group delimiter=" ">
              <text variable="authority"/>
              <date variable="issued">
                <date-part name="year"/>
              </date>
            </group>
          </else-if>
          <else-if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song thesis" match="any">
            <date variable="issued">
              <date-part name="year"/>
            </date>
          </else-if>
          <else-if type="patent">
            <group delimiter=", ">
              <group delimiter=" ">
                <text value="filed"/>
                <date variable="submitted" form="text"/>
              </group>
              <group delimiter=" ">
                <choose>
                  <if variable="issued submitted" match="all">
                    <text term="and"/>
                  </if>
                </choose>
                <text value="issued"/>
                <date variable="issued" form="text"/>
              </group>
            </group>
          </else-if>
          <else>
            <date variable="issued" form="text"/>
          </else>
        </choose>
      </if>
      <else-if variable="status">
        <text variable="status"/>
      </else-if>
      <else-if variable="accessed URL" match="all"/>
      <else>
        <text term="no date" form="short"/>
      </else>
    </choose>
  </macro>
  <macro name="point-locators-subsequent">
    <choose>
      <if type="legal_case"/>
      <else-if variable="locator">
        <choose>
          <if locator="page" match="none">
            <group delimiter=" ">
              <choose>
                <if type="bill book graphic legislation motion_picture report song" match="any">
                  <choose>
                    <if variable="volume">
                      <group delimiter=", ">
                        <group delimiter=" ">
                          <text term="volume" form="short"/>
                          <number variable="volume" form="numeric"/>
                        </group>
                        <label variable="locator" form="short"/>
                      </group>
                    </if>
                    <else>
                      <label variable="locator" form="short"/>
                    </else>
                  </choose>
                </if>
                <else>
                  <label variable="locator" form="short"/>
                </else>
              </choose>
              <text variable="locator"/>
            </group>
          </if>
          <else-if type="bill book graphic legislation motion_picture report song" match="any">
            <group delimiter=":">
              <number variable="volume" form="numeric"/>
              <text variable="locator"/>
            </group>
          </else-if>
          <else>
            <text variable="locator"/>
          </else>
        </choose>
      </else-if>
    </choose>
  </macro>
  <macro name="locators-chapter">
    <choose>
      <if type="chapter paper-conference" match="any">
        <choose>
          <if variable="author container-author" match="all"/>
          <else>
            <choose>
              <if variable="page">
                <number variable="volume" suffix=":"/>
                <text variable="page"/>
              </if>
            </choose>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="locators-journal-join-with-colon">
    <choose>
      <if type="article-journal">
        <choose>
          <if variable="volume issue" match="any">
            <text variable="page"/>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="locators-journal-join-with-comma">
    <choose>
      <if type="article-journal">
        <choose>
          <if variable="volume issue" match="none">
            <text variable="page"/>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="archive">
    <choose>
      <if type="thesis">
        <group delimiter=" ">
          <text variable="archive"/>
          <text variable="archive_location" prefix="(" suffix=")"/>
        </group>
      </if>
      <else>
        <group delimiter=". ">
          <text variable="archive_location" text-case="capitalize-first"/>
          <text variable="archive"/>
          <text variable="archive-place"/>
        </group>
      </else>
    </choose>
  </macro>
  <macro name="issue-join-with-space">
    <choose>
      <if type="article-journal legal_case" match="any">
        <choose>
          <if variable="issue volume" match="any">
            <text macro="issue"/>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="issue-join-with-period">
    <choose>
      <if type="article-journal legal_case" match="none">
        <choose>
          <if type="speech" variable="publisher publisher-place" match="any">
            <text macro="issue"/>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="issue-join-with-comma">
    <choose>
      <if type="article-journal legal_case" match="none">
        <choose>
          <if type="speech" variable="publisher publisher-place" match="none">
            <text macro="issue"/>
          </if>
        </choose>
      </if>
      <else-if variable="volume issue" match="none">
        <text macro="issue"/>
      </else-if>
    </choose>
  </macro>
  <macro name="issue">
    <choose>
      <if type="legal_case" match="any">
        <text macro="issued" prefix="(" suffix=")"/>
      </if>
      <else-if type="article-journal">
        <choose>
          <if variable="issue volume" match="any">
            <text macro="issued" prefix="(" suffix=")"/>
          </if>
          <else>
            <text macro="issued"/>
          </else>
        </choose>
      </else-if>
      <else-if type="speech">
        <group delimiter=", ">
          <group delimiter=" ">
            <choose>
              <if variable="title" match="none"/>
              <else>
                <text variable="genre" text-case="capitalize-first"/>
              </else>
            </choose>
            <text macro="event"/>
          </group>
          <text variable="event-place"/>
          <text macro="issued"/>
        </group>
      </else-if>
      <else-if type="article-newspaper">
        <text macro="issued"/>
      </else-if>
      <else-if variable="publisher-place publisher" match="any">
        <group delimiter=", ">
          <choose>
            <if type="thesis">
              <text variable="genre" text-case="capitalize-first"/>
            </if>
          </choose>
          <group delimiter=". ">
            <text macro="originally-published"/>
            <group delimiter=", ">
              <text macro="reprint"/>
              <text macro="publisher"/>
            </group>
          </group>
          <text macro="issued"/>
        </group>
      </else-if>
      <else>
        <text macro="issued"/>
      </else>
    </choose>
  </macro>
  <macro name="access">
    <group delimiter=". ">
      <choose>
        <if type="graphic report" match="any">
          <text macro="archive"/>
        </if>
        <else-if type="article-journal bill book chapter legal_case legislation motion_picture paper-conference" match="none">
          <text macro="archive"/>
        </else-if>
      </choose>
      <choose>
        <if variable="issued" match="none">
          <group delimiter=" ">
            <text term="accessed" text-case="capitalize-first"/>
            <date variable="accessed" form="text"/>
          </group>
        </if>
      </choose>
      <choose>
        <if type="legal_case" match="none">
          <choose>
            <if variable="DOI">
              <text variable="DOI" prefix="doi:"/>
            </if>
            <else>
              <text variable="URL"/>
            </else>
          </choose>
        </if>
      </choose>
    </group>
  </macro>
  <macro name="case-locator-subsequent">
    <choose>
      <if type="legal_case">
        <text macro="locators-note"/>
      </if>
    </choose>
  </macro>
  <macro name="case-issue-subsequent">
    <choose>
      <if type="legal_case">
        <text macro="issue"/>
      </if>
    </choose>
  </macro>
  <citation et-al-min="4" et-al-use-first="1" disambiguate-add-names="true">
    <layout suffix="." delimiter="; ">
      <choose>
        <if match="all" position="subsequent">
          <text variable="first-reference-note-number" prefix="see ref: "/>
        </if>
        <else-if type="webpage post-weblog" match="any">
          <group delimiter=" ">
            <text variable="title" suffix=": "/>
            <text variable="URL"/>
          </group>
        </else-if>
        <else>
          <group delimiter=", ">
            <text macro="contributors-short" strip-periods="true"/>
            <text variable="title" font-style="italic" />
            <group delimiter=" ">
              <group delimiter=", ">
                <date date-parts="year" form="numeric" variable="issued"/>
                <text macro="case-locator-subsequent"/>
                <choose>
                  <if type="chapter" match="any">
                    <group>
                      <text variable="title" form="short"/>
                      <text value="in: " prefix=", "/>
                      <text variable="container-title" form="short" font-style="italic" suffix=", "/>
                      <text variable="publisher" prefix="(" suffix=")"/>
                      <text variable="page" form="short" prefix=": "/>
                    </group>
                  </if>
                  <else>
                    <group delimiter=" ">
                      <text variable="container-title" form="short" strip-periods="true" font-style="italic"/>
                      <text variable="volume" strip-periods="true" font-weight="bold" suffix=":"/>
                      <text variable="page" form="short" strip-periods="false"/>
                    </group>
                  </else>
                </choose>
              </group>
              <text macro="case-issue-subsequent"/>
            </group>
            <text macro="point-locators-subsequent"/>
          </group>
        </else>
      </choose>
    </layout>
  </citation>
  <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="&#8212;&#8212;&#8212;" entry-spacing="0">
    <sort>
      <key variable="call-number"/>
    </sort>
    <layout suffix=".">
      <group delimiter=". ">
        <group delimiter=": ">
          <group delimiter=", ">
            <group delimiter=" ">
              <group delimiter=". ">
                <group delimiter=" ">
                  <group delimiter=", ">
                    <group delimiter=". ">
                      <group delimiter=". ">
                        <text macro="contributors"/>
                        <text macro="title"/>
                      </group>
                      <text macro="description"/>
                      <text macro="secondary-contributors"/>
                      <group delimiter=", ">
                        <text macro="container-title"/>
                        <text macro="container-contributors"/>
                      </group>
                      <text macro="locators-join-with-period"/>
                    </group>
                    <text macro="locators-join-with-comma"/>
                    <text macro="locators-chapter"/>
                  </group>
                  <text macro="locators-join-with-space"/>
                </group>
                <text macro="collection-title"/>
                <text macro="issue-join-with-period"/>
              </group>
              <text macro="issue-join-with-space"/>
            </group>
            <text macro="issue-join-with-comma"/>
            <text macro="locators-journal-join-with-comma"/>
            <text macro="locators-newspaper"/>
          </group>
          <text macro="locators-journal-join-with-colon"/>
        </group>
        <text macro="access"/>
      </group>
    </layout>
  </bibliography>
</style>

PAW Setups & PseudoPotentials

GPAW has a large set of PAW setups (updated in 2016) for elements from H to Rn, excluding lanthanides, actinides, and radioactive elements. One can generate new setups with a PAW generating build-in tool and their own risk. One can use optimized norm-conserving Vanderbilt SG15 pseudopotentials (updated in 2017) or norm-conserving Hartwigsen-Goedecker-Hutter HGH pseudopotentials (see also GPAW intro) or even JTH pseudopotentials from ABINIT. There are even more setups, including f-elements, listed on the QE webpage. The great thing about these setups is that they use a similar format – either xml or upfApparently, GPAW can read both formats, although there is no relevant documentation. So, there are many ways to run calculations with elements that are missing in the GPAW default setups set. QuantumATK webpage provides an overview of pseudopotentials and even suggests mixing them. I hope that in the future, these and new PAWs will be gathered together like basis sets at the basis sets exchange portal.

P.S. Interesting https://esl.cecam.org/data/ and https://molmod.ugent.be/deltacodesdft

DFT geometry optimizers

These are undeservedly less attention to optimizers than density functionals (concerning Jacob’s ladder). It is not even covered in the recent review: Best-Practice DFT Protocols for Basic Molecular Computational Chemistry. At the same time, in my current projects, the most resource-demanding was geometry optimization – the time spent on optimizing structures was much longer than a single-point calculation. Papers that introduce new (AI-based) optimizers promise significant speed-up. However, there are always some problems:

  1. The tested systems are different from my electrochemical interfaces.
  2. The code is not available or difficult to install.
  3. The code is outdated and contains bugs.
  4. Optimizers perform worse than the common ones, like QuasiNewton in ASE.

ASE wiki lists all internal and some external optimizers and provides their comparison. I have checked the most promising on a high-entropy alloy slab.

Observation 1. QuasiNewton outperforms all other optimizers. Point. I have run a standard GPAW/DFT/PBE/PW optimization with various optimizers:

Observation 2. Pre-optimizing the slab with a cheaper method does not reduce the number of optimization steps. I have preoptimized the geometry with TBLITE/DFTB/GFN1-xTB to continue with GPAW/DFT/PBE/PW. Preoptimization takes just some minutes and the obtained geometry looks similar to the DFT one but that does not reduce the number of DFT optimization steps.

OptimizerN steps*Time$N steps*#Total time#
BFGS1602:44:271703:01:26
LBFGS1502:30:351602:55:04
BondMin1202:46:271302:45:07
GPMin1205:26:233108:14:22
MLMin38verylong2812:31:29
FIRE3805:06:564405:56:54
QuasiNewton801:36:23902:00:10

Note * – the printed number of steps might different from the actuall number of calculations because each calculator has a different way of reporting that number.

Note $ – the time between the end of the first and last steps.

Note # – started from the TBLITE/DFTB/GFN1-xTB preoptimized geometry.

N.B! I have done my test only once in two runs: starting with slab.xyz and preoptized geometry. Runs were on similar nodes and all optimizations were done on the same node.

Conclusion. Do not believe in claims in articles advertizing new optimizers – Run your tests before using them.

A practical finding. The usual problem with calculations that require many optimization steps is that they need to fit into HPC time limits. On the restart, ASE usually rewrites the trajectory. Some optimizers (GPMin and AI-based) could benefit from reading the full trajectory. So, I started writing two trajectories and a restart file like this.

# Restarting
if os.path.exists(f'{name}_last.gpw') == True and os.stat(f'{name}_last.gpw').st_size > 0:
    atoms,calc = restart(f'{name}_last.gpw', txt=None)
    parprint(f'Restart from the gpw geometry.')
elif os.path.exists(f'{name}_full.traj') == True and os.stat(f'{name}_full.traj').st_size > 0:
    atoms = read(f'{name}_full.traj',-1)
    parprint(f'Restart with the traj geometry.')
else:
    atoms = read(f'{name}_init.xyz')
    parprint(f'Start with the initial xyz geometry.')

# Optimizing
opt = QuasiNewton(atoms, trajectory=f'{name}.traj', logfile=f'{name}.log')
traj= Trajectory(f'{name}_full.traj', 'a', atoms)
opt.attach(traj.write, interval=1)
def writegpw():
    calc.write(f'{name}_last.gpw')
opt.attach(writegpw, interval=1)
opt.run(fmax=0.05, steps=42)

Here are some details on the tests.

My gpaw_opt.py for DFT calculations on 24 cores:

# Load modules
from ase import Atom, Atoms
from ase.build import add_adsorbate, fcc100, fcc110, fcc111, fcc211, molecule
from ase.calculators.mixing import SumCalculator
from ase.constraints import FixAtoms, FixedPlane, FixInternals
from ase.data.vdw_alvarez import vdw_radii
from ase.db import connect
from ase.io import write, read
from ase.optimize import BFGS, GPMin, LBFGS, FIRE, QuasiNewton
from ase.parallel import parprint
from ase.units import Bohr
from bondmin import BondMin
from catlearn.optimize.mlmin import MLMin
from dftd4.ase import DFTD4
from gpaw import GPAW, PW, FermiDirac, PoissonSolver, Mixer, restart
from gpaw.dipole_correction import DipoleCorrection
from gpaw.external import ConstantElectricField
from gpaw.utilities import h2gpts
import numpy as np
import os

atoms = read('slab.xyz')
atoms.set_constraint([FixAtoms(indices=[atom.index for atom in atoms if atom.tag in [1,2]])])

# Set calculator
kwargs = dict(poissonsolver={'dipolelayer':'xy'},
              xc='RPBE',
              kpts=(4,4,1),
              gpts=h2gpts(0.18, atoms.get_cell(), idiv=4),
              mode=PW(400),
              basis='dzp',
              parallel={'augment_grids':True,'sl_auto':True,'use_elpa':True},
             )
calc = GPAW(**kwargs)

#atoms.calc = SumCalculator([DFTD4(method='RPBE'), calc])
#atoms.calc = calc

# Optimization paramters
maxf = 0.05

# Run optimization
###############################################################################

# 2.A. Optimize structure using MLMin (CatLearn).
initial_mlmin = atoms.copy()
initial_mlmin.set_calculator(calc)
mlmin_opt = MLMin(initial_mlmin, trajectory='results_mlmin.traj')
mlmin_opt.run(fmax=maxf, kernel='SQE', full_output=True)

# 2.B Optimize using GPMin.
initial_gpmin = atoms.copy()
initial_gpmin.set_calculator(calc)
gpmin_opt = GPMin(initial_gpmin, trajectory='results_gpmin.traj', logfile='results_gpmin.log', update_hyperparams=True)
gpmin_opt.run(fmax=maxf)

# 2.C Optimize using LBFGS.
initial_lbfgs = atoms.copy()
initial_lbfgs.set_calculator(calc)
lbfgs_opt = LBFGS(initial_lbfgs, trajectory='results_lbfgs.traj', logfile='results_lbfgs.log')
lbfgs_opt.run(fmax=maxf)

# 2.D Optimize using FIRE.
initial_fire = atoms.copy()
initial_fire.set_calculator(calc)
fire_opt = FIRE(initial_fire, trajectory='results_fire.traj', logfile='results_fire.log')
fire_opt.run(fmax=maxf)

# 2.E Optimize using QuasiNewton.
initial_qn = atoms.copy()
initial_qn.set_calculator(calc)
qn_opt = QuasiNewton(initial_qn, trajectory='results_qn.traj', logfile='results_qn.log')
qn_opt.run(fmax=maxf)

# 2.F Optimize using BFGS.
initial_bfgs = atoms.copy()
initial_bfgs.set_calculator(calc)
bfgs_opt = LBFGS(initial_bfgs, trajectory='results_bfgs.traj', logfile='results_bfgs.log')
bfgs_opt.run(fmax=maxf)

# 2.G. Optimize structure using BondMin.
initial_bondmin = atoms.copy()
initial_bondmin.set_calculator(calc)
bondmin_opt = BondMin(initial_bondmin, trajectory='results_bondmin.traj',logfile='results_bondmin.log')
bondmin_opt.run(fmax=maxf)

# Summary of the results
###############################################################################

fire_results = read('results_fire.traj', ':')
parprint('Number of function evaluations using FIRE:',
         len(fire_results))

lbfgs_results = read('results_lbfgs.traj', ':')
parprint('Number of function evaluations using LBFGS:',
         len(lbfgs_results))

gpmin_results = read('results_gpmin.traj', ':')
parprint('Number of function evaluations using GPMin:',
         gpmin_opt.function_calls)

bfgs_results = read('results_bfgs.traj', ':')
parprint('Number of function evaluations using BFGS:',
         len(bfgs_results))

qn_results = read('results_qn.traj', ':')
parprint('Number of function evaluations using QN:',
         len(qn_results))

catlearn_results = read('results_mlmin.traj', ':')
parprint('Number of function evaluations using MLMin:',
         len(catlearn_results))

bondmin_results = read('results_bondmin.traj', ':')
parprint('Number of function evaluations using BondMin:',
         len(bondmin_results))

Initial slab.xyz file:

45
Lattice="8.529357696932532 0.0 0.0 4.264678848466266 7.386640443507905 0.0 0.0 0.0 29.190908217261956" Properties=species:S:1:pos:R:3:tags:I:1 pbc="T T F"
Ir       0.00000000       1.62473838      10.00000000        5
Ru       2.81412943       1.62473838      10.00000000        5
Pt       5.62825885       1.62473838      10.00000000        5
Pd       1.40706471       4.06184595      10.00000000        5
Ag       4.22119414       4.06184595      10.00000000        5
Ag       7.03532356       4.06184595      10.00000000        5
Ag       2.81412943       6.49895353      10.00000000        5
Ru       5.62825885       6.49895353      10.00000000        5
Pt       8.44238828       6.49895353      10.00000000        5
Pt       0.00000000       0.00000000      12.29772705        4
Ag       2.81412943       0.00000000      12.29772705        4
Ru       5.62825885       0.00000000      12.29772705        4
Ru       1.40706471       2.43710757      12.29772705        4
Ir       4.22119414       2.43710757      12.29772705        4
Ag       7.03532356       2.43710757      12.29772705        4
Ag       2.81412943       4.87421514      12.29772705        4
Ir       5.62825885       4.87421514      12.29772705        4
Pd       8.44238828       4.87421514      12.29772705        4
Pd       1.40706471       0.81236919      14.59545411        3
Ir       4.22119414       0.81236919      14.59545411        3
Pt       7.03532356       0.81236919      14.59545411        3
Ag       2.81412943       3.24947676      14.59545411        3
Ir       5.62825885       3.24947676      14.59545411        3
Ir       8.44238828       3.24947676      14.59545411        3
Pd       4.22119414       5.68658433      14.59545411        3
Pt       7.03532356       5.68658433      14.59545411        3
Ag       9.84945299       5.68658433      14.59545411        3
Pd       0.00000000       1.62473838      16.89318116        2
Pd       2.81412943       1.62473838      16.89318116        2
Ag       5.62825885       1.62473838      16.89318116        2
Pt       1.40706471       4.06184595      16.89318116        2
Ag       4.22119414       4.06184595      16.89318116        2
Ag       7.03532356       4.06184595      16.89318116        2
Ru       2.81412943       6.49895353      16.89318116        2
Ru       5.62825885       6.49895353      16.89318116        2
Ru       8.44238828       6.49895353      16.89318116        2
Ir       0.00000000       0.00000000      19.19090822        1
Ag       2.81412943       0.00000000      19.19090822        1
Pt       5.62825885       0.00000000      19.19090822        1
Pd       1.40706471       2.43710757      19.19090822        1
Ag       4.22119414       2.43710757      19.19090822        1
Pd       7.03532356       2.43710757      19.19090822        1
Ag       2.81412943       4.87421514      19.19090822        1
Ru       5.62825885       4.87421514      19.19090822        1
Ir       8.44238828       4.87421514      19.19090822        1

My tblite_opt.py for DFTB calcualation with just one core. It takes some minutes but eventually crashes 🙁

# Load modules
from ase import Atom, Atoms
from ase.build import add_adsorbate, fcc100, fcc110, fcc111, fcc211, molecule
from ase.calculators.mixing import SumCalculator
from ase.constraints import FixAtoms, FixedPlane, FixInternals
from ase.data.vdw_alvarez import vdw_radii
from ase.db import connect
from ase.io import write, read
from ase.optimize import BFGS, GPMin, LBFGS, FIRE, QuasiNewton
from ase.parallel import parprint
from ase.units import Bohr
from tblite.ase import TBLite
import numpy as np
import os

# https://tblite.readthedocs.io/en/latest/users/ase.html

atoms = read('slab.xyz')
atoms.set_constraint([FixAtoms(indices=[atom.index for atom in atoms if atom.tag in [1,2]])])

# Set calculator
calc = TBLite(method="GFN1-xTB",accuracy=1000,electronic_temperature=300,max_iterations=300)
atoms.set_calculator(calc)
qn_opt = QuasiNewton(atoms, trajectory='results_qn.traj', logfile='results_qn.log', maxstep=0.1)
qn_opt.run(fmax=0.1)

To compare structures I have used MDanalysis, which unfortunately does not work with ASE traj, so I prepared xyz-files with “ase convert -n -1 file.traj file.xyz”

import MDAnalysis as mda
from MDAnalysis.analysis.rms import rmsd
import sys

def coord(file_name):
    file  = mda.Universe(f"{file_name}.xyz")
    atoms = file.select_atoms("index 1:9")
    return  atoms.positions.copy()

print(rmsd(coord(sys.argv[1]),coord(sys.argv[2])))

An instruction on installation of GPAW. TBLITE can be installed as “conda install -c conda-forge tblite”.

GPAW installation with pip

Between installation with conda and compilation of libraries, an intermediate path – installation of GPAW with pip – is a compromise for those who wish to text specific GPAW branches or packages.

For example, I wish to text self-interaction error correction (SIC) and evaluate Bader charges with pybader. Neither SIC nor pybader is compatible with the recent GPAW. Here is not to get a workable version.

# numba in pybader is not compatible with python 3.11, so create a conda environment with python 3.10
conda create -n gpaw-pip python=3.10 
conda activate gpaw-pip

conda install -c conda-forge libxc libvdwxc
conda install -c conda-forge ase
# ensure that you install the right openmpi (not external)
conda install -c conda-forge openmpi ucx
conda install -c conda-forge compilers
conda install -c conda-forge openblas scalapack
conda install -c conda-forge pytest
pip install pybader

# Get a developer version of GPAW with SIC
git clone -b dm_sic_mom_update https://gitlab.com/alxvov/gpaw.git
cd gpaw
cp siteconfig_example.py siteconfig.py

# In the siteconfig.py rewrite
'''
fftw = True
scalapack = True
if scalapack:
    libraries += ['scalapack']
'''

unset CC
python -m pip install -e .
gpaw info

Visualizing ASE atoms in Jupyter notebooks

For a long time I wanted to see ASE atoms in my Jupyter notebook. My previous attempts were usually unsuccessful. Today I decided to try again. First ASE wiki suggests x3d and webngl:

view(atoms, viewer='x3d')
view(atoms, viewer='ngl')

Łucasz Mentel gives some useful tips in his blogpost from 2017.

In my case x3d works and webngl fails. The x3d picture is not enought, and I do not want to spend much time on fixing webngl.

ASE-notebook is what works for me.

conda create -n "jupyter"
conda activate jupyter
conda install -c conda-forge ase-notebook
conda install -c conda-forge jupyterlab

By the way, the model is from my “Surface Curvature Effect on Dual-Atom Site Oxygen Electrocatalysis” paper, which you can read at chemRxiv until it turns Gold Open Access.

Bayesian Error Estimation (BEE) for RPBE

The Beyesian Error Estimation (BEE) is implemented in GPAW only for PBE, BEEF-vdW, and mBEEF-vdW.

Here is a trick for making the BEE with the RPBE functional. Just edit the lines in ASE and GPAW codes by adding RPBE as an exception.

To find the needed files, run

find ./ -name "bee.py"

In ase/dft/bee.py change one line:

class BEEFEnsemble:



            if self.xc in ['BEEF-vdW', 'BEEF', 'PBE', 'RPBE']: # add RPBE
                self.beef_type = 'beefvdw'

In gpaw/xc/bee.py add two lines:

class BEEFEnsemble:
    """BEEF ensemble error estimation."""
    def __init__(self, calc):



        # determine functional and read parameters
        self.xc = self.calc.get_xc_functional()
        if self.xc == 'BEEF-vdW':
            self.bee_type = 1
        elif self.xc == 'RPBE': # catch the RPBE exchange functional
            self.bee_type = 1   # assign BEEF coefficients the RBPE

Below we use BEEF-vdW, RPBE, and PBE dimensionless density (n) with gradient (s) and apply BEEF coefficients (E₀, ΔEᵢ) to evaluate the BEE as the standard deviation for the ensemble total energies with the variable enhancement factor (F(s,θᵢ)).


from ase import Atoms
from ase.dft.bee import BEEFEnsemble
from ase.parallel import parprint
from gpaw import GPAW
import time

for xc in ['BEEF-vdW','RPBE','PBE']:
    start_time = time.time()

    h2 = Atoms('H2',[[0.,0.,0.],[0.,0.,0.741]]) #exp. bond length
    h2.center(vacuum=3)
    cell = h2.get_cell()

    calc = GPAW(xc=xc,txt='H2_{0}.txt'.format(xc))
    h2.calc = calc
    e_h2 = h2.get_potential_energy()
    ens = BEEFEnsemble(calc)
    de_h2 = ens.get_ensemble_energies()
    del h2, calc, ens

    h = Atoms('H')
    h.set_cell(cell)
    h.center()
    calc = GPAW(xc=xc,txt='H_{0}.txt'.format(xc), hund=True)
    h.calc = calc
    e_h = h.get_potential_energy()
    ens = BEEFEnsemble(calc)
    de_h = ens.get_ensemble_energies()
    del h, calc, ens

    E_bind = 2*e_h - e_h2
    dE_bind = 2*de_h[:] - de_h2[:]
    dE_bind = dE_bind.std()
    
    parpting('{0} functional'.format(xc))
    parprint('Time: {0} s'.format(round(time.time()-start_time,0)))
    parprint('E_bind: {0} eV'.format(round(E_bind,4)))
    parprint('Error bar {0} eV'.format(round(dE_bind,4)))

Synchronizing calendars

This post describes ways of pushing MS outlook and Google calendars to Nextcloud.

My main working calendar is the Nextcloud app because I can easily sync it is my Sailfish phone. I also use Google calendar (for sharing family events) and MS outlook calendar (for work). Today I decided to merge all these calendars into a single one that I can sync on all my devices. Here is how.

MS to Nextcloud

Use outlookcaldavsynchronizer as recommended in the Nextcloud blog.

Google to Nextcould

  • Get the iCal link from Google Calendar as follows:
  • In the left calendar list menu of Google Calendar, go to the ⋮ menu of the calendar to be shared
  • Click on “Settings and sharing”
  • On the Calendar settings page, scroll down to “Secret address in iCal format”
  • In Nextcloud Calendar’s left menu, click on “+New Calendar” > “New subscription from link (read-only)”
  • Insert the “Secret address in iCal format”
  • Your new calendar subscription will appear in the list; you can change its name or color in the menu of your calendar