mirror of
https://github.com/QuantumPackage/qp2.git
synced 2024-08-24 21:21:47 +02:00
added properly the first tuto!
This commit is contained in:
parent
dd2f0a2c07
commit
e0af6d8425
@ -40,6 +40,7 @@
|
||||
programmers_guide/ezfio
|
||||
programmers_guide/plugins
|
||||
programmers_guide/plugins_tuto_intro
|
||||
programmers_guide/plugins_tuto_I
|
||||
programmers_guide/new_ks
|
||||
programmers_guide/index
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
Tutorial for creating a plugin
|
||||
==============================
|
||||
|
||||
Introduction: what is a plugin, and what this tuto will be about ?
|
||||
==================================================================
|
||||
Introduction: what is a plugin, and what tutorial will be about ?
|
||||
=================================================================
|
||||
|
||||
The |QP| is split into two kinds of routines/global variables (i.e. *providers*):
|
||||
i) the **core modules** locatedin qp2/src/, which contains all the bulk of a quantum chemistry software (integrals, matrix elements between Slater determinants, linear algebra routines, DFT stuffs etc..)
|
||||
ii) the **plugins** which are external routines/*providers* connected to the qp2/src/ routines/*providers*.
|
||||
1) the **core modules** locatedin qp2/src/, which contains all the bulk of a quantum chemistry software (integrals, matrix elements between Slater determinants, linear algebra routines, DFT stuffs etc..)
|
||||
2) the **plugins** which are external routines/*providers* connected to the qp2/src/ routines/*providers*.
|
||||
|
||||
More precisely, a **plugin** of the |QP| is a directory where you can create routines,
|
||||
providers and executables that use all the global variables/functions/routines already created
|
||||
@ -16,24 +16,24 @@ in the modules of qp2/src or in other plugins.
|
||||
Instead of giving a theoretical lecture on what is a plugin,
|
||||
we will go through a series of examples that allow you to do the following thing:
|
||||
|
||||
i) print out **one- and two-electron integrals** on the AO/MO basis, creates two providers which manipulate these objects, print out these providers,
|
||||
1) print out **one- and two-electron integrals** on the AO/MO basis, creates two providers which manipulate these objects, print out these providers,
|
||||
|
||||
ii) browse the **Slater determinants stored** in the |EZFIO| wave function and compute their matrix elements,
|
||||
2) browse the **Slater determinants stored** in the |EZFIO| wave function and compute their matrix elements,
|
||||
|
||||
iii) build the **Hamiltonian matrix** and **diagonalize** it either with **Lapack or Davidson**,
|
||||
3) build the **Hamiltonian matrix** and **diagonalize** it either with **Lapack or Davidson**,
|
||||
|
||||
iv) print out the **one- and two-electron rdms**,
|
||||
4) print out the **one- and two-electron rdms**,
|
||||
|
||||
v) obtain the **AOs** and **MOs** on the **DFT grid**, together with the **density**,
|
||||
5) obtain the **AOs** and **MOs** on the **DFT grid**, together with the **density**,
|
||||
|
||||
How the tutorial will be done
|
||||
-----------------------------
|
||||
|
||||
This tuto is as follows:
|
||||
|
||||
i) you **READ THIS FILE UNTIL THE END** in order to get the big picture and vocabulary,
|
||||
1) you **READ THIS FILE UNTIL THE END** in order to get the big picture and vocabulary,
|
||||
|
||||
ii) you go to the directory :file:`qp2/plugins/tuto_plugins/` and you will find detailed tutorials for each of the 5 examples.
|
||||
2) you go to the directory :file:`qp2/plugins/tuto_plugins/` and you will find detailed tutorials for each of the 5 examples.
|
||||
|
||||
Creating a plugin: the basic
|
||||
----------------------------
|
||||
@ -77,23 +77,23 @@ Then, to create the plugin of your dreams, the two questions you need to answer
|
||||
|
||||
The routine :c:func:`lapack_diagd` (which diagonalises a real hermitian matrix) is located in the file
|
||||
:file:`qp2/src/utils/linear_algebra.irp.f`
|
||||
therefore it "belongs" to the module "utils"
|
||||
therefore it "belongs" to the module :ref:`module_utils`
|
||||
|
||||
The routine :c:func:`ao_to_mo` (which converts a given matrix A from the AO basis to the MO basis) is located in the file
|
||||
:file:`qp2/src/mo_one_e_ints/ao_to_mo.irp.f`
|
||||
therefore it "belongs" to the module "mo_one_e_ints"
|
||||
therefore it "belongs" to the module :ref:`module_mo_one_e_ints`
|
||||
|
||||
The provider :c:data:`ao_one_e_integrals` (which is the integrals of one-body part of H on the AO basis) is located in the file
|
||||
:file:`qp2/src/mo_one_e_ints/ao_to_mo.irp.f`
|
||||
therefore it belongs to the module "mo_one_e_ints"
|
||||
:file:`qp2/src/ao_one_e_ints/ao_one_e_ints.irp.f`
|
||||
therefore it belongs to the module :ref:`module_ao_one_e_ints`
|
||||
|
||||
The provider :c:data:`one_e_dm_mo_beta_average` (which is the state average beta density matrix on the MO basis) is located in the file
|
||||
:file:`qp2/src/determinants/density_matrix.irp.f`
|
||||
therefore it belongs to the module "determinants"
|
||||
therefore it belongs to the module :ref:`module_determinants`
|
||||
|
||||
To import all the variables that you need, you just need to write the name of the plugins in the :file:`NEED` file .
|
||||
|
||||
To import all the variables/routines of the module "utils", "determinants" and "mo_one_e_ints", the :file:`NEED` file you will need is simply the following:
|
||||
To import all the variables/routines of the module :ref:`module_utils`, :ref:`module_determinants` and :ref:`module_mo_one_e_ints`, the :file:`NEED` file you will need is simply the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
@ -121,6 +121,7 @@ Example: execute the following command line :
|
||||
|
||||
Then all the information you need on :c:data:`ao_one_e_integrals` will appear on the screen.
|
||||
This includes
|
||||
|
||||
- **where** the provider is created, (*i.e.* the actual file where the provider is designed)
|
||||
- the **type** of the provider (*i.e.* a logical, integer etc ...)
|
||||
- the **dimension** if it is an array,
|
||||
|
@ -1,126 +1,218 @@
|
||||
=====================================================================
|
||||
Tutorial for plugin I: One-e integrals (duration: 20 minutes at most)
|
||||
=====================================================================
|
||||
=============================================
|
||||
Tuto I: One- and two-e integrals (20 minutes)
|
||||
=============================================
|
||||
|
||||
Requirements
|
||||
------------
|
||||
a) You know how to create an EZFIO file and run calculations with QP
|
||||
(check the tuto: `<https://quantumpackage.github.io/qp2/post/hartree-fock/>`),
|
||||
b) You have an EZFIO file with MOs created (with the 'scf' executable for instance).
|
||||
As we are going to print out some integrals, don't take a too large system/basis (Ex: H2, cc-pVDZ is ok :)
|
||||
c) You made an qp set_file YOUR_EZFIO_FILE_FOR_H2 in order to work on that ezfio folder,
|
||||
d) You have READ the ../README.rst file to HAVE THE VOCABULARY.
|
||||
1) You know how to create an |EZFIO| file and run calculations with |QP| (check the tuto: `<https://quantumpackage.github.io/qp2/post/hartree-fock/>`_),
|
||||
|
||||
2) You have an |EZFIO| file with MOs created (with the :ref:`scf` executable for instance). As we are going to print out some integrals, don't take a too large system/basis (Ex: H2, cc-pVDZ is ok :)
|
||||
|
||||
3) You made an qp set_file YOUR_EZFIO_FILE_FOR_H2 in order to work on that ezfio folder.
|
||||
|
||||
4) You have READ the :file:`qp2/plugins/README.rst` file to HAVE THE **VOCABULARY**.
|
||||
|
||||
Our goals:
|
||||
----------
|
||||
We want to create a plugin to do the following things:
|
||||
a) print out one- and two-electron integrals on the AO/MO basis,
|
||||
b) creates two providers which manipulate these objects,
|
||||
c) print out these providers,
|
||||
1) print out one- and two-electron integrals on the AO/MO basis,
|
||||
|
||||
I) Starting: creating the plugin
|
||||
--------------------------------
|
||||
2) creates two providers which manipulate these objects,
|
||||
|
||||
3) print out these providers.
|
||||
|
||||
I) Getting started: creating the plugin
|
||||
---------------------------------------
|
||||
We will go step-by-step through these plugins.
|
||||
|
||||
The name of the plugin will be "plugin_I", and its location is in "tuto_plugins".
|
||||
We will create a plugin named "plugin_I", and its location will be in "tuto_plugins".
|
||||
Therefore to create the plugin, we do:
|
||||
|
||||
qp plugins create -n plugin_I -r tuto_plugins
|
||||
.. code:: bash
|
||||
|
||||
qp plugins create -n plugin_I -r tuto_plugins
|
||||
|
||||
Then do an "ls" in qp2/plugins/tuto_plugins/ and you will find a directory called "plugin_I".
|
||||
|
||||
In that directory you will find:
|
||||
i) a "NEED" file that will eventually contain all the other modules/plugins needed by our "plugin_I"
|
||||
ii) a "README.rst" file that you can AND SHOULD modify in order to document what is doing the plugin.
|
||||
iii) a "plugin_I.irp.f" file that is a program to be compiled and just printing "Hello world"
|
||||
|
||||
1) a :file:`NEED` file that will eventually contain all the other modules/plugins needed by our "plugin_I",
|
||||
|
||||
2) a :file:`README.rst` file that you can and **SHOULD** modify in order to **DOCUMENT** what is doing the plugin,
|
||||
|
||||
3) a :file:`plugin_I.irp.f` file that is a program to be compiled and just printing "Hello world"
|
||||
|
||||
II) Specifying the dependencies
|
||||
-------------------------------
|
||||
The next step is to know what are the other modules/plugins that we need to do what we want.
|
||||
We need here
|
||||
a) the one-electron integrals on the AO basis, which are computed in qp2/src/ao_one_e_ints/
|
||||
b) the one-electron integrals on the MO basis, which are computed in qp2/src/mo_one_e_ints/
|
||||
c) the two-electron integrals on the AO basis, which are computed in qp2/src/ao_two_e_ints/
|
||||
d) the two-electron integrals on the MO basis, which are computed in qp2/src/mo_two_e_ints/
|
||||
|
||||
a) the one-electron integrals on the AO basis, which are computed in :file:`qp2/src/ao_one_e_ints/`
|
||||
|
||||
b) the one-electron integrals on the MO basis, which are computed in :file:`qp2/src/mo_one_e_ints/`
|
||||
|
||||
c) the two-electron integrals on the AO basis, which are computed in :file:`qp2/src/ao_two_e_ints/`
|
||||
|
||||
d) the two-electron integrals on the MO basis, which are computed in :file:`qp2/src/mo_two_e_ints/`
|
||||
|
||||
Therefore, we will need the following four modules:
|
||||
a) ao_one_e_ints
|
||||
b) mo_one_e_ints
|
||||
c) ao_two_e_ints
|
||||
d) mo_two_e_ints
|
||||
|
||||
a) ao_one_e_ints
|
||||
b) mo_one_e_ints
|
||||
c) ao_two_e_ints
|
||||
d) mo_two_e_ints
|
||||
|
||||
You can then create the following "NEED" file by executing the following command
|
||||
$ cat <<EOF > NEED
|
||||
ao_one_e_ints
|
||||
mo_one_e_ints
|
||||
ao_two_e_ints
|
||||
mo_two_e_ints
|
||||
EOF
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cat <<EOF > NEED
|
||||
ao_one_e_ints
|
||||
mo_one_e_ints
|
||||
ao_two_e_ints
|
||||
mo_two_e_ints
|
||||
EOF
|
||||
|
||||
II) Installing the plugin
|
||||
-------------------------
|
||||
Now that we have specified the various depenencies we need now to INSTALL the plugin, which means to create the equivalent of a Makefile for the compilation.
|
||||
|
||||
To do it we simply do
|
||||
$ qp plugins install plugin_I
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qp plugins install plugin_I
|
||||
|
||||
|
||||
III) Compiling the void plugin
|
||||
------------------------------
|
||||
It is customary to compile first your "void" plugin, void in the sense that it does not contain anything else than the program printing "Hello world".
|
||||
|
||||
To do so, just go in the plugin and execute the following command
|
||||
$ ninja
|
||||
|
||||
.. code:: bash
|
||||
|
||||
ninja
|
||||
|
||||
It does a lot of stuffs, but it must conclude with something like
|
||||
"
|
||||
make: Leaving directory 'SOME_PATH_TOWARD_YOUR_QP2_DIRECTORY/qp2/ocaml'
|
||||
"
|
||||
|
||||
.. code:: bash
|
||||
|
||||
make: Leaving directory 'SOME_PATH_TOWARD_YOUR_QP2_DIRECTORY/qp2/ocaml'
|
||||
|
||||
|
||||
Since that it has compiled, an executable "plugin_I" has been created.
|
||||
|
||||
Also, if you make "ls" in the "plugin_I" you will notice that many symbolink links have been created, and among which the four modules that you included in the NEED file.
|
||||
All the other modules (Ex:"ao_basis", "utils") are here because they are need by some of the four modules that you need.
|
||||
|
||||
All the other modules (Ex::ref:`module_ao_basis`, :ref:`module_utils`) are here because they are need by some of the four modules that you need.
|
||||
The variables that we need are
|
||||
ao_one_e_integrals
|
||||
mo_one_e_integrals
|
||||
|
||||
:data:`ao_one_e_integrals`
|
||||
|
||||
:data:`mo_one_e_integrals`
|
||||
|
||||
You can check them with
|
||||
irpman ao_one_e_integrals
|
||||
irpman mo_one_e_integrals
|
||||
|
||||
.. code:: bash
|
||||
|
||||
irpman ao_one_e_integrals
|
||||
|
||||
|
||||
.. code:: bash
|
||||
|
||||
irpman mo_one_e_integrals
|
||||
|
||||
in order to get some information on where they are created, and many more information.
|
||||
We will modify the executable such that it prints out the integrals.
|
||||
We will now create an executable such that it prints out the integrals.
|
||||
|
||||
|
||||
IV) Printing out the one-electron integrals
|
||||
--------------------------------------------
|
||||
We will create a program that will print out the one-electron integrals on the AO and MO basis.
|
||||
You can then copy the file "print_one_e_h.irp.f" located in "plugins/tuto_plugins/tuto_I" in your plugin.
|
||||
In the file you will see that we simply browse the two arrays "ao_one_e_integrals" and "mo_one_e_integrals", which are global variables (providers) and we browse them until either "ao_num" or "mo_num" which are also providers representing the number of AOs or MOs.
|
||||
You can check these variables with irpman !
|
||||
If you recompile using "ninja" as before, and another executable has been created "print_one_e_h".
|
||||
We will now create a program that will print out the one-electron integrals on the AO and MO basis.
|
||||
|
||||
You can then copy the file :file:`qp2/plugins/tuto_plugins/tuto_I/print_one_e_h.irp.f` in your plugin.
|
||||
|
||||
In this file you will see that we simply browse the two arrays :data:`ao_one_e_integrals` and :data:`mo_one_e_integrals`, which are the providers and we browse them until either :data:`ao_num` or :data:`mo_num` which are also providers representing the number of AOs or MOs.
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
You can check these variables with :command:`irpman` !
|
||||
|
||||
If you recompile using |ninja| as before, and another executable has been created "print_one_e_h".
|
||||
Then, you can run the program on the ezfio file by doing
|
||||
qp run print_one_e_h
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qp run print_one_e_h
|
||||
|
||||
and will print out the data you need :)
|
||||
|
||||
By the way, as the file "plugin_I.irp.f" contains nothing but a "Hello world" print, you can simply remove it if you want.
|
||||
By the way, as the file :file:`plugin_I.irp.f` contains nothing but a "Hello world" print, you can simply remove it if you want.
|
||||
|
||||
V) Printing out the two-electron integrals
|
||||
------------------------------------------
|
||||
We will now create a file that prints out the two-electron integrals in the AO and MO basis.
|
||||
These can be accessed with the following subroutines :
|
||||
+) get_ao_two_e_integral for the AO basis
|
||||
+) get_two_e_integral for the MO basis
|
||||
check them with irpman !
|
||||
To print the two-electron integrals, you can copy the file "print_two_e_h.irp.f" in your plugin and recompile.
|
||||
|
||||
1- :c:func:`get_ao_two_e_integral` for the AO basis
|
||||
|
||||
2- :c:func:`get_two_e_integral` for the MO basis
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
check them with irpman !
|
||||
|
||||
To print the two-electron integrals, you can copy the file :file:`qp2/plugins/tuto_plugins/tuto_I/print_two_e_h.irp.f` in your plugin and recompile with |ninja|.
|
||||
Then just run the program
|
||||
qp run print_two_e_h
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qp run print_two_e_h
|
||||
|
||||
and it will print all the things you want :)
|
||||
|
||||
VI) Creating new providers and a program to print them
|
||||
------------------------------------------------------
|
||||
We will now create new providers that manipulates the objects that we just printed.
|
||||
As an example, we will compute the trace of the one electron integrals in the AO and MO basis.
|
||||
In the file "traces_one_e.irp.f" you will find the several new providers among which
|
||||
a) trace_mo_one_e_ints : simply the sum of the diagonal matrix element of the one-electron integrals
|
||||
b) trace_ao_one_e_ints : the corresponding trace on the AO basis : Sum(m,n) S^{-1}_{mn} h_{mn}
|
||||
c) trace_ao_one_e_ints_from_mo : the trace on the AO basis with the integrals obtained first from the MO basis
|
||||
As explained in these files, "trace_mo_one_e_ints" is equal to "trace_ao_one_e_ints" only if the number of AO basis functions is equal to the number of MO basis functions, which means if you work with cartesian functions.
|
||||
(You can check with "qp create_ezfio -h" for the option to create an EZFIO with cartesian basis functions)
|
||||
In the file :file:`qp2/plugins/tuto_plugins/tuto_I/traces_one_e.irp.f` you will find the several new providers among which
|
||||
|
||||
In the file "print_traces_on_e.irp.f" you will find an example of executable that prints out the various providers.
|
||||
1- :c:data:`trace_mo_one_e_ints` : simply the sum of the diagonal matrix element of the one-electron integrals
|
||||
|
||||
2- :c:data:`trace_ao_one_e_ints` : the corresponding trace on the AO basis
|
||||
.. math::
|
||||
|
||||
\text{Tr}({\bf h}{\bf S}^{-1}) = \sum_{m,n} S^{-1}_{mn} h_{mn}
|
||||
|
||||
|
||||
3- :c:data:`trace_ao_one_e_ints_from_mo` : the trace on the AO basis with the integrals obtained first from the MO basis
|
||||
.. math::
|
||||
|
||||
\text{Tr}({\bf \tilde{h}}{\bf S}^{-1}) = \text{Tr}\big({\bf SC h}({\bf SC }^T){\bf S}^{-1}\big)
|
||||
|
||||
Just copy the :file:`qp2/plugins/tuto_plugins/tuto_I/traces_one_e.irp.f` in your plugin and recompile.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Once it has compiled, check your new providers with :command:`irpman` !
|
||||
|
||||
As explained in the files :file:`qp2/plugins/tuto_plugins/tuto_I/traces_one_e.irp.f` and :file:`qp2/plugins/tuto_plugins/tuto_I/print_traces_on_e.irp.f`, :c:data:`trace_mo_one_e_ints` is equal to :c:data:`trace_ao_one_e_ints` only if the number of AO basis functions is equal to the number of MO basis functions, which means if you work with cartesian functions.
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
You can check with :command:`qp create_ezfio -h` for the option to create an |EZFIO| with cartesian basis functions
|
||||
|
||||
In the file :file:`qp2/plugins/tuto_plugins/tuto_I/print_traces_on_e.irp.f` you will find an example of executable that prints out the various providers.
|
||||
Copy these two files in your plugin and recompile to execute it.
|
||||
|
||||
Execute the program print_traces_on_e and check for the results !
|
||||
Execute the program print_traces_on_e and check for the results with
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qp run print_traces_on_e
|
||||
|
||||
The code in :file:`qp2/plugins/tuto_plugins/tuto_I/print_traces_on_e.irp.f` should be easy to read, I let the reader interpret it.
|
||||
|
Loading…
Reference in New Issue
Block a user