1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-11-03 20:54:09 +01:00
qmckl/qmckl_examples.html

1359 lines
63 KiB
HTML

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2024-02-23 Fri 15:16 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Code examples</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="TREX CoE" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" title="Standard" href="qmckl.css" type="text/css" />
<script type="text/javascript" src="org-info.js">
/**
*
* @source: org-info.js
*
* @licstart The following is the entire license notice for the
* JavaScript code in org-info.js.
*
* Copyright (C) 2012-2020 Free Software Foundation, Inc.
*
*
* The JavaScript code in this tag is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* @licend The above is the entire license notice
* for the JavaScript code in org-info.js.
*
*/
</script>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2020 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
org_html_manager.set("TOC_DEPTH", "4");
org_html_manager.set("LINK_HOME", "index.html");
org_html_manager.set("LINK_UP", "");
org_html_manager.set("LOCAL_TOC", "1");
org_html_manager.set("VIEW_BUTTONS", "0");
org_html_manager.set("MOUSE_HINT", "underline");
org_html_manager.set("FIXED_TOC", "0");
org_html_manager.set("TOC", "1");
org_html_manager.set("VIEW", "info");
org_html_manager.setup(); // activate after the parameters are set
/*]]>*///-->
</script>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2020 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="org-div-home-and-up">
<a accesskey="h" href=""> UP </a>
|
<a accesskey="H" href="index.html"> HOME </a>
</div><div id="content">
<h1 class="title">Code examples</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgc5b9274">1. Overlap matrix in the MO basis</a>
<ul>
<li><a href="#org712031e">1.1. Python</a></li>
<li><a href="#org94bf33c">1.2. C</a></li>
<li><a href="#orgfd02750">1.3. Fortran</a></li>
</ul>
</li>
<li><a href="#org242e5bc">2. Fortran</a>
<ul>
<li><a href="#orgc63972a">2.1. Checking errors</a></li>
<li><a href="#org150be84">2.2. Computing an atomic orbital on a grid</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-orgc5b9274" class="outline-2">
<h2 id="orgc5b9274"><span class="section-number-2">1</span> Overlap matrix in the MO basis</h2>
<div class="outline-text-2" id="text-1">
<p>
The focal point of this example is the numerical evaluation of the overlap
matrix in the MO basis. Utilizing QMCkl, we approximate the MOs at
discrete grid points to compute the overlap matrix \( S_{ij} \) as follows:
\[
S_{ij} = \int \phi_i(\mathbf{r})\, \phi_j(\mathbf{r}) \text{d}\mathbf{r} \approx
\sum_k \phi_i(\mathbf{r}_k)\, \phi_j(\mathbf{r}_k) \delta\mathbf{r}
\]
</p>
<p>
The code starts by reading a wave function from a TREXIO file. This is
accomplished using the <code>qmckl_trexio_read</code> function, which populates a
<code>qmckl_context</code> with the necessary wave function parameters. The context
serves as the primary interface for interacting with the QMCkl library,
encapsulating the state and configurations of the system.
Subsequently, the code retrieves various attributes such as the number of
nuclei <code>nucl_num</code> and coordinates <code>nucl_coord</code>.
These attributes are essential for setting up the integration grid.
</p>
<p>
The core of the example lies in the numerical computation of the overlap
matrix. To achieve this, the code employs a regular grid in three-dimensional
space, and the grid points are then populated into the <code>qmckl_context</code> using
the <code>qmckl_set_point</code> function.
</p>
<p>
The MO values at these grid points are computed using the
<code>qmckl_get_mo_basis_mo_value</code> function. These values are then used to
calculate the overlap matrix through a matrix multiplication operation
facilitated by the <code>qmckl_dgemm</code> function.
</p>
<p>
The code is also instrumented to measure the execution time for the MO
value computation, providing an empirical assessment of the computational
efficiency. Error handling is robustly implemented at each stage to ensure the
reliability of the simulation.
</p>
<p>
In summary, this example serves as a holistic guide for leveraging the QMCkl
library, demonstrating its ease of use. It provides a concrete starting point
for researchers and developers interested in integrating QMCkl into their QMC
code.
</p>
</div>
<div id="outline-container-org712031e" class="outline-3">
<h3 id="org712031e"><span class="section-number-3">1.1</span> Python</h3>
<div class="outline-text-3" id="text-1-1">
<p>
In this example, we will compute numerically the overlap
between the molecular orbitals:
</p>
<p>
\[
S_{ij} = \int \phi_i(\mathbf{r}) \phi_j(\mathbf{r})
\text{d}\mathbf{r} \sim \sum_{k=1}^{N} \phi_i(\mathbf{r}_k)
\phi_j(\mathbf{r}_k) \delta \mathbf{r}
\]
\[
S_{ij} = \langle \phi_i | \phi_j \rangle
\sim \sum_{k=1}^{N} \langle \phi_i | \mathbf{r}_k \rangle
\langle \mathbf{r}_k | \phi_j \rangle
\]
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a020f0;">import</span> numpy <span style="color: #a020f0;">as</span> np
<span style="color: #a020f0;">import</span> qmckl
</pre>
</div>
<p>
First, we create a context for the QMCkl calculation, and load the
wave function stored in <code>h2o_5z.h5</code> inside it. It is a Hartree-Fock
determinant for the water molecule in the cc-pV5Z basis set.
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a0522d;">trexio_filename</span> = <span style="color: #8b2252;">"..//share/qmckl/test_data/h2o_5z.h5"</span>
<span style="color: #a0522d;">context</span> = qmckl.context_create()
qmckl.trexio_read(context, trexio_filename)
</pre>
</div>
<p>
We now define the grid points \(\mathbf{r}_k\) as a regular grid around the
molecule.
</p>
<p>
We fetch the nuclear coordinates from the context,
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a0522d;">nucl_num</span> = qmckl.get_nucleus_num(context)
<span style="color: #a0522d;">nucl_charge</span> = qmckl.get_nucleus_charge(context, nucl_num)
<span style="color: #a0522d;">nucl_coord</span> = qmckl.get_nucleus_coord(context, <span style="color: #8b2252;">'N'</span>, nucl_num*3)
<span style="color: #a0522d;">nucl_coord</span> = np.reshape(nucl_coord, (3, nucl_num))
<span style="color: #a020f0;">for</span> i <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(nucl_num):
<span style="color: #a020f0;">print</span>(<span style="color: #8b2252;">"%d %+f %+f %+f"</span>%(<span style="color: #483d8b;">int</span>(nucl_charge[i]),
nucl_coord[i,0],
nucl_coord[i,1],
nucl_coord[i,2]) )
</pre>
</div>
<pre class="example">
8 +0.000000 +0.000000 +0.000000
1 -1.430429 +0.000000 -1.107157
1 +1.430429 +0.000000 -1.107157
</pre>
<p>
and compute the coordinates of the grid points:
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a0522d;">nx</span> = ( 120, 120, 120 )
<span style="color: #a0522d;">shift</span> = np.array([5.,5.,5.])
<span style="color: #a0522d;">point_num</span> = nx[0] * nx[1] * nx[2]
<span style="color: #a0522d;">rmin</span> = np.array( <span style="color: #483d8b;">list</span>([ np.<span style="color: #483d8b;">min</span>(nucl_coord[:,a]) <span style="color: #a020f0;">for</span> a <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(3) ]) )
<span style="color: #a0522d;">rmax</span> = np.array( <span style="color: #483d8b;">list</span>([ np.<span style="color: #483d8b;">max</span>(nucl_coord[:,a]) <span style="color: #a020f0;">for</span> a <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(3) ]) )
<span style="color: #a0522d;">linspace</span> = [ <span style="color: #008b8b;">None</span> <span style="color: #a020f0;">for</span> i <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(3) ]
<span style="color: #a0522d;">step</span> = [ <span style="color: #008b8b;">None</span> <span style="color: #a020f0;">for</span> i <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(3) ]
<span style="color: #a020f0;">for</span> a <span style="color: #a020f0;">in</span> <span style="color: #483d8b;">range</span>(3):
linspace[a], <span style="color: #a0522d;">step</span>[a] = np.linspace(rmin[a]-shift[a],
rmax[a]+shift[a],
num=nx[a],
retstep=<span style="color: #008b8b;">True</span>)
<span style="color: #a0522d;">dr</span> = step[0] * step[1] * step[2]
</pre>
</div>
<p>
Now the grid is ready, we can create the list of grid points
\(\mathbf{r}_k\) on which the MOs \(\phi_i\) will be evaluated, and
transfer them to the QMCkl context:
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a0522d;">point</span> = []
<span style="color: #a020f0;">for</span> x <span style="color: #a020f0;">in</span> linspace[0]:
<span style="color: #a020f0;">for</span> y <span style="color: #a020f0;">in</span> linspace[1]:
<span style="color: #a020f0;">for</span> z <span style="color: #a020f0;">in</span> linspace[2]:
<span style="color: #a0522d;">point</span> += [ [x, y, z] ]
<span style="color: #a0522d;">point</span> = np.array(point)
<span style="color: #a0522d;">point_num</span> = <span style="color: #483d8b;">len</span>(point)
qmckl.set_point(context, <span style="color: #8b2252;">'N'</span>, point_num, np.reshape(point, (point_num*3)))
</pre>
</div>
<p>
Then, we evaluate all the MOs at the grid points (and time the execution),
and thus obtain the matrix \(M_{ki} = \langle \mathbf{r}_k | \phi_i \rangle =
\phi_i(\mathbf{r}_k)\).
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a020f0;">import</span> time
<span style="color: #a0522d;">mo_num</span> = qmckl.get_mo_basis_mo_num(context)
<span style="color: #a0522d;">before</span> = time.time()
<span style="color: #a0522d;">mo_value</span> = qmckl.get_mo_basis_mo_value(context, point_num*mo_num)
<span style="color: #a0522d;">after</span> = time.time()
<span style="color: #a0522d;">mo_value</span> = np.reshape( mo_value, (point_num, mo_num) ).T # <span style="color: #b22222;">Transpose to get mo_num x point_num</span>
<span style="color: #a020f0;">print</span>(<span style="color: #8b2252;">"Number of MOs: "</span>, mo_num)
<span style="color: #a020f0;">print</span>(<span style="color: #8b2252;">"Number of grid points: "</span>, point_num)
<span style="color: #a020f0;">print</span>(<span style="color: #8b2252;">"Execution time : "</span>, (after - before), <span style="color: #8b2252;">"seconds"</span>)
</pre>
</div>
<pre class="example">
Number of MOs: 201
Number of grid points: 1728000
Execution time : 5.577778577804565 seconds
</pre>
<p>
and finally we compute the overlap between all the MOs as
\(M.M^\dagger\).
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #a0522d;">overlap</span> = mo_value @ mo_value.T * dr
<span style="color: #a020f0;">print</span> (overlap)
</pre>
</div>
<pre class="example">
[[ 9.88693941e-01 2.34719693e-03 -1.50518232e-08 ... 3.12084178e-09
-5.81064929e-10 3.70130091e-02]
[ 2.34719693e-03 9.99509628e-01 3.18930040e-09 ... -2.46888958e-10
-1.06064273e-09 -7.65567973e-03]
[-1.50518232e-08 3.18930040e-09 9.99995073e-01 ... -5.84882580e-06
-1.21598117e-06 4.59036468e-08]
...
[ 3.12084178e-09 -2.46888958e-10 -5.84882580e-06 ... 1.00019107e+00
-2.03342837e-04 -1.36954855e-08]
[-5.81064929e-10 -1.06064273e-09 -1.21598117e-06 ... -2.03342837e-04
9.99262427e-01 1.18264754e-09]
[ 3.70130091e-02 -7.65567973e-03 4.59036468e-08 ... -1.36954855e-08
1.18264754e-09 8.97215950e-01]]
</pre>
</div>
</div>
<div id="outline-container-org94bf33c" class="outline-3">
<h3 id="org94bf33c"><span class="section-number-3">1.2</span> C</h3>
<div class="outline-text-3" id="text-1-2">
<p>
In this example, electron-nucleus cusp fitting is added.
</p>
<p>
In this example, we will compute numerically the overlap
between the molecular orbitals:
</p>
<p>
\[
S_{ij} = \int \phi_i(\mathbf{r}) \phi_j(\mathbf{r})
\text{d}\mathbf{r} \sim \sum_{k=1}^{N} \phi_i(\mathbf{r}_k)
\phi_j(\mathbf{r}_k) \delta \mathbf{r}
\]
\[
S_{ij} = \langle \phi_i | \phi_j \rangle
\sim \sum_{k=1}^{N} \langle \phi_i | \mathbf{r}_k \rangle
\langle \mathbf{r}_k | \phi_j \rangle
\]
</p>
<p>
We apply the cusp fitting procedure, so the MOs might deviate
slightly from orthonormality.
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #483d8b;">#include</span> <span style="color: #8b2252;">&lt;qmckl.h&gt;</span>
<span style="color: #483d8b;">#include</span> <span style="color: #8b2252;">&lt;stdio.h&gt;</span>
<span style="color: #483d8b;">#include</span> <span style="color: #8b2252;">&lt;string.h&gt;</span>
<span style="color: #483d8b;">#include</span> <span style="color: #8b2252;">&lt;sys/time.h&gt;</span>
<span style="color: #228b22;">int</span> <span style="color: #0000ff;">main</span>(<span style="color: #228b22;">int</span> <span style="color: #a0522d;">argc</span>, <span style="color: #228b22;">char</span>** <span style="color: #a0522d;">argv</span>)
{
<span style="color: #a020f0;">const</span> <span style="color: #228b22;">char</span>* <span style="color: #a0522d;">trexio_filename</span> = <span style="color: #8b2252;">"..//share/qmckl/test_data/h2o_5z.h5"</span>;
<span style="color: #228b22;">qmckl_exit_code</span> <span style="color: #a0522d;">rc</span> = QMCKL_SUCCESS;
</pre>
</div>
<p>
First, we create a context for the QMCkl calculation, and load the
wave function stored in <code>h2o_5z.h5</code> inside it. It is a Hartree-Fock
determinant for the water molecule in the cc-pV5Z basis set.
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #228b22;">qmckl_context</span> <span style="color: #a0522d;">context</span> = qmckl_context_create();
rc = qmckl_trexio_read(context, trexio_filename, strlen(trexio_filename));
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error reading TREXIO file:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
</pre>
</div>
<p>
We impose the electron-nucleus cusp fitting to occur when the
electrons are close to the nuclei. The critical distance
is 0.5 atomic units for hydrogens and 0.1 for the oxygen.
To identify which atom is an oxygen and which are hydrogens, we
fetch the nuclear charges from the context.
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #228b22;">int64_t</span> <span style="color: #a0522d;">nucl_num</span>;
rc = qmckl_get_nucleus_num(context, &amp;nucl_num);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error getting nucl_num:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">nucl_charge</span>[nucl_num];
rc = qmckl_get_nucleus_charge(context, &amp;(nucl_charge[0]), nucl_num);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error getting nucl_charge:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">r_cusp</span>[nucl_num];
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;nucl_num ; ++i) {
<span style="color: #a020f0;">switch</span> ((<span style="color: #228b22;">int</span>) nucl_charge[i]) {
<span style="color: #a020f0;">case</span> 1:
r_cusp[i] = 0.5;
<span style="color: #a020f0;">break</span>;
<span style="color: #a020f0;">case</span> 8:
r_cusp[i] = 0.1;
<span style="color: #a020f0;">break</span>;
}
}
rc = qmckl_set_mo_basis_r_cusp(context, &amp;(r_cusp[0]), nucl_num);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error setting r_cusp:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
</pre>
</div>
<p>
We now define the grid points \(\mathbf{r}_k\) as a regular grid around the
molecule.
We fetch the nuclear coordinates from the context,
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #228b22;">double</span> <span style="color: #a0522d;">nucl_coord</span>[nucl_num][3];
rc = qmckl_get_nucleus_coord(context, <span style="color: #8b2252;">'N'</span>, &amp;(nucl_coord[0][0]), nucl_num*3);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error getting nucl_coord:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;nucl_num ; ++i) {
printf(<span style="color: #8b2252;">"%d %+f %+f %+f\n"</span>,
(<span style="color: #228b22;">int32_t</span>) nucl_charge[i],
nucl_coord[i][0],
nucl_coord[i][1],
nucl_coord[i][2]);
}
</pre>
</div>
<pre class="example">
8 +0.000000 +0.000000 +0.000000
1 -1.430429 +0.000000 -1.107157
1 +1.430429 +0.000000 -1.107157
</pre>
<p>
and compute the coordinates of the grid points:
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">nx</span>[3] = { 120, 120, 120 };
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">shift</span>[3] = {5.,5.,5.};
<span style="color: #228b22;">int64_t</span> <span style="color: #a0522d;">point_num</span> = nx[0] * nx[1] * nx[2];
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">rmin</span>[3] = { nucl_coord[0][0], nucl_coord[0][1], nucl_coord[0][2] } ;
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">rmax</span>[3] = { nucl_coord[0][0], nucl_coord[0][1], nucl_coord[0][2] } ;
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;nucl_num ; ++i) {
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">int</span> <span style="color: #a0522d;">j</span>=0 ; j&lt;3 ; ++j) {
rmin[j] = nucl_coord[i][j] &lt; rmin[j] ? nucl_coord[i][j] : rmin[j];
rmax[j] = nucl_coord[i][j] &gt; rmax[j] ? nucl_coord[i][j] : rmax[j];
}
}
<span style="color: #228b22;">rmin</span>[0] -= shift[0]; <span style="color: #228b22;">rmin</span>[1] -= shift[1]; <span style="color: #228b22;">rmin</span>[2] -= shift[2];
<span style="color: #228b22;">rmax</span>[0] += shift[0]; <span style="color: #228b22;">rmax</span>[1] += shift[1]; <span style="color: #228b22;">rmax</span>[2] += shift[2];
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">step</span>[3];
<span style="color: #228b22;">double</span>* <span style="color: #a0522d;">linspace</span>[3];
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">int</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;3 ; ++i) {
linspace[i] = (<span style="color: #228b22;">double</span>*) calloc( <span style="color: #a020f0;">sizeof</span>(<span style="color: #228b22;">double</span>), nx[i] );
<span style="color: #a020f0;">if</span> (linspace[i] == <span style="color: #008b8b;">NULL</span>) {
fprintf(stderr, <span style="color: #8b2252;">"Allocation failed (linspace)\n"</span>);
exit(1);
}
step[i] = (rmax[i] - rmin[i]) / ((<span style="color: #228b22;">double</span>) (nx[i]-1));
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">j</span>=0 ; j&lt;nx[i] ; ++j) {
linspace[i][j] = rmin[i] + j*step[i];
}
}
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">dr</span> = step[0] * step[1] * step[2];
</pre>
</div>
<p>
Now the grid is ready, we can create the list of grid points
\(\mathbf{r}_k\) on which the MOs \(\phi_i\) will be evaluated, and
transfer them to the QMCkl context:
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #228b22;">double</span>* <span style="color: #a0522d;">point</span> = (<span style="color: #228b22;">double</span>*) calloc(<span style="color: #a020f0;">sizeof</span>(<span style="color: #228b22;">double</span>), 3*point_num);
<span style="color: #a020f0;">if</span> (point == <span style="color: #008b8b;">NULL</span>) {
fprintf(stderr, <span style="color: #8b2252;">"Allocation failed (point)\n"</span>);
exit(1);
}
<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">m</span> = 0;
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;nx[0] ; ++i) {
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">j</span>=0 ; j&lt;nx[1] ; ++j) {
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">k</span>=0 ; k&lt;nx[2] ; ++k) {
point[m] = linspace[0][i];
m++;
point[m] = linspace[1][j];
m++;
point[m] = linspace[2][k];
m++;
}
}
}
rc = qmckl_set_point(context, <span style="color: #8b2252;">'N'</span>, point_num, point, (point_num*3));
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error setting points:\n%s\n"</span>, qmckl_string_of_error(rc));
exit(1);
}
</pre>
</div>
<p>
Then, we evaluate all the MOs at the grid points (and time the execution),
and thus obtain the matrix \(M_{ki} = \langle \mathbf{r}_k | \phi_i
\rangle = \phi_i(\mathbf{r}_k)\).
</p>
<div class="org-src-container">
<pre class="src src-c">
<span style="color: #228b22;">int64_t</span> <span style="color: #a0522d;">mo_num</span>;
rc = qmckl_get_mo_basis_mo_num(context, &amp;mo_num);
<span style="color: #228b22;">long</span> <span style="color: #a0522d;">before</span>, <span style="color: #a0522d;">after</span>;
<span style="color: #a020f0;">struct</span> <span style="color: #228b22;">timeval</span> <span style="color: #a0522d;">timecheck</span>;
<span style="color: #228b22;">double</span>* <span style="color: #a0522d;">mo_value</span> = (<span style="color: #228b22;">double</span>*) calloc(<span style="color: #a020f0;">sizeof</span>(<span style="color: #228b22;">double</span>), point_num*mo_num);
<span style="color: #a020f0;">if</span> (mo_value == <span style="color: #008b8b;">NULL</span>) {
fprintf(stderr, <span style="color: #8b2252;">"Allocation failed (mo_value)\n"</span>);
exit(1);
}
gettimeofday(&amp;timecheck, <span style="color: #008b8b;">NULL</span>);
before = (<span style="color: #228b22;">long</span>)timecheck.tv_sec * 1000 + (<span style="color: #228b22;">long</span>)timecheck.tv_usec / 1000;
rc = qmckl_get_mo_basis_mo_value(context, mo_value, point_num*mo_num);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error getting mo_value)\n"</span>);
exit(1);
}
gettimeofday(&amp;timecheck, <span style="color: #008b8b;">NULL</span>);
after = (<span style="color: #228b22;">long</span>)timecheck.tv_sec * 1000 + (<span style="color: #228b22;">long</span>)timecheck.tv_usec / 1000;
printf(<span style="color: #8b2252;">"Number of MOs: %ld\n"</span>, (<span style="color: #228b22;">long</span>) mo_num);
printf(<span style="color: #8b2252;">"Number of grid points: %ld\n"</span>, (<span style="color: #228b22;">long</span>) point_num);
printf(<span style="color: #8b2252;">"Execution time : %f seconds\n"</span>, (after - before)*1.e-3);
</pre>
</div>
<pre class="example">
Number of MOs: 201
Number of grid points: 1728000
Execution time : 5.608000 seconds
</pre>
<p>
and finally we compute the overlap between all the MOs as
\(M.M^\dagger\).
</p>
<div class="org-src-container">
<pre class="src src-c"> <span style="color: #228b22;">double</span>* <span style="color: #a0522d;">overlap</span> = (<span style="color: #228b22;">double</span>*) <span style="color: #0000ff;">malloc</span> (<span style="color: #228b22;">mo_num</span>*<span style="color: #0000ff;">mo_num</span>*<span style="color: #a020f0;">sizeof</span>(<span style="color: #228b22;">double</span>));
rc = qmckl_dgemm(context, <span style="color: #8b2252;">'N'</span>, <span style="color: #8b2252;">'T'</span>, mo_num, mo_num, point_num, dr,
mo_value, mo_num, mo_value, mo_num, 0.0,
overlap, mo_num);
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">i</span>=0 ; i&lt;mo_num ; ++i) {
printf(<span style="color: #8b2252;">"%4ld"</span>, i);
<span style="color: #a020f0;">for</span> (<span style="color: #228b22;">size_t</span> <span style="color: #a0522d;">j</span>=0 ; j&lt;mo_num ; ++j) {
printf(<span style="color: #8b2252;">" %f"</span>, overlap[i*mo_num+j]);
}
printf(<span style="color: #8b2252;">"\n"</span>);
}
// <span style="color: #b22222;">Clean-up and exit</span>
<span style="color: #0000ff;">free</span>(mo_value);
<span style="color: #0000ff;">free</span>(overlap);
rc = qmckl_context_destroy(context);
<span style="color: #a020f0;">if</span> (rc != QMCKL_SUCCESS) {
fprintf(stderr, <span style="color: #8b2252;">"Error destroying context)\n"</span>);
exit(1);
}
<span style="color: #a020f0;">return</span> 0;
}
</pre>
</div>
<pre class="example">
0 0.988765 0.002336 0.000000 -0.000734 0.000000 0.000530 0.000000 0.000446 0.000000 -0.000000 -0.000511 -0.000000 -0.000267 0.000000 0.000000 0.001007 0.000000 0.000168 -0.000000 -0.000000 -0.000670 -0.000000 0.000000 -0.000251 -0.000261 -0.000000 -0.000000 -0.000000 -0.000397 -0.000000 -0.000810 0.000000 0.000231 -0.000000 -0.000000 0.000000 -0.000000
...
200 0.039017 -0.013066 -0.000000 -0.001935 -0.000000 -0.003829 -0.000000 0.000996 -0.000000 0.000000 -0.003733 0.000000 0.000065 -0.000000 -0.000000 -0.002220 -0.000000 -0.001961 0.000000 0.000000 -0.004182 0.000000 -0.000000 -0.000165 -0.002445 0.000000 -0.000000 0.000000 0.001985 0.000000 0.001685 -0.000000 -0.002899 0.000000 0.000000 0.000000 -0.000000 0.002591 0.000000 -0.000000 0.000000 0.002385 0.000000 -0.011086 0.000000 -0.003885 0.000000 -0.000000 0.003602 -0.000000 0.000000 -0.003241 0.000000 0.000000 0.002613 -0.007344 -0.000000 -0.000000 0.000000 0.000017 0.000000 0.000000 0.000000 -0.008719 0.000000 -0.001358 -0.003233 0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.003778 0.000000 0.000000 -0.000000 0.000000 0.000000 -0.001190 0.000000 0.000000 -0.000000 0.005578 -0.000000 -0.001502 0.003899 -0.000000 -0.000000 0.000000 -0.003291 -0.001775 -0.000000 -0.002374 0.000000 -0.000000 -0.000000 -0.000000 -0.001290 -0.000000 0.002178 0.000000 0.000000 0.000000 -0.001252 0.000000 -0.000000 -0.000926 0.000000 -0.000000 -0.013130 -0.000000 0.012124 0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.025194 0.000343 -0.000000 0.000000 -0.000000 -0.004421 0.000000 0.000000 -0.000599 -0.000000 0.005289 0.000000 -0.000000 0.012826 -0.000000 0.000000 0.006190 0.000000 0.000000 -0.000000 0.000000 -0.000321 0.000000 -0.000000 -0.000000 0.000000 -0.000000 0.001499 -0.006629 0.000000 0.000000 0.000000 -0.000000 0.008737 -0.000000 0.006880 0.000000 -0.001851 -0.000000 -0.000000 0.000000 -0.007464 0.000000 0.010298 -0.000000 -0.000000 -0.000000 -0.000000 -0.000000 0.000000 0.000540 0.000000 -0.006616 -0.000000 0.000000 -0.002927 -0.000000 0.000000 0.010352 0.000000 -0.003103 -0.000000 -0.007640 -0.000000 -0.000000 0.005302 0.000000 0.000000 -0.000000 -0.000000 -0.010181 0.000000 -0.001108 0.000000 0.000000 -0.000000 0.000000 0.000000 -0.000998 -0.009754 0.013562 0.000000 -0.000000 0.887510
</pre>
</div>
</div>
<div id="outline-container-orgfd02750" class="outline-3">
<h3 id="orgfd02750"><span class="section-number-3">1.3</span> Fortran</h3>
<div class="outline-text-3" id="text-1-3">
<p>
Here is the same piece of code translated in Fortran
</p>
<div class="org-src-container">
<pre class="src src-f90"><span style="color: #483d8b;">#include</span> <span style="color: #8b2252;">&lt;qmckl_f.F90&gt;</span>
<span style="color: #a020f0;">program</span> <span style="color: #0000ff;">main</span>
<span style="color: #a020f0;">use</span> <span style="color: #0000ff;">iso_c_binding</span>
<span style="color: #a020f0;">use</span> <span style="color: #0000ff;">qmckl</span>
<span style="color: #a020f0;">implicit</span> <span style="color: #228b22;">none</span>
! <span style="color: #b22222;">Declare variables</span>
<span style="color: #228b22;">integer</span> ::<span style="color: #a0522d;"> argc</span>
<span style="color: #228b22;">character</span>(128) ::<span style="color: #a0522d;"> trexio_filename, err_msg</span>
<span style="color: #228b22;">integer</span>(qmckl_exit_code) ::<span style="color: #a0522d;"> rc</span>
<span style="color: #228b22;">integer</span>(qmckl_context) ::<span style="color: #a0522d;"> context</span>
<span style="color: #228b22;">integer</span>*8 ::<span style="color: #a0522d;"> nucl_num, mo_num, point_num</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">allocatable</span> ::<span style="color: #a0522d;"> nucl_coord(:,:)</span>
<span style="color: #228b22;">integer</span>*8 ::<span style="color: #a0522d;"> nx(3)</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">dimension</span>(3) ::<span style="color: #a0522d;"> shift, step, rmin, rmax</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">allocatable</span> ::<span style="color: #a0522d;"> mo_value(:,:), overlap(:,:), point(:), linspace(:,:)</span>
<span style="color: #228b22;">double precision</span> ::<span style="color: #a0522d;"> before, after, dr</span>
<span style="color: #228b22;">integer</span>*8 ::<span style="color: #a0522d;"> i,j,k,m</span>
! <span style="color: #b22222;">Initialize variables</span>
err_msg = <span style="color: #8b2252;">' '</span>
argc = <span style="color: #a020f0;">command_argument_count</span>()
<span style="color: #a020f0;">if</span> (argc /= 1) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, <span style="color: #8b2252;">"Usage: ./program &lt;TREXIO filename&gt;"</span>
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">get_command_argument</span>(1, trexio_filename)
rc = QMCKL_SUCCESS
! <span style="color: #b22222;">Create a QMCkl context</span>
context = qmckl_context_create()
! <span style="color: #b22222;">Read the TREXIO file into the context</span>
rc = qmckl_trexio_read(context, <span style="color: #a020f0;">trim</span>(trexio_filename), <span style="color: #a020f0;">len</span>(trexio_filename)*1_8)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error reading TREXIO file:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
! <span style="color: #b22222;">Retrieve the number of nuclei</span>
rc = qmckl_get_nucleus_num(context, nucl_num)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error getting nucl_num:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
! <span style="color: #b22222;">Retrieve the nuclear coordinates</span>
<span style="color: #a020f0;">allocate</span>(nucl_coord(3, nucl_num))
rc = qmckl_get_nucleus_coord(context, <span style="color: #8b2252;">'N'</span>, nucl_coord, nucl_num * 3_8)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error getting nucl_coord:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
! <span style="color: #b22222;">Retrieve the number of MOs</span>
rc = qmckl_get_mo_basis_mo_num(context, mo_num)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error getting mo_num:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
! <span style="color: #b22222;">Initialize grid points for the calculation</span>
nx = (/ 120, 120, 120 /)
shift = (/ 5.d0, 5.d0, 5.d0 /)
point_num = nx(1) * nx(2) * nx(3)
! <span style="color: #b22222;">Initialize rmin and rmax</span>
rmin = nucl_coord(:,1)
rmax = nucl_coord(:,1)
! <span style="color: #b22222;">Update rmin and rmax based on nucl_coord</span>
<span style="color: #a020f0;">do</span> i = 1, 3
<span style="color: #a020f0;">do</span> j = 1, nucl_num
rmin(i) = <span style="color: #a020f0;">min</span>(nucl_coord(i,j), rmin(i))
rmax(i) = <span style="color: #a020f0;">max</span>(nucl_coord(i,j), rmax(i))
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">end do</span>
! <span style="color: #b22222;">Apply shift</span>
rmin = rmin - shift
rmax = rmax + shift
! <span style="color: #b22222;">Initialize linspace and step</span>
<span style="color: #a020f0;">allocate</span>(linspace(3, <span style="color: #a020f0;">maxval</span>(nx)))
<span style="color: #a020f0;">do</span> i = 1, 3
step(i) = (rmax(i) - rmin(i)) / <span style="color: #a020f0;">real</span>(nx(i) - 1, 8)
<span style="color: #a020f0;">do</span> j = 1, nx(i)
linspace(i, j) = rmin(i) + (j - 1) * step(i)
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">end do</span>
! <span style="color: #b22222;">Initialize point array</span>
<span style="color: #a020f0;">allocate</span>(point(3 * point_num))
m = 1
<span style="color: #a020f0;">do</span> i = 1, nx(1)
<span style="color: #a020f0;">do</span> j = 1, nx(2)
<span style="color: #a020f0;">do</span> k = 1, nx(3)
point(m) = linspace(1, i); m = m + 1
point(m) = linspace(2, j); m = m + 1
point(m) = linspace(3, k); m = m + 1
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">deallocate</span>(linspace)
! <span style="color: #b22222;">Set points in QMCKL context</span>
rc = qmckl_set_point(context, <span style="color: #8b2252;">'N'</span>, point_num, point, point_num * 3)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error setting point:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
! <span style="color: #b22222;">Perform the actual calculation and measure the time taken</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">cpu_time</span>(before)
<span style="color: #a020f0;">allocate</span>(mo_value(point_num, mo_num))
rc = qmckl_get_mo_basis_mo_value(context, mo_value, point_num * mo_num)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error getting mo_value:"</span>, err_msg
<span style="color: #a020f0;">stop</span>
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">cpu_time</span>(after)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Number of MOs:"</span>, mo_num
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Number of grid points:"</span>, point_num
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Execution time:"</span>, (after - before), <span style="color: #8b2252;">"seconds"</span>
! <span style="color: #b22222;">Compute the overlap matrix</span>
dr = step(1) * step(2) * step(3)
<span style="color: #a020f0;">allocate</span>(overlap(mo_num, mo_num))
rc = qmckl_dgemm(context, <span style="color: #8b2252;">'N'</span>, <span style="color: #8b2252;">'T'</span>, mo_num, mo_num, point_num, dr, <span style="color: #a020f0;">&amp;</span>
mo_value, mo_num, mo_value, mo_num, 0.d0, overlap, mo_num)
! <span style="color: #b22222;">Print the overlap matrix</span>
<span style="color: #a020f0;">do</span> i = 1, mo_num
<span style="color: #a020f0;">write</span>(*,<span style="color: #8b2252;">'(i4)'</span>, advance=<span style="color: #8b2252;">'no'</span>) i
<span style="color: #a020f0;">do</span> j = 1, mo_num
<span style="color: #a020f0;">write</span>(*,<span style="color: #8b2252;">'(f8.4)'</span>, advance=<span style="color: #8b2252;">'no'</span>) overlap(i, j)
<span style="color: #a020f0;">end do</span>
<span style="color: #a020f0;">write</span>(*,*)
<span style="color: #a020f0;">end do</span>
! <span style="color: #b22222;">Clean-up and exit</span>
<span style="color: #a020f0;">deallocate</span>(mo_value, overlap)
rc = qmckl_context_destroy(context)
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, err_msg)
<span style="color: #a020f0;">write</span>(*,*) <span style="color: #8b2252;">"Error destroying context:"</span>, err_msg
<span style="color: #a020f0;">stop</span> -1
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">end program</span> <span style="color: #0000ff;">main</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org242e5bc" class="outline-2">
<h2 id="org242e5bc"><span class="section-number-2">2</span> Fortran</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-orgc63972a" class="outline-3">
<h3 id="orgc63972a"><span class="section-number-3">2.1</span> Checking errors</h3>
<div class="outline-text-3" id="text-2-1">
<p>
All QMCkl functions return an error code. A convenient way to handle
errors is to write an error-checking function that displays the
error in text format and exits the program.
</p>
<div class="org-src-container">
<pre class="src src-f90" id="org2a82012"><span style="color: #a020f0;">subroutine</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, message)
<span style="color: #a020f0;">use</span> <span style="color: #0000ff;">qmckl</span>
<span style="color: #a020f0;">implicit</span> <span style="color: #228b22;">none</span>
<span style="color: #228b22;">integer</span>(qmckl_exit_code), <span style="color: #a020f0;">intent</span>(in) ::<span style="color: #a0522d;"> rc</span>
<span style="color: #228b22;">character</span>(len=*) , <span style="color: #a020f0;">intent</span>(in) ::<span style="color: #a0522d;"> message</span>
<span style="color: #228b22;">character</span>(len=128) ::<span style="color: #a0522d;"> str_buffer</span>
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, message
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, str_buffer)
<span style="color: #a020f0;">print</span> *, str_buffer
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">exit</span>(rc)
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">end subroutine</span> <span style="color: #0000ff;">qmckl_check_error</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org150be84" class="outline-3">
<h3 id="org150be84"><span class="section-number-3">2.2</span> Computing an atomic orbital on a grid</h3>
<div class="outline-text-3" id="text-2-2">
<p>
The following program, in Fortran, computes the values of an atomic
orbital on a regular 3-dimensional grid. The 100<sup>3</sup> grid points are
automatically defined, such that the molecule fits in a box with 5
atomic units in the borders.
</p>
<p>
This program uses the <code>qmckl_check_error</code> function defined above.
</p>
<p>
To use this program, run
</p>
<div class="org-src-container">
<pre class="src src-bash">$ ao_grid &lt;trexio_file&gt; &lt;AO_id&gt; &lt;point_num&gt;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-f90"><span style="color: #a020f0;">subroutine</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, message)
<span style="color: #a020f0;">use</span> <span style="color: #0000ff;">qmckl</span>
<span style="color: #a020f0;">implicit</span> <span style="color: #228b22;">none</span>
<span style="color: #228b22;">integer</span>(qmckl_exit_code), <span style="color: #a020f0;">intent</span>(in) ::<span style="color: #a0522d;"> rc</span>
<span style="color: #228b22;">character</span>(len=*) , <span style="color: #a020f0;">intent</span>(in) ::<span style="color: #a0522d;"> message</span>
<span style="color: #228b22;">character</span>(len=128) ::<span style="color: #a0522d;"> str_buffer</span>
<span style="color: #a020f0;">if</span> (rc /= QMCKL_SUCCESS) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, message
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_string_of_error</span>(rc, str_buffer)
<span style="color: #a020f0;">print</span> *, str_buffer
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">exit</span>(rc)
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">end subroutine</span> <span style="color: #0000ff;">qmckl_check_error</span>
<span style="color: #a020f0;">program</span> <span style="color: #0000ff;">ao_grid</span>
<span style="color: #a020f0;">use</span> <span style="color: #0000ff;">qmckl</span>
<span style="color: #a020f0;">implicit</span> <span style="color: #228b22;">none</span>
<span style="color: #228b22;">integer</span>(qmckl_context) ::<span style="color: #a0522d;"> qmckl_ctx </span>! <span style="color: #b22222;">QMCkl context</span>
<span style="color: #228b22;">integer</span>(qmckl_exit_code) ::<span style="color: #a0522d;"> rc </span>! <span style="color: #b22222;">Exit code of QMCkl functions</span>
<span style="color: #228b22;">character</span>(len=128) ::<span style="color: #a0522d;"> trexio_filename</span>
<span style="color: #228b22;">character</span>(len=128) ::<span style="color: #a0522d;"> str_buffer</span>
<span style="color: #228b22;">integer</span> ::<span style="color: #a0522d;"> ao_id</span>
<span style="color: #228b22;">integer</span> ::<span style="color: #a0522d;"> point_num_x</span>
<span style="color: #228b22;">integer</span>(<span style="color: #008b8b;">c_int64_t</span>) ::<span style="color: #a0522d;"> nucl_num</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">allocatable</span> ::<span style="color: #a0522d;"> nucl_coord(:,:)</span>
<span style="color: #228b22;">integer</span>(<span style="color: #008b8b;">c_int64_t</span>) ::<span style="color: #a0522d;"> point_num</span>
<span style="color: #228b22;">integer</span>(<span style="color: #008b8b;">c_int64_t</span>) ::<span style="color: #a0522d;"> ao_num</span>
<span style="color: #228b22;">integer</span>(<span style="color: #008b8b;">c_int64_t</span>) ::<span style="color: #a0522d;"> ipoint, i, j, k</span>
<span style="color: #228b22;">double precision</span> ::<span style="color: #a0522d;"> x, y, z, dr(3)</span>
<span style="color: #228b22;">double precision</span> ::<span style="color: #a0522d;"> rmin(3), rmax(3)</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">allocatable</span> ::<span style="color: #a0522d;"> points(:,:)</span>
<span style="color: #228b22;">double precision</span>, <span style="color: #a020f0;">allocatable</span> ::<span style="color: #a0522d;"> ao_vgl(:,:,:)</span>
</pre>
</div>
<p>
Start by fetching the command-line arguments:
</p>
<div class="org-src-container">
<pre class="src src-f90"><span style="color: #a020f0;">if</span> (iargc() /= 3) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, <span style="color: #8b2252;">'Syntax: ao_grid &lt;trexio_file&gt; &lt;AO_id&gt; &lt;point_num&gt;'</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">exit</span>(-1)
<span style="color: #a020f0;">end if</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">getarg</span>(1, trexio_filename)
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">getarg</span>(2, str_buffer)
<span style="color: #a020f0;">read</span>(str_buffer, *) ao_id
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">getarg</span>(3, str_buffer)
<span style="color: #a020f0;">read</span>(str_buffer, *) point_num_x
<span style="color: #a020f0;">if</span> (point_num_x &lt; 0 <span style="color: #a020f0;">.or.</span> point_num_x &gt; 300) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, <span style="color: #8b2252;">'Error: 0 &lt; point_num &lt; 300'</span>
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">exit</span>(-1)
<span style="color: #a020f0;">end if</span>
</pre>
</div>
<p>
Create the QMCkl context and initialize it with the wave function
present in the TREXIO file:
</p>
<div class="org-src-container">
<pre class="src src-f90">qmckl_ctx = qmckl_context_create()
rc = qmckl_trexio_read(qmckl_ctx, trexio_filename, 1_8*<span style="color: #a020f0;">len</span>(<span style="color: #a020f0;">trim</span>(trexio_filename)))
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Read TREXIO'</span>)
</pre>
</div>
<p>
We need to check that <code>ao_id</code> is in the range, so we get the total
number of AOs from QMCkl:
</p>
<div class="org-src-container">
<pre class="src src-f90">rc = qmckl_get_ao_basis_ao_num(qmckl_ctx, ao_num)
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Getting ao_num'</span>)
<span style="color: #a020f0;">if</span> (ao_id &lt; 0 <span style="color: #a020f0;">.or.</span> ao_id &gt; ao_num) <span style="color: #a020f0;">then</span>
<span style="color: #a020f0;">print</span> *, <span style="color: #8b2252;">'Error: 0 &lt; ao_id &lt; '</span>, ao_num
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">exit</span>(-1)
<span style="color: #a020f0;">end if</span>
</pre>
</div>
<p>
Now we will compute the limits of the box in which the molecule fits.
For that, we first need to ask QMCkl the coordinates of nuclei.
</p>
<div class="org-src-container">
<pre class="src src-f90">rc = qmckl_get_nucleus_num(qmckl_ctx, nucl_num)
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Get nucleus num'</span>)
<span style="color: #a020f0;">allocate</span>( nucl_coord(3, nucl_num) )
rc = qmckl_get_nucleus_coord(qmckl_ctx, <span style="color: #8b2252;">'N'</span>, nucl_coord, 3_8*nucl_num)
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Get nucleus coord'</span>)
</pre>
</div>
<p>
We now compute the coordinates of opposite points of the box, and
the distance between points along the 3 directions:
</p>
<div class="org-src-container">
<pre class="src src-f90">rmin(1) = <span style="color: #a020f0;">minval</span>( nucl_coord(1,:) ) - 5.d0
rmin(2) = <span style="color: #a020f0;">minval</span>( nucl_coord(2,:) ) - 5.d0
rmin(3) = <span style="color: #a020f0;">minval</span>( nucl_coord(3,:) ) - 5.d0
rmax(1) = <span style="color: #a020f0;">maxval</span>( nucl_coord(1,:) ) + 5.d0
rmax(2) = <span style="color: #a020f0;">maxval</span>( nucl_coord(2,:) ) + 5.d0
rmax(3) = <span style="color: #a020f0;">maxval</span>( nucl_coord(3,:) ) + 5.d0
dr(1:3) = (rmax(1:3) - rmin(1:3)) / <span style="color: #a020f0;">dble</span>(point_num_x-1)
</pre>
</div>
<p>
We now produce the list of point coordinates where the AO will be
evaluated:
</p>
<div class="org-src-container">
<pre class="src src-f90">point_num = point_num_x**3
<span style="color: #a020f0;">allocate</span>( points(point_num, 3) )
ipoint=0
z = rmin(3)
<span style="color: #a020f0;">do</span> k=1,point_num_x
y = rmin(2)
<span style="color: #a020f0;">do</span> j=1,point_num_x
x = rmin(1)
<span style="color: #a020f0;">do</span> i=1,point_num_x
ipoint = ipoint+1
points(ipoint,1) = x
points(ipoint,2) = y
points(ipoint,3) = z
x = x + dr(1)
<span style="color: #a020f0;">end do</span>
y = y + dr(2)
<span style="color: #a020f0;">end do</span>
z = z + dr(3)
<span style="color: #a020f0;">end do</span>
</pre>
</div>
<p>
We give the points to QMCkl:
</p>
<div class="org-src-container">
<pre class="src src-f90">rc = qmckl_set_point(qmckl_ctx, <span style="color: #8b2252;">'T'</span>, point_num, points, <span style="color: #a020f0;">size</span>(points)*1_8 )
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Setting points'</span>)
</pre>
</div>
<p>
We allocate the space required to retrieve the values, gradients and
Laplacian of all AOs, and ask to retrieve the values of the
AOs computed at the point positions.
</p>
<div class="org-src-container">
<pre class="src src-f90"><span style="color: #a020f0;">allocate</span>( ao_vgl(ao_num, 5, point_num) )
rc = qmckl_get_ao_basis_ao_vgl(qmckl_ctx, ao_vgl, ao_num*5_8*point_num)
<span style="color: #a020f0;">call</span> <span style="color: #0000ff;">qmckl_check_error</span>(rc, <span style="color: #8b2252;">'Setting points'</span>)
</pre>
</div>
<p>
We finally print the value and Laplacian of the AO:
</p>
<div class="org-src-container">
<pre class="src src-f90"><span style="color: #a020f0;">do</span> ipoint=1, point_num
<span style="color: #a020f0;">print</span> <span style="color: #8b2252;">'(3(F10.6,X),2(E20.10,X))'</span>, points(ipoint, 1:3), ao_vgl(ao_id,1,ipoint), ao_vgl(ao_id,5,ipoint)
<span style="color: #a020f0;">end do</span>
</pre>
</div>
<div class="org-src-container">
<pre class="src src-f90"> <span style="color: #a020f0;">deallocate</span>( nucl_coord, points, ao_vgl )
<span style="color: #a020f0;">end program</span> <span style="color: #0000ff;">ao_grid</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: TREX CoE</p>
<p class="date">Created: 2024-02-23 Fri 15:16</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>