Skip to content

Commit

Permalink
Merge branch 'main' into alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
HowWeiBin authored Apr 5, 2024
2 parents 3ecea51 + c2dcd2f commit 1819ba0
Show file tree
Hide file tree
Showing 24 changed files with 641 additions and 174 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ jobs:
- roy-gch
- sample-selection
- gaas-map
# - batch-cp2k
- batch-cp2k
- lpr

steps:
- uses: actions/checkout@v4
Expand Down
106 changes: 64 additions & 42 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
@@ -1,82 +1,103 @@
Contributing
============

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and
credit will always be given. You can contribute in the ways listed below.
Contributions are welcome, and they are greatly appreciated! Every little bit
helps, and credit will always be given. You can contribute in the ways listed
below.

Requirements for new contributions
----------------------------------

All code included in this repository is executed in each pull request. This ensures that
the code in this repository stays executable for a longer time frame. Because of that we
do not want to have examples with heavy calculations that take more than 30 seconds to
execute. If heavy calculations are needed, it might be a better option to put your
example in an external repository and link to it on the `Wiki page
<https://github.com/lab-cosmo/software-cookbook/wiki>`_. If you feel unsure if a
contribution is suitable, feel free to contact one of the `support`_ before.
All code included in this repository is executed in each pull request. This
ensures that the code in this repository stays executable for a longer time
frame. Because of that we do not want to have examples with heavy calculations
that take more than 30 to 1 min seconds to execute. If you feel unsure if a
contribution is suitable, feel free to contact one of the `support`_ person
beforehand.

Adding a new examples
---------------------

To visualize examples on our readthedocs page we use `sphinx-gallery`. When building the
doc the examples are run and compiled automatically into HTML files and moved to the
documentation folder `docs/src <docs/src>`_. You will find all the examples Python
scripts in the `examples/` folder of the repository. Each example is put into one of the
example category folders, e.g. `examples/sample_selection <examples/sample_selection>`_.
If you do not know where to put your example, just put in the `examples/uncategorized
<examples/uncategorized>`_ folder and when doing a pull request, we will figure out
where to put it.
The examples in this repository are python files that we render for the website
using `sphinx-gallery`_. In short, these are python files containing comments
formatted as `RestructuredText`_, which are executed, and then the comments,
code and outputs (including plots, ``print`` outputs, etc.) are assembled in a
single HTML webpage.

After adding a file, you'll need to update ``tox.ini`` to build your example when
building the documentation. Look how it's done for the ``lode_linear`` example, and
do the same for yours!
To add a new example, you'll need to create a new folder in example (substitute
``<example-name>`` with the folder name in the instructions below), and add the
following files inside:

- ``README.rst``, can be empty or can contain a short description of the example;
- ``environment.yml``, a `conda`_ environment file containing the list of
dependencies needed by your example;
- as many Python files as you want, each one will be converted to a separate
HTML page.

.. _sphinx-gallery: https://sphinx-gallery.github.io/
.. _RestructuredText: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
.. _conda: https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually

Finally, you'll need to add your example to the list so it is automatically
build on CI. The list is in the ``.github/workflows/docs.yml`` file, near the
``example-name:`` section.

Converting a Jupyter notebook to a sphinx-gallery compatible Python script
--------------------------------------------------------------------------

Often it is more convenient to work in a Jupyter notebook and convert in later to
sphinx-gallery example. To convert your Jupyter notebook you can just use the
`ipynb-to-gallery.py <ipynb_to_gallery.py>`_ file that is root folder of the repository
Often it is more convenient to work in a Jupyter notebook and convert in later
to sphinx-gallery example. To convert your Jupyter notebook you can use the
`ipynb-to-gallery.py <ipynb_to_gallery.py>`_ file that is root folder of the
repository

.. code-block:: bash
python ipynb-to-gallery.py <notebook.ipynb>
Building the cookbook locally
-----------------------------
Running your example and visualizing the HTML
---------------------------------------------

When you add a new example, you can run the linter (code format checker) and build the
doc to check if your code runs with
We use `nox`_ as a task runner to run all examples and assemble the final
documentation. You can install it with ``pip install nox``.

To run your example and make sure it conforms to the expected code formatting,
you can use the following commands:

.. code-block:: bash
tox
# execute the example and render it to HTML
nox -e <example-name>
# check the code formatting
nox -e lint
To visualize the generated cookbook open ``docs/build/html/index.html`` in a web
browser.

If there are formatting errors appearing you can format your file automatically with
If there are formatting errors you can try to fix them automatically with:

.. code-block:: bash
tox -e format
nox -e format
That should fix most of the formatting issues automatically. If there are still
formatting issues remaining, then the reviewer of your pull request can fix them.
To visualize the generated cookbook open in a browser the file
``docs/build/html/index.html``.
You can also build all examples (warning, this will take quite some time) with:

.. code-block:: bash
nox -e docs
.. _nox: https://nox.thea.codes/

Known issues
------------

Sometimes the doc preview from readthedocs is not rendered correctly. If something works
in your local build but not in the readthedocs PR preview. It could that the issue is
fixed once you merge with the main branch.

Chemiscope widgets are not currently integrated into our sphinx gallery.

Support
-------

If you still have problems adding your example to the repository, please feel free to
contact one of the people
If you still have problems adding your example to the repository, please feel
free to contact one of the people

`@agoscinski (Alexander Goscinski) <[email protected]>`_

Expand All @@ -85,5 +106,6 @@ contact one of the people
Code of Conduct
---------------

Please note that the COSMO cookbook project is released with a `Contributor Code of
Conduct <CONDUCT.md>`_. By contributing to this project you agree to abide by its terms.
Please note that the COSMO cookbook project is released with a `Contributor Code
of Conduct <CONDUCT.md>`_. By contributing to this project you agree to abide by
its terms.
9 changes: 8 additions & 1 deletion docs/src/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from datetime import datetime


# Add any Sphinx extension module names here, as strings.
extensions = [
"sphinx.ext.viewcode",
Expand All @@ -9,7 +12,11 @@
exclude_patterns = ["_build"]

project = "cosmo-software-cookbook"
copyright = "BSD 3-Clause License, Copyright (c) 2023, COSMO software cookbook team"
copyright = (
"BSD 3-Clause License, "
f"Copyright (c) {datetime.now().date().year}, "
"COSMO software cookbook team"
)

htmlhelp_basename = "COSMO software-cookbook"
html_theme = "furo"
Expand Down
12 changes: 12 additions & 0 deletions docs/src/index.rst.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ COSMO Software Cookbook
:end-before: marker-intro-end


All the examples provide an ``environment.yml`` file that you can download and
then use with conda to create a new environment with all the required
dependencies for this example.

.. code-block:: bash

# Pick a name for the environment and replace <environment-name> with it
conda env create --name <environment-name> --file environment.yml

# when you want to use the environment
conda env activate --name <environment-name>

.. toctree::
:caption: Table of Contents
:maxdepth: 1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
production/
parameters/

cp2k.out
cp2k.inp
cp2k_shell.ssmp
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
channels:
- conda-forge
dependencies:
- python=3.11
- pip
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,53 @@
Batch run of CP2K calculations
==============================
.. start-body
:Authors: Matthias Kellner `@bananenpampe <https://github.com/bananenpampe/>`_,
Philip Loche `@PicoCentauri <https://github.com/PicoCentauri/>`_
This is an example how to perform single point calculations based on list of structures
using `CP2K <https://www.cp2k.org>`_ using its `reftraj functionality
<https://manual.cp2k.org/trunk/CP2K_INPUT/MOTION/MD/REFTRAJ.html>`_. The inputs are a
set of structures in :download:`example.xyz` using the DFT parameters defined in
:download:`reftraj_template.cp2k` importing basis set and pseudopotentials from the
local CP2K installation. The reference DFT parameters are taken from `Cheng et al. Ab
initio thermodynamics of liquid and solid water 2019
:download:`reftraj_template.cp2k`. The reference DFT parameters are taken from `Cheng et
al. Ab initio thermodynamics of liquid and solid water 2019
<https://www.pnas.org/doi/10.1073/pnas.1815117116>`_. Due to the small size of the test
structure and convergence issues, we have decreased the size of the ``CUTOFF_RADIUS``
from :math:`6.0\,\mathrm{Å}` to :math:`3.0\,\mathrm{Å}`. For actual production
calculations adapt the template!
To run this example, we use a bare executable called with ``cp2k``. If you want to use
another version you can either adjust the the names within this example or link your
binary with a different name to ``cp2k``.
"""

# %%
# We start the example by importing the required packages.


import os
import re
import platform
import subprocess
from os.path import basename, splitext
from typing import List, Union

import ase.io
import ase.visualize.plot
import matplotlib.pyplot as plt
import numpy as np
from ase.calculators.cp2k import CP2K
import requests


# %%
#
# Install CP2K
# ------------
#
# We'll need a working installation of cp2k. The best way to do so depends on your
# platform, here are some possible solutions, but feel free to replace them with another
# installation method.

if platform.system() == "Linux":
# use conda on Linux
subprocess.run(["conda", "install", "cp2k", "-c", "conda-forge", "-y"], check=True)
elif platform.system() == "Darwin":
# use homebrew on macOS
subprocess.run(["brew", "install", "cp2k"], check=True)
else:
print("no known way to install cp2k, skipping installation")


# %%
Expand Down Expand Up @@ -136,17 +149,25 @@ def write_cp2k_in(


# %%
#
# We will now download basis set files from CP2K website. Depending on your CP2K
# installation, this might not be necessary!


def mkdir_force(*args, **kwargs) -> None:
"""Warpper to ``os.mkdir``.
def download_parameter(file):
path = os.path.join("parameters", file)

if not os.path.exists(path):
url = f"https://raw.githubusercontent.com/cp2k/cp2k/support/v2024.1/data/{file}"
response = requests.get(url)
response.raise_for_status()
with open(path, "wb") as f:
f.write(response.content)

The function does not raise an error if the directory already exists.
"""
try:
os.mkdir(*args, **kwargs)
except OSError:
pass

os.makedirs("parameters", exist_ok=True)
for file in ["GTH_BASIS_SETS", "BASIS_ADMM", "POTENTIAL", "dftd3.dat", "t_c_g.dat"]:
download_parameter(file)


# %%
Expand Down Expand Up @@ -200,11 +221,9 @@ def mkdir_force(*args, **kwargs) -> None:
# directory named ``H4O2`` because our dataset consists only of a single structure with
# two water molecules.

mkdir_force(project_directory)

for stoichiometry, frames in frames_dict.items():
current_directory = f"{project_directory}/{stoichiometry}"
mkdir_force(current_directory)
os.makedirs(current_directory, exist_ok=True)

write_cp2k_in(
f"{current_directory}/in.cp2k",
Expand Down Expand Up @@ -281,50 +300,5 @@ def mkdir_force(*args, **kwargs) -> None:

new_frames += frames_dft

new_fname = f"{splitext(basename(write_to_file))[0]}_dft.xyz"
new_fname = f"{os.path.splitext(os.path.basename(write_to_file))[0]}_dft.xyz"
ase.io.write(f"{project_directory}/{new_fname}", new_frames)

# %%
# Perform calculations using ASE calculator
# -----------------------------------------
# Above we performed the calculations using an external bash script. ASE also provides a
# calculator class that we can use the perform the calculations with our input file
# without a detour of writing files to disk.
#
# To use the ASE calculator together with a custom input script this requires some
# adjustments. First the name of the executable that has the exact name ``cp2k_shell``.
# We create a symlink to follow this requirement.

# %%
# Next, we load the input file abd remove ``GLOBAL`` section because from it

inp = open("./production/H4O2/in.cp2k", "r").read()
inp = re.sub(
f"{re.escape('&GLOBAL')}.*?{re.escape('&END GLOBAL')}", "", inp, flags=re.DOTALL
)

# %%
# Afterwards we define the :py:class:`ase.calculators.cp2k.CP2K`` calculator. Note that
# we disable all parameters because we want to use all options from our input file

calc = CP2K(
inp=inp,
max_scf=None,
cutoff=None,
xc=None,
force_eval_method=None,
basis_set=None,
pseudo_potential=None,
basis_set_file=None,
potential_file=None,
stress_tensor=False,
poisson_solver=None,
print_level=None,
)

# %%
# We now load a new structure, add the calculator and perform the computation.

atoms = ase.io.read("example.xyz")
atoms.set_calculator(calc)
# atoms.get_potential_energy()
Loading

0 comments on commit 1819ba0

Please sign in to comment.