From 1fd93d76b6ad7d7733834bae2da0b9dbbea8d49f Mon Sep 17 00:00:00 2001 From: eginer Date: Thu, 21 Mar 2024 15:31:06 +0100 Subject: [PATCH] working on the tuto --- plugins/README.rst | 76 +++++++++++++++ plugins/tuto_plugins/n2.xyz | 4 + .../tuto_plugins/tuto_I/print_one_e_h.irp.f | 20 ++++ plugins/tuto_plugins/tuto_I/tuto_I.rst | 97 +++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 plugins/README.rst create mode 100644 plugins/tuto_plugins/n2.xyz create mode 100644 plugins/tuto_plugins/tuto_I/print_one_e_h.irp.f create mode 100644 plugins/tuto_plugins/tuto_I/tuto_I.rst diff --git a/plugins/README.rst b/plugins/README.rst new file mode 100644 index 00000000..7f3f3c75 --- /dev/null +++ b/plugins/README.rst @@ -0,0 +1,76 @@ +============================== +Tutorial for creating a plugin +============================== + +Introduction: what is a plugin, and what this tuto 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 stuffs connected to the qp2/src/ stuffs. + +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 +in the modules ofqp2/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, + II) 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 Lapck or Davidson, + IV) print out the one- and two-electron rdms, + V) obtain the AOs and MOs on the DFT grid, together with the density, + +This tuto is as follows: + i) you READ THIS FILE UNTIL THE END in order to get the big picture and vocabulary, + ii) you go to the directory qp2/plugins/tuto_plugins/ and you will find detailed tuto there for each of the 5 examples. + +Creating a plugin: the basic +---------------------------- +The first thing to do is to be in the QPSH mode: you execute the qp2/bin/qpsh script that essentially loads all +the environement variables and allows for the completion of command lines in bash (that is an AMAZING feature :) + +Then, you need to known where you want to create your plugin, and what is the name of the plugin. +!!!! WARINING: The plugins are NECESSARILY located in qp2/plugins/ !!!! +Ex: If you want to create a plugin named "my_fancy_plugin" in the directory plugins/plugins_test/, +this goes with the command +qp plugins create -n my_fancy_plugin -r plugins_test/ + +Then, to create plugin of your dreams, the two questions you need to answer are the following: +a) What do I need to compute what I want, which means what are the objects that I need ? + There are two kind of objects: + + the routines/functions + Ex: Linear algebra routines, integration routines etc ... + + the global variables which are called the PROVIDERS + Ex: one-electron integrals, Slater determinants, density matrices etc ... +b) Where do I find these objects ? + The objects (routines/functions/providers) are necessarily created in other modules/plugins + Ex: the routine "lapack_diagd" (which diagonalises a real hermitian matrix) is located in the file + qp2/src/utils/linear_algebra.irp.f + therefore it "belongs" to the module "utils" + : the routine "ao_to_mo" (which converts a given matrix A from the AO basis to the MO basis) is located in the file + qp2/src/mo_one_e_ints/ao_to_mo.irp.f + therefore it "belongs" to the module "mo_one_e_ints" + : the provider "ao_one_e_integrals" (which is the integrals of one-body part of H on the AO basis) is located in the file + qp2/src/mo_one_e_ints/ao_to_mo.irp.f + therefore it belongs to the module "mo_one_e_ints" + : the provider "one_e_dm_mo_beta_average" (which is the state average beta density matrix on the MO basis) is located in the file + qp2/src/determinants/density_matrix.irp.f + therefore it belongs to the module "determinants" + +To import all the variables that you need, you just need to write the name of the plugins in the file "NEED" +Ex: to import all the variables/routines of the module "utils", "determinants" and "mo_one_e_ints" you will have the following NEED file: +utils +determinants +mo_one_e_ints + +TIPS +---- +There are many many routines/providers in the core modules of QP. Nevertheless, as everything is coded with the IRPF90, you can use the following amazing tools: irpman +irpman can be used in command line in bash to obtain all the info on a routine or variable ! +Ex: execute the following command line : +irpman ao_one_e_integrals +Then it appears all the information you want on ao_one_e_integrals, including where it is created, the type, dimension if it is an array, what providers it needs to be built, and what providers need this provider. + + diff --git a/plugins/tuto_plugins/n2.xyz b/plugins/tuto_plugins/n2.xyz new file mode 100644 index 00000000..016732d8 --- /dev/null +++ b/plugins/tuto_plugins/n2.xyz @@ -0,0 +1,4 @@ +2 +N2 Geo: Experiment Mult: 1 symmetry: 14 +N 0.0 0.0 0.5488 +N 0.0 0.0 -0.5488 diff --git a/plugins/tuto_plugins/tuto_I/print_one_e_h.irp.f b/plugins/tuto_plugins/tuto_I/print_one_e_h.irp.f new file mode 100644 index 00000000..5d8dc1e7 --- /dev/null +++ b/plugins/tuto_plugins/tuto_I/print_one_e_h.irp.f @@ -0,0 +1,20 @@ +program my_program_to_print_stuffs + implicit none + BEGIN_DOC +! TODO : Put the documentation of the program here + END_DOC + integer :: i,j + print*,'AO integrals ' + do i = 1, ao_num + do j = 1, ao_num + print*,j,i,ao_one_e_integrals(j,i) + enddo + enddo + + print*,'MO integrals ' + do i = 1, mo_num + do j = 1, mo_num + print*,j,i,mo_one_e_integrals(j,i) + enddo + enddo +end diff --git a/plugins/tuto_plugins/tuto_I/tuto_I.rst b/plugins/tuto_plugins/tuto_I/tuto_I.rst new file mode 100644 index 00000000..05db8635 --- /dev/null +++ b/plugins/tuto_plugins/tuto_I/tuto_I.rst @@ -0,0 +1,97 @@ +====================================== +Tutorial for plugin I: One-e integrals +====================================== + +!!! Requirements: + a) you know how to create an EZFIO file and run calculations with QP + (check the tuto: ``), + b) you have an EZFIO file in the sto-3g from the file H2.xyz in plugins/tuto_plugins, + and you have run an HF calculation giving an energy of -1.116759 a.u., + c) you made an qp set_file YOUR_EZFIO_FILE_FOR_H2 in order to be, + d) you have READ the ../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, + +I) Starting: 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". +Therefore to create the plugin, we do + +$ qp plugins create -n plugin_I -r tuto_plugins +Then to 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" + +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/ + +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 + +You can then create the following "NEED" file by executing the following command +$ cat < 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 + +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 +It does a lot of stuffs, but it must conclude with something like +" +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. +The variables that we need are +ao_one_e_integrals +mo_one_e_integrals +You can check them with +irpman ao_one_e_integral +irpman mo_one_e_integral +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. + + +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" 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". +Then, you can run the program on the ezfio file by doing +qp run print_one_e_h +and will print out the data you need :) +