mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-12-22 12:23:31 +01:00
Localization
This commit is contained in:
parent
8502befb65
commit
0b6fe42e55
@ -3,7 +3,7 @@
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2021-01-27 Wed 23:44 -->
|
||||
<!-- 2021-01-29 Fri 15:35 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Linear Algebra</title>
|
||||
@ -250,18 +250,18 @@ org_html_manager.setup(); // activate after the parameters are set
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#org6e14c98">1. Summmary</a></li>
|
||||
<li><a href="#org73480ff">1. Summmary</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org6e14c98" class="outline-2">
|
||||
<h2 id="org6e14c98"><span class="section-number-2">1</span> Summmary</h2>
|
||||
<div id="outline-container-org73480ff" class="outline-2">
|
||||
<h2 id="org73480ff"><span class="section-number-2">1</span> Summmary</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<p class="author">Author: Anthony Scemama</p>
|
||||
<p class="date">Created: 2021-01-27 Wed 23:44</p>
|
||||
<p class="date">Created: 2021-01-29 Fri 15:35</p>
|
||||
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
194
docs/mo.html
194
docs/mo.html
@ -3,7 +3,7 @@
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2021-01-27 Wed 23:44 -->
|
||||
<!-- 2021-01-30 Sat 19:07 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Molecular orbitals</title>
|
||||
@ -238,6 +238,28 @@ org_html_manager.setup(); // activate after the parameters are set
|
||||
/*]]>*///-->
|
||||
// @license-end
|
||||
</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">
|
||||
@ -250,36 +272,46 @@ org_html_manager.setup(); // activate after the parameters are set
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#orgdaf938b">1. Summmary</a></li>
|
||||
<li><a href="#org9acb3b3">2. Frozen core</a>
|
||||
<li><a href="#org5ae1447">1. Summmary</a></li>
|
||||
<li><a href="#org5d6abfd">2. Frozen core</a>
|
||||
<ul>
|
||||
<li><a href="#org64a252c">2.1. Type</a></li>
|
||||
<li><a href="#org987723c">2.2. Creation</a></li>
|
||||
<li><a href="#orgc89d6d7">2.3. Access</a></li>
|
||||
<li><a href="#org5c73928">2.4. Printers</a></li>
|
||||
<li><a href="#org6013f02">2.1. Type</a></li>
|
||||
<li><a href="#orgc66d8bd">2.2. Creation</a></li>
|
||||
<li><a href="#org7a06aed">2.3. Access</a></li>
|
||||
<li><a href="#org7d4d0a2">2.4. Printers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#org80b59a6">3. Orbital localization</a>
|
||||
<ul>
|
||||
<li><a href="#org3a774bd">3.1. Type</a></li>
|
||||
<li><a href="#org3792219">3.2. Edmiston-Rudenberg</a></li>
|
||||
<li><a href="#org2a12adf">3.3. Boys</a></li>
|
||||
<li><a href="#org7f7571f">3.4. Access</a></li>
|
||||
<li><a href="#orgd0fc6f0">3.5. Printers</a></li>
|
||||
<li><a href="#org93f02d0">3.6. Tests</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgdaf938b" class="outline-2">
|
||||
<h2 id="orgdaf938b"><span class="section-number-2">1</span> Summmary</h2>
|
||||
<div id="outline-container-org5ae1447" class="outline-2">
|
||||
<h2 id="org5ae1447"><span class="section-number-2">1</span> Summmary</h2>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org9acb3b3" class="outline-2">
|
||||
<h2 id="org9acb3b3"><span class="section-number-2">2</span> Frozen core</h2>
|
||||
<div id="outline-container-org5d6abfd" class="outline-2">
|
||||
<h2 id="org5d6abfd"><span class="section-number-2">2</span> Frozen core</h2>
|
||||
<div class="outline-text-2" id="text-2">
|
||||
<p>
|
||||
Defines how the core electrons are frozen, for each atom.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org64a252c" class="outline-3">
|
||||
<h3 id="org64a252c"><span class="section-number-3">2.1</span> Type</h3>
|
||||
<div id="outline-container-org6013f02" class="outline-3">
|
||||
<h3 id="org6013f02"><span class="section-number-3">2.1</span> Type</h3>
|
||||
<div class="outline-text-3" id="text-2-1">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml" id="org92bd127"><span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">kind</span> <span class="org-tuareg-font-lock-operator">=</span>
|
||||
<pre class="src src-ocaml" id="org7e482ab"><span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">kind</span> <span class="org-tuareg-font-lock-operator">=</span>
|
||||
<span class="org-tuareg-font-lock-operator">|</span> <span class="org-tuareg-font-lock-constructor">All_electron</span>
|
||||
<span class="org-tuareg-font-lock-operator">|</span> <span class="org-tuareg-font-lock-constructor">Small</span>
|
||||
<span class="org-tuareg-font-lock-operator">|</span> Large
|
||||
@ -293,8 +325,8 @@ Defines how the core electrons are frozen, for each atom.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org987723c" class="outline-3">
|
||||
<h3 id="org987723c"><span class="section-number-3">2.2</span> Creation</h3>
|
||||
<div id="outline-container-orgc66d8bd" class="outline-3">
|
||||
<h3 id="orgc66d8bd"><span class="section-number-3">2.2</span> Creation</h3>
|
||||
<div class="outline-text-3" id="text-2-2">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">make</span> <span class="org-tuareg-font-lock-operator">:</span> kind <span class="org-tuareg-font-lock-operator">-></span> <span class="org-tuareg-font-lock-module">Particles.Nuclei.</span>t <span class="org-tuareg-font-lock-operator">-></span> t
|
||||
@ -330,7 +362,7 @@ Defines how the core electrons are frozen, for each atom.
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<pre class="example" id="org8539b48">
|
||||
<pre class="example" id="orgd0bea50">
|
||||
let f = Frozen_core.(make Small nuclei) ;;
|
||||
val f : Frozen_core.t = [|0; 2; 2; 0|]
|
||||
|
||||
@ -340,8 +372,8 @@ val f : Frozen_core.t = [|0; 2; 2; 0|]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgc89d6d7" class="outline-3">
|
||||
<h3 id="orgc89d6d7"><span class="section-number-3">2.3</span> Access</h3>
|
||||
<div id="outline-container-org7a06aed" class="outline-3">
|
||||
<h3 id="org7a06aed"><span class="section-number-3">2.3</span> Access</h3>
|
||||
<div class="outline-text-3" id="text-2-3">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">num_elec</span> <span class="org-tuareg-font-lock-operator">:</span> t <span class="org-tuareg-font-lock-operator">-></span> int
|
||||
@ -370,7 +402,7 @@ val f : Frozen_core.t = [|0; 2; 2; 0|]
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<pre class="example" id="org5deb173">
|
||||
<pre class="example" id="org8a415bd">
|
||||
Frozen_core.num_elec f ;;
|
||||
- : int = 4
|
||||
|
||||
@ -380,8 +412,8 @@ Frozen_core.num_mos f ;;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org5c73928" class="outline-3">
|
||||
<h3 id="org5c73928"><span class="section-number-3">2.4</span> Printers</h3>
|
||||
<div id="outline-container-org7d4d0a2" class="outline-3">
|
||||
<h3 id="org7d4d0a2"><span class="section-number-3">2.4</span> Printers</h3>
|
||||
<div class="outline-text-3" id="text-2-4">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">pp</span> <span class="org-tuareg-font-lock-operator">:</span> <span class="org-tuareg-font-lock-module">Format.</span>formatter <span class="org-tuareg-font-lock-operator">-></span> t <span class="org-tuareg-font-lock-operator">-></span> unit
|
||||
@ -390,10 +422,126 @@ Frozen_core.num_mos f ;;
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org80b59a6" class="outline-2">
|
||||
<h2 id="org80b59a6"><span class="section-number-2">3</span> Orbital localization</h2>
|
||||
<div class="outline-text-2" id="text-3">
|
||||
<p>
|
||||
Molecular orbital localization function.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boys:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Edmiston-Rudenberg:
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="outline-container-org3a774bd" class="outline-3">
|
||||
<h3 id="org3a774bd"><span class="section-number-3">3.1</span> Type</h3>
|
||||
<div class="outline-text-3" id="text-3-1">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml" id="org7ba3fe2"><span class="org-tuareg-font-lock-governing">open </span><span class="org-tuareg-font-lock-module">Linear_algebra</span>
|
||||
|
||||
<span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">localization_kind</span> <span class="org-tuareg-font-lock-operator">=</span>
|
||||
<span class="org-tuareg-font-lock-operator">|</span> <span class="org-tuareg-font-lock-constructor">Edmiston</span>
|
||||
<span class="org-tuareg-font-lock-operator">|</span> <span class="org-tuareg-font-lock-constructor">Boys</span>
|
||||
|
||||
<span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">mo</span> <span class="org-tuareg-font-lock-operator">=</span> <span class="org-tuareg-font-lock-module">Mo_dim.</span>t
|
||||
<span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">ao</span> <span class="org-tuareg-font-lock-operator">=</span> <span class="org-tuareg-font-lock-module">Ao.Ao_dim.</span>t
|
||||
<span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">loc</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">localization_data</span>
|
||||
<span class="org-tuareg-font-lock-governing">type</span> <span class="org-type">t</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org3792219" class="outline-3">
|
||||
<h3 id="org3792219"><span class="section-number-3">3.2</span> Edmiston-Rudenberg</h3>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org2a12adf" class="outline-3">
|
||||
<h3 id="org2a12adf"><span class="section-number-3">3.3</span> Boys</h3>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org7f7571f" class="outline-3">
|
||||
<h3 id="org7f7571f"><span class="section-number-3">3.4</span> Access</h3>
|
||||
<div class="outline-text-3" id="text-3-4">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">kind</span> <span class="org-tuareg-font-lock-operator">:</span> t <span class="org-tuareg-font-lock-operator">-></span> localization_kind
|
||||
<span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">simulation</span> <span class="org-tuareg-font-lock-operator">:</span> t <span class="org-tuareg-font-lock-operator">-></span> <span class="org-tuareg-font-lock-module">Simulation.</span>t
|
||||
<span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">selected_mos</span> <span class="org-tuareg-font-lock-operator">:</span> t <span class="org-tuareg-font-lock-operator">-></span> int list
|
||||
|
||||
<span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">kappa</span> <span class="org-tuareg-font-lock-operator">:</span>
|
||||
<span class="org-tuareg-font-lock-label">kind</span><span class="org-tuareg-font-lock-operator">:</span>localization_kind <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-module">Basis.</span>t <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-operator">(</span> ao<span class="org-tuareg-font-lock-operator">,</span>loc<span class="org-tuareg-font-lock-operator">)</span> <span class="org-tuareg-font-lock-module">Matrix.</span>t <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-operator">(</span>loc<span class="org-tuareg-font-lock-operator">,</span>loc<span class="org-tuareg-font-lock-operator">)</span> <span class="org-tuareg-font-lock-module">Matrix.</span>t <span class="org-tuareg-font-lock-operator">*</span> float
|
||||
|
||||
<span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">make</span> <span class="org-tuareg-font-lock-operator">:</span>
|
||||
<span class="org-tuareg-font-lock-label">kind</span><span class="org-tuareg-font-lock-operator">:</span>localization_kind <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-label">?max_iter</span><span class="org-tuareg-font-lock-operator">:</span>int <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-label">?convergence</span><span class="org-tuareg-font-lock-operator">:</span>float <span class="org-tuareg-font-lock-operator">-></span>
|
||||
<span class="org-tuareg-font-lock-module">Basis.</span>t <span class="org-tuareg-font-lock-operator">-></span>
|
||||
int list <span class="org-tuareg-font-lock-operator">-></span>
|
||||
t
|
||||
|
||||
<span class="org-tuareg-font-lock-governing">val</span> <span class="org-function-name">to_basis</span> <span class="org-tuareg-font-lock-operator">:</span> t <span class="org-tuareg-font-lock-operator">-></span> <span class="org-tuareg-font-lock-module">Basis.</span>t
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
||||
|
||||
|
||||
<colgroup>
|
||||
<col class="org-left" />
|
||||
|
||||
<col class="org-left" />
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="org-left"><code>kappa</code></td>
|
||||
<td class="org-left">Returns the \(\kappa\) antisymmetric matrix used for the rotation matrix and the value of the localization function</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="org-left"><code>make</code></td>
|
||||
<td class="org-left">Performs the orbital localization</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgd0fc6f0" class="outline-3">
|
||||
<h3 id="orgd0fc6f0"><span class="section-number-3">3.5</span> Printers</h3>
|
||||
<div class="outline-text-3" id="text-3-5">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-ocaml"><span class="org-comment-delimiter">(*</span>
|
||||
<span class="org-comment"> val pp : Format.formatter -> t -> unit</span>
|
||||
<span class="org-comment"> </span><span class="org-comment-delimiter">*)</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org93f02d0" class="outline-3">
|
||||
<h3 id="org93f02d0"><span class="section-number-3">3.6</span> Tests</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<p class="author">Author: Anthony Scemama</p>
|
||||
<p class="date">Created: 2021-01-27 Wed 23:44</p>
|
||||
<p class="date">Created: 2021-01-30 Sat 19:07</p>
|
||||
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -3,7 +3,7 @@
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2021-01-28 Thu 00:32 -->
|
||||
<!-- 2021-01-30 Sat 19:07 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Top-level</title>
|
||||
@ -250,18 +250,18 @@ org_html_manager.setup(); // activate after the parameters are set
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#org55c0065">1. Summmary</a></li>
|
||||
<li><a href="#org6d8977c">1. Summmary</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org55c0065" class="outline-2">
|
||||
<h2 id="org55c0065"><span class="section-number-2">1</span> Summmary</h2>
|
||||
<div id="outline-container-org6d8977c" class="outline-2">
|
||||
<h2 id="org6d8977c"><span class="section-number-2">1</span> Summmary</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<p class="author">Author: Anthony Scemama</p>
|
||||
<p class="date">Created: 2021-01-28 Thu 00:32</p>
|
||||
<p class="date">Created: 2021-01-30 Sat 19:07</p>
|
||||
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -393,7 +393,7 @@ let qr a =
|
||||
q, r
|
||||
|
||||
|
||||
let exponential_iterative a =
|
||||
let exponential a =
|
||||
assert (dim1 a = dim2 a);
|
||||
let rec loop result accu n =
|
||||
let b = scale (1./.n) a in
|
||||
@ -413,7 +413,7 @@ let exponential_iterative a =
|
||||
loop id id 1.
|
||||
|
||||
|
||||
let exponential a =
|
||||
let exponential_antisymmetric a =
|
||||
|
||||
let n = dim1 a in
|
||||
assert (n = dim2 a);
|
||||
@ -433,8 +433,12 @@ let exponential a =
|
||||
|> amax
|
||||
|> abs_float
|
||||
in
|
||||
assert (test < Constants.epsilon);
|
||||
|
||||
(* If the exponential failed, fall back to the iterative exponential *)
|
||||
if test < 10. *. Constants.epsilon then
|
||||
result
|
||||
else
|
||||
exponential a
|
||||
|
||||
|
||||
let to_file ~filename ?(sym=false) ?(cutoff=0.) t =
|
||||
|
@ -306,8 +306,8 @@ val diagonalize_symm : ('a,'a) t -> ('a,'a) t * 'a Vector.t
|
||||
val exponential : ('a,'a) t -> ('a,'a) t
|
||||
(** Computes the exponential of a square matrix. *)
|
||||
|
||||
val exponential_iterative : ('a,'a) t -> ('a,'a) t
|
||||
(** Computes the exponential of a square matrix with an iteratve algorithm. *)
|
||||
val exponential_antisymmetric: ('a,'a) t -> ('a,'a) t
|
||||
(** Computes the exponential of an antisymmetric square matrix. *)
|
||||
|
||||
val xt_o_x : o:('a,'a) t -> x:('a,'b) t -> ('b,'b) t
|
||||
(** Computes {% $\mathbf{X^\dag\, O\, X}$ %} *)
|
||||
|
@ -77,7 +77,7 @@ let n_iterations t =
|
||||
|
||||
|
||||
let last_iteration t =
|
||||
Util.of_some @@ Lazy.force (t.data.(n_iterations t - 1))
|
||||
Util.of_some @@ Lazy.force t.data.(n_iterations t - 1)
|
||||
|
||||
let eigenvectors t =
|
||||
let data = last_iteration t in
|
||||
|
331
mo/lib/localization.ml
Normal file
331
mo/lib/localization.ml
Normal file
@ -0,0 +1,331 @@
|
||||
(* [[file:~/QCaml/mo/localization.org::*Type][Type:3]] *)
|
||||
open Linear_algebra
|
||||
|
||||
type localization_kind =
|
||||
| Edmiston
|
||||
| Boys
|
||||
|
||||
type mo = Mo_dim.t
|
||||
type ao = Ao.Ao_dim.t
|
||||
type loc
|
||||
|
||||
type localization_data =
|
||||
{
|
||||
coefficients : (ao, loc) Matrix.t ;
|
||||
kappa : (loc, loc) Matrix.t ;
|
||||
scaling : float ;
|
||||
loc_value : float ;
|
||||
iteration : int ;
|
||||
}
|
||||
|
||||
type t =
|
||||
{
|
||||
kind : localization_kind ;
|
||||
mo_basis : Basis.t ;
|
||||
data : localization_data option lazy_t array ;
|
||||
selected_mos : int list ;
|
||||
}
|
||||
|
||||
open Common
|
||||
(* Type:3 ends here *)
|
||||
|
||||
(* Edmiston-Rudenberg *)
|
||||
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Edmiston-Rudenberg][Edmiston-Rudenberg:1]] *)
|
||||
let kappa_edmiston in_basis m_C =
|
||||
let ao_basis =
|
||||
Basis.simulation in_basis
|
||||
|> Simulation.ao_basis
|
||||
in
|
||||
|
||||
let ee_ints = Ao.Basis.ee_ints ao_basis in
|
||||
let n_ao = Ao.Basis.size ao_basis in
|
||||
|
||||
let n_mo = Matrix.dim2 m_C in
|
||||
|
||||
(* Temp arrays for integral transformation *)
|
||||
let m_pqr =
|
||||
Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)
|
||||
in
|
||||
let m_qr_i = Matrix.create (n_ao*n_ao) n_mo in
|
||||
let m_ri_j = Matrix.create (n_ao*n_mo) n_mo in
|
||||
let m_ij_k = Matrix.create (n_mo*n_mo) n_mo in
|
||||
|
||||
|
||||
let m_a12 = Bigarray.(Array2.create Float64 fortran_layout n_mo n_mo) in
|
||||
let m_b12 = Bigarray.(Array2.create Float64 fortran_layout n_mo n_mo) in
|
||||
Bigarray.Array2.fill m_b12 0.;
|
||||
Bigarray.Array2.fill m_a12 0.;
|
||||
let v_d =
|
||||
Vector.init n_mo (fun _ -> 0.)
|
||||
|> Vector.to_bigarray_inplace
|
||||
in
|
||||
|
||||
Array.iter (fun s ->
|
||||
|
||||
Array.iter (fun r ->
|
||||
Array.iter (fun q ->
|
||||
Array.iter (fun p ->
|
||||
m_pqr.{p,q,r} <- Four_idx_storage.get_phys ee_ints p q r s
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
let m_p_qr =
|
||||
Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]
|
||||
|> Bigarray.array2_of_genarray
|
||||
|> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (qr,i) = <i r|q s> = \sum_p <p r | q s> C_{pi} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_qr_i m_p_qr m_C;
|
||||
|
||||
let m_q_ri =
|
||||
let x = Matrix.to_bigarray_inplace m_qr_i |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape_2 x n_ao (n_ao*n_mo) |> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (ri,j) = <i r | j s> = \sum_q <i r | q s> C_{qj} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_ri_j m_q_ri m_C;
|
||||
|
||||
let m_r_ij =
|
||||
let x = Matrix.to_bigarray_inplace m_ri_j |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape_2 x n_ao (n_mo*n_mo) |> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (ij,k) = <i k | j s> = \sum_r <i r | j s> C_{rk} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_ij_k m_r_ij m_C;
|
||||
|
||||
let m_ijk =
|
||||
let x = Matrix.to_bigarray_inplace m_ij_k |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape x [| n_mo ; n_mo ; n_mo |]
|
||||
|> Bigarray.array3_of_genarray
|
||||
in
|
||||
|
||||
let m_Cx = Matrix.to_bigarray_inplace m_C in
|
||||
Array.iter (fun j ->
|
||||
Array.iter (fun i ->
|
||||
m_b12.{i,j} <- m_b12.{i,j} +. m_Cx.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});
|
||||
m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_Cx.{s,j} -.
|
||||
0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_Cx.{s,i} +.
|
||||
(m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_Cx.{s,j})
|
||||
) (Util.array_range 1 n_mo);
|
||||
v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_Cx.{s,j}
|
||||
) (Util.array_range 1 n_mo)
|
||||
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
let f i j =
|
||||
if i=j then
|
||||
0.
|
||||
else
|
||||
begin
|
||||
let x = 1./. sqrt (m_b12.{i,j} *. m_b12.{i,j} +. m_a12.{i,j} *. m_a12.{i,j} ) in
|
||||
if asin (m_b12.{i,j} /. x) > 0. then
|
||||
0.25 *. acos( -. m_a12.{i,j} *. x)
|
||||
else
|
||||
-. 0.25 *. acos( -. m_a12.{i,j} *. x )
|
||||
end
|
||||
in
|
||||
(
|
||||
Matrix.init_cols n_mo n_mo ( fun i j -> if i<=j then f i j else -. (f j i) ),
|
||||
Vector.sum (Vector.of_bigarray_inplace v_d)
|
||||
)
|
||||
(* Edmiston-Rudenberg:1 ends here *)
|
||||
|
||||
(* Boys *)
|
||||
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Boys][Boys:1]] *)
|
||||
let kappa_boys in_basis =
|
||||
let ao_basis =
|
||||
Basis.simulation in_basis
|
||||
|> Simulation.ao_basis
|
||||
in
|
||||
let multipole = Ao.Basis.multipole ao_basis in
|
||||
fun m_C ->
|
||||
let n_mo = Matrix.dim2 m_C in
|
||||
|
||||
let phi_x_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "x") in
|
||||
let phi_y_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "y") in
|
||||
let phi_z_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "z") in
|
||||
|
||||
let m_b12 =
|
||||
let g x i j =
|
||||
let x_ii = x%:(i,i) in
|
||||
let x_jj = x%:(j,j) in
|
||||
let x_ij = x%:(i,j) in
|
||||
(x_ii -. x_jj) *. x_ij
|
||||
in
|
||||
Matrix.init_cols n_mo n_mo (fun i j ->
|
||||
let x =
|
||||
(g phi_x_phi i j) +. (g phi_y_phi i j) +. (g phi_z_phi i j)
|
||||
in
|
||||
if (abs_float x > 1.e-15) then x else 0.
|
||||
)
|
||||
in
|
||||
|
||||
let m_a12 =
|
||||
let g x i j =
|
||||
let x_ii = x%:(i,i) in
|
||||
let x_jj = x%:(j,j) in
|
||||
let x_ij = x%:(i,j) in
|
||||
let y = x_ii -. x_jj in
|
||||
(x_ij *. x_ij) -. 0.25 *. y *. y
|
||||
in
|
||||
Matrix.init_cols n_mo n_mo (fun i j ->
|
||||
let x =
|
||||
(g phi_x_phi i j) +. (g phi_y_phi i j) +. (g phi_z_phi i j)
|
||||
in
|
||||
if (abs_float x > 1.e-15) then x else 0.
|
||||
)
|
||||
in
|
||||
|
||||
let f i j =
|
||||
let pi = Constants.pi in
|
||||
if i=j then
|
||||
0.
|
||||
else
|
||||
let x = atan2 (m_b12%:(i,j)) (m_a12%:(i,j)) in
|
||||
if x >= 0. then
|
||||
0.25 *. (pi -. x)
|
||||
else
|
||||
-. 0.25 *. ( pi +. x)
|
||||
in
|
||||
(
|
||||
Matrix.init_cols n_mo n_mo ( fun i j -> if i>j then f i j else -. (f j i) ),
|
||||
let r2 x y z = x*.x +. y*.y +. z*.z in
|
||||
Vector.init n_mo ( fun i ->
|
||||
r2 (phi_x_phi%:(i,i)) (phi_y_phi%:(i,i)) (phi_z_phi%:(i,i)))
|
||||
|> Vector.sum
|
||||
)
|
||||
(* Boys:1 ends here *)
|
||||
|
||||
|
||||
|
||||
(* | ~kappa~ | Returns the $\kappa$ antisymmetric matrix used for the rotation matrix and the value of the localization function |
|
||||
* | ~make~ | Performs the orbital localization | *)
|
||||
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Access][Access:2]] *)
|
||||
let kind t = t.kind
|
||||
let simulation t = Basis.simulation t.mo_basis
|
||||
let selected_mos t = t.selected_mos
|
||||
|
||||
let kappa ~kind =
|
||||
match kind with
|
||||
| Edmiston -> kappa_edmiston
|
||||
| Boys -> kappa_boys
|
||||
|
||||
|
||||
let n_iterations t =
|
||||
Array.fold_left (fun accu x ->
|
||||
match Lazy.force x with
|
||||
| Some _ -> accu + 1
|
||||
| None -> accu
|
||||
) 0 t.data
|
||||
|
||||
let last_iteration t =
|
||||
Util.of_some @@ Lazy.force t.data.(n_iterations t - 1)
|
||||
|
||||
(*
|
||||
let ao_basis t = Simulation.ao_basis (simulation t)
|
||||
*)
|
||||
|
||||
|
||||
|
||||
let make ~kind ?(max_iter=500) ?(convergence=1.e-8) mo_basis selected_mos =
|
||||
|
||||
let kappa_loc = kappa ~kind mo_basis in
|
||||
|
||||
let mo_array = Matrix.to_col_vecs (Basis.mo_coef mo_basis) in
|
||||
let mos_vec_list = List.map (fun i -> mo_array.(i-1)) selected_mos in
|
||||
let x: (ao,loc) Matrix.t =
|
||||
Matrix.of_col_vecs_list mos_vec_list
|
||||
in
|
||||
|
||||
let next_coef kappa =
|
||||
let r = Matrix.exponential_antisymmetric kappa in
|
||||
let m_C = Matrix.gemm_nt x r in
|
||||
m_C
|
||||
in
|
||||
|
||||
let data_initial =
|
||||
let iteration = 0
|
||||
and kappa, loc_value = kappa_loc x
|
||||
and scaling = 1.0
|
||||
in
|
||||
let coefficients = next_coef kappa in
|
||||
{ coefficients ; kappa ; scaling ; loc_value ; iteration }
|
||||
in
|
||||
|
||||
let iteration data =
|
||||
let x = data.coefficients in
|
||||
let iteration = data.iteration + 1
|
||||
and kappa, loc_value = kappa_loc x
|
||||
and scaling = data.scaling
|
||||
in
|
||||
let coefficients = next_coef kappa in
|
||||
Printf.printf "%4d %20f\n" iteration loc_value ;
|
||||
{ coefficients ; kappa ; scaling ; loc_value ; iteration }
|
||||
in
|
||||
|
||||
let array_data =
|
||||
|
||||
let storage =
|
||||
Array.make max_iter None
|
||||
in
|
||||
|
||||
let rec loop = function
|
||||
| 0 -> Some (iteration data_initial)
|
||||
| n -> begin
|
||||
match storage.(n) with
|
||||
| Some result -> Some result
|
||||
| None -> begin
|
||||
let data = loop (n-1) in
|
||||
match data with
|
||||
| None -> None
|
||||
| Some data -> begin
|
||||
(* Check convergence *)
|
||||
let converged =
|
||||
abs_float data.loc_value < convergence
|
||||
in
|
||||
if converged then
|
||||
None
|
||||
else
|
||||
begin
|
||||
storage.(n-1) <- Some data ;
|
||||
storage.(n) <- Some (iteration data);
|
||||
storage.(n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
in
|
||||
Array.init max_iter (fun i -> lazy (loop i))
|
||||
in
|
||||
{ kind ; mo_basis ; data = array_data ; selected_mos }
|
||||
|
||||
|
||||
|
||||
let to_basis t =
|
||||
let mo_basis = t.mo_basis in
|
||||
let simulation = Basis.simulation mo_basis in
|
||||
let mo_occupation = Basis.mo_occupation mo_basis in
|
||||
|
||||
let data = last_iteration t in
|
||||
|
||||
let mo_coef_array = Matrix.to_col_vecs (Basis.mo_coef mo_basis) in
|
||||
let new_mos =
|
||||
Matrix.to_col_vecs data.coefficients
|
||||
in
|
||||
selected_mos t
|
||||
|> List.iteri (fun i j -> mo_coef_array.(j) <- new_mos.(i)) ;
|
||||
let mo_coef = Matrix.of_col_vecs mo_coef_array in
|
||||
Basis.make ~simulation ~mo_type:(Localized "Boys") ~mo_occupation ~mo_coef ()
|
||||
(* Access:2 ends here *)
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Printers][Printers:2]] *)
|
||||
|
||||
(* Printers:2 ends here *)
|
54
mo/lib/localization.mli
Normal file
54
mo/lib/localization.mli
Normal file
@ -0,0 +1,54 @@
|
||||
(* Type
|
||||
*
|
||||
* #+NAME: types *)
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::types][types]] *)
|
||||
open Linear_algebra
|
||||
|
||||
type localization_kind =
|
||||
| Edmiston
|
||||
| Boys
|
||||
|
||||
type mo = Mo_dim.t
|
||||
type ao = Ao.Ao_dim.t
|
||||
type loc
|
||||
(* types ends here *)
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Type][Type:2]] *)
|
||||
type localization_data
|
||||
type t
|
||||
(* Type:2 ends here *)
|
||||
|
||||
(* Access *)
|
||||
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Access][Access:1]] *)
|
||||
val kind : t -> localization_kind
|
||||
val simulation : t -> Simulation.t
|
||||
val selected_mos : t -> int list
|
||||
|
||||
val kappa :
|
||||
kind:localization_kind ->
|
||||
Basis.t ->
|
||||
( ao,loc) Matrix.t ->
|
||||
(loc,loc) Matrix.t * float
|
||||
|
||||
val make :
|
||||
kind:localization_kind ->
|
||||
?max_iter:int ->
|
||||
?convergence:float ->
|
||||
Basis.t ->
|
||||
int list ->
|
||||
t
|
||||
|
||||
val to_basis : t -> Basis.t
|
||||
(* Access:1 ends here *)
|
||||
|
||||
(* Printers *)
|
||||
|
||||
|
||||
(* [[file:~/QCaml/mo/localization.org::*Printers][Printers:1]] *)
|
||||
(*
|
||||
val pp : Format.formatter -> t -> unit
|
||||
*)
|
||||
(* Printers:1 ends here *)
|
477
mo/localization.org
Normal file
477
mo/localization.org
Normal file
@ -0,0 +1,477 @@
|
||||
#+begin_src elisp tangle: no :results none :exports none
|
||||
(setq pwd (file-name-directory buffer-file-name))
|
||||
(setq name (file-name-nondirectory (substring buffer-file-name 0 -4)))
|
||||
(setq lib (concat pwd "lib/"))
|
||||
(setq testdir (concat pwd "test/"))
|
||||
(setq mli (concat lib name ".mli"))
|
||||
(setq ml (concat lib name ".ml"))
|
||||
(setq test-ml (concat testdir name ".ml"))
|
||||
(org-babel-tangle)
|
||||
#+end_src
|
||||
|
||||
* Orbital localization
|
||||
:PROPERTIES:
|
||||
:header-args: :noweb yes :comments both
|
||||
:END:
|
||||
|
||||
Molecular orbital localization function.
|
||||
|
||||
Boys:
|
||||
|
||||
Edmiston-Rudenberg:
|
||||
|
||||
|
||||
** Type
|
||||
|
||||
#+NAME: types
|
||||
#+begin_src ocaml :tangle (eval mli)
|
||||
open Linear_algebra
|
||||
|
||||
type localization_kind =
|
||||
| Edmiston
|
||||
| Boys
|
||||
|
||||
type mo = Mo_dim.t
|
||||
type ao = Ao.Ao_dim.t
|
||||
type loc
|
||||
#+end_src
|
||||
|
||||
#+begin_src ocaml :tangle (eval mli)
|
||||
type localization_data
|
||||
type t
|
||||
#+end_src
|
||||
|
||||
#+begin_src ocaml :tangle (eval ml) :exports none
|
||||
<<types>>
|
||||
|
||||
type localization_data =
|
||||
{
|
||||
coefficients : (ao, loc) Matrix.t ;
|
||||
kappa : (loc, loc) Matrix.t ;
|
||||
scaling : float ;
|
||||
loc_value : float ;
|
||||
iteration : int ;
|
||||
}
|
||||
|
||||
type t =
|
||||
{
|
||||
kind : localization_kind ;
|
||||
mo_basis : Basis.t ;
|
||||
data : localization_data option lazy_t array ;
|
||||
selected_mos : int list ;
|
||||
}
|
||||
|
||||
open Common
|
||||
#+end_src
|
||||
|
||||
** Edmiston-Rudenberg
|
||||
|
||||
#+begin_src ocaml :tangle (eval ml) :exports none
|
||||
let kappa_edmiston in_basis m_C =
|
||||
let ao_basis =
|
||||
Basis.simulation in_basis
|
||||
|> Simulation.ao_basis
|
||||
in
|
||||
|
||||
let ee_ints = Ao.Basis.ee_ints ao_basis in
|
||||
let n_ao = Ao.Basis.size ao_basis in
|
||||
|
||||
let n_mo = Matrix.dim2 m_C in
|
||||
|
||||
(* Temp arrays for integral transformation *)
|
||||
let m_pqr =
|
||||
Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)
|
||||
in
|
||||
let m_qr_i = Matrix.create (n_ao*n_ao) n_mo in
|
||||
let m_ri_j = Matrix.create (n_ao*n_mo) n_mo in
|
||||
let m_ij_k = Matrix.create (n_mo*n_mo) n_mo in
|
||||
|
||||
|
||||
let m_a12 = Bigarray.(Array2.create Float64 fortran_layout n_mo n_mo) in
|
||||
let m_b12 = Bigarray.(Array2.create Float64 fortran_layout n_mo n_mo) in
|
||||
Bigarray.Array2.fill m_b12 0.;
|
||||
Bigarray.Array2.fill m_a12 0.;
|
||||
let v_d =
|
||||
Vector.init n_mo (fun _ -> 0.)
|
||||
|> Vector.to_bigarray_inplace
|
||||
in
|
||||
|
||||
Array.iter (fun s ->
|
||||
|
||||
Array.iter (fun r ->
|
||||
Array.iter (fun q ->
|
||||
Array.iter (fun p ->
|
||||
m_pqr.{p,q,r} <- Four_idx_storage.get_phys ee_ints p q r s
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
let m_p_qr =
|
||||
Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]
|
||||
|> Bigarray.array2_of_genarray
|
||||
|> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (qr,i) = <i r|q s> = \sum_p <p r | q s> C_{pi} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_qr_i m_p_qr m_C;
|
||||
|
||||
let m_q_ri =
|
||||
let x = Matrix.to_bigarray_inplace m_qr_i |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape_2 x n_ao (n_ao*n_mo) |> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (ri,j) = <i r | j s> = \sum_q <i r | q s> C_{qj} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_ri_j m_q_ri m_C;
|
||||
|
||||
let m_r_ij =
|
||||
let x = Matrix.to_bigarray_inplace m_ri_j |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape_2 x n_ao (n_mo*n_mo) |> Matrix.of_bigarray_inplace
|
||||
in
|
||||
|
||||
(* (ij,k) = <i k | j s> = \sum_r <i r | j s> C_{rk} *)
|
||||
Matrix.gemm_tn_inplace ~c:m_ij_k m_r_ij m_C;
|
||||
|
||||
let m_ijk =
|
||||
let x = Matrix.to_bigarray_inplace m_ij_k |> Bigarray.genarray_of_array2 in
|
||||
Bigarray.reshape x [| n_mo ; n_mo ; n_mo |]
|
||||
|> Bigarray.array3_of_genarray
|
||||
in
|
||||
|
||||
let m_Cx = Matrix.to_bigarray_inplace m_C in
|
||||
Array.iter (fun j ->
|
||||
Array.iter (fun i ->
|
||||
m_b12.{i,j} <- m_b12.{i,j} +. m_Cx.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});
|
||||
m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_Cx.{s,j} -.
|
||||
0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_Cx.{s,i} +.
|
||||
(m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_Cx.{s,j})
|
||||
) (Util.array_range 1 n_mo);
|
||||
v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_Cx.{s,j}
|
||||
) (Util.array_range 1 n_mo)
|
||||
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
let f i j =
|
||||
if i=j then
|
||||
0.
|
||||
else
|
||||
begin
|
||||
let x = 1./. sqrt (m_b12.{i,j} *. m_b12.{i,j} +. m_a12.{i,j} *. m_a12.{i,j} ) in
|
||||
if asin (m_b12.{i,j} /. x) > 0. then
|
||||
0.25 *. acos( -. m_a12.{i,j} *. x)
|
||||
else
|
||||
-. 0.25 *. acos( -. m_a12.{i,j} *. x )
|
||||
end
|
||||
in
|
||||
(
|
||||
Matrix.init_cols n_mo n_mo ( fun i j -> if i<=j then f i j else -. (f j i) ),
|
||||
Vector.sum (Vector.of_bigarray_inplace v_d)
|
||||
)
|
||||
|
||||
|
||||
|
||||
#+end_src
|
||||
|
||||
** Boys
|
||||
|
||||
#+begin_src ocaml :tangle (eval ml) :exports none
|
||||
let kappa_boys in_basis =
|
||||
let ao_basis =
|
||||
Basis.simulation in_basis
|
||||
|> Simulation.ao_basis
|
||||
in
|
||||
let multipole = Ao.Basis.multipole ao_basis in
|
||||
fun m_C ->
|
||||
let n_mo = Matrix.dim2 m_C in
|
||||
|
||||
let phi_x_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "x") in
|
||||
let phi_y_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "y") in
|
||||
let phi_z_phi = Matrix.xt_o_x ~x:m_C ~o:(multipole "z") in
|
||||
|
||||
let m_b12 =
|
||||
let g x i j =
|
||||
let x_ii = x%:(i,i) in
|
||||
let x_jj = x%:(j,j) in
|
||||
let x_ij = x%:(i,j) in
|
||||
(x_ii -. x_jj) *. x_ij
|
||||
in
|
||||
Matrix.init_cols n_mo n_mo (fun i j ->
|
||||
let x =
|
||||
(g phi_x_phi i j) +. (g phi_y_phi i j) +. (g phi_z_phi i j)
|
||||
in
|
||||
if (abs_float x > 1.e-15) then x else 0.
|
||||
)
|
||||
in
|
||||
|
||||
let m_a12 =
|
||||
let g x i j =
|
||||
let x_ii = x%:(i,i) in
|
||||
let x_jj = x%:(j,j) in
|
||||
let x_ij = x%:(i,j) in
|
||||
let y = x_ii -. x_jj in
|
||||
(x_ij *. x_ij) -. 0.25 *. y *. y
|
||||
in
|
||||
Matrix.init_cols n_mo n_mo (fun i j ->
|
||||
let x =
|
||||
(g phi_x_phi i j) +. (g phi_y_phi i j) +. (g phi_z_phi i j)
|
||||
in
|
||||
if (abs_float x > 1.e-15) then x else 0.
|
||||
)
|
||||
in
|
||||
|
||||
let f i j =
|
||||
let pi = Constants.pi in
|
||||
if i=j then
|
||||
0.
|
||||
else
|
||||
let x = atan2 (m_b12%:(i,j)) (m_a12%:(i,j)) in
|
||||
if x >= 0. then
|
||||
0.25 *. (pi -. x)
|
||||
else
|
||||
-. 0.25 *. ( pi +. x)
|
||||
in
|
||||
(
|
||||
Matrix.init_cols n_mo n_mo ( fun i j -> if i>j then f i j else -. (f j i) ),
|
||||
let r2 x y z = x*.x +. y*.y +. z*.z in
|
||||
Vector.init n_mo ( fun i ->
|
||||
r2 (phi_x_phi%:(i,i)) (phi_y_phi%:(i,i)) (phi_z_phi%:(i,i)))
|
||||
|> Vector.sum
|
||||
)
|
||||
|
||||
#+end_src
|
||||
|
||||
|
||||
** Access
|
||||
|
||||
#+begin_src ocaml :tangle (eval mli)
|
||||
val kind : t -> localization_kind
|
||||
val simulation : t -> Simulation.t
|
||||
val selected_mos : t -> int list
|
||||
|
||||
val kappa :
|
||||
kind:localization_kind ->
|
||||
Basis.t ->
|
||||
( ao,loc) Matrix.t ->
|
||||
(loc,loc) Matrix.t * float
|
||||
|
||||
val make :
|
||||
kind:localization_kind ->
|
||||
?max_iter:int ->
|
||||
?convergence:float ->
|
||||
Basis.t ->
|
||||
int list ->
|
||||
t
|
||||
|
||||
val to_basis : t -> Basis.t
|
||||
|
||||
#+end_src
|
||||
|
||||
| ~kappa~ | Returns the $\kappa$ antisymmetric matrix used for the rotation matrix and the value of the localization function |
|
||||
| ~make~ | Performs the orbital localization |
|
||||
|
||||
#+begin_src ocaml :tangle (eval ml) :exports none
|
||||
let kind t = t.kind
|
||||
let simulation t = Basis.simulation t.mo_basis
|
||||
let selected_mos t = t.selected_mos
|
||||
|
||||
let kappa ~kind =
|
||||
match kind with
|
||||
| Edmiston -> kappa_edmiston
|
||||
| Boys -> kappa_boys
|
||||
|
||||
|
||||
let n_iterations t =
|
||||
Array.fold_left (fun accu x ->
|
||||
match Lazy.force x with
|
||||
| Some _ -> accu + 1
|
||||
| None -> accu
|
||||
) 0 t.data
|
||||
|
||||
let last_iteration t =
|
||||
Util.of_some @@ Lazy.force t.data.(n_iterations t - 1)
|
||||
|
||||
(*
|
||||
let ao_basis t = Simulation.ao_basis (simulation t)
|
||||
*)
|
||||
|
||||
|
||||
|
||||
let make ~kind ?(max_iter=500) ?(convergence=1.e-8) mo_basis selected_mos =
|
||||
|
||||
let kappa_loc = kappa ~kind mo_basis in
|
||||
|
||||
let mo_array = Matrix.to_col_vecs (Basis.mo_coef mo_basis) in
|
||||
let mos_vec_list = List.map (fun i -> mo_array.(i-1)) selected_mos in
|
||||
let x: (ao,loc) Matrix.t =
|
||||
Matrix.of_col_vecs_list mos_vec_list
|
||||
in
|
||||
|
||||
let next_coef kappa =
|
||||
let r = Matrix.exponential_antisymmetric kappa in
|
||||
let m_C = Matrix.gemm_nt x r in
|
||||
m_C
|
||||
in
|
||||
|
||||
let data_initial =
|
||||
let iteration = 0
|
||||
and kappa, loc_value = kappa_loc x
|
||||
and scaling = 1.0
|
||||
in
|
||||
let coefficients = next_coef kappa in
|
||||
{ coefficients ; kappa ; scaling ; loc_value ; iteration }
|
||||
in
|
||||
|
||||
let iteration data =
|
||||
let x = data.coefficients in
|
||||
let iteration = data.iteration + 1
|
||||
and kappa, loc_value = kappa_loc x
|
||||
and scaling = data.scaling
|
||||
in
|
||||
let coefficients = next_coef kappa in
|
||||
Printf.printf "%4d %20f\n" iteration loc_value ;
|
||||
{ coefficients ; kappa ; scaling ; loc_value ; iteration }
|
||||
in
|
||||
|
||||
let array_data =
|
||||
|
||||
let storage =
|
||||
Array.make max_iter None
|
||||
in
|
||||
|
||||
let rec loop = function
|
||||
| 0 -> Some (iteration data_initial)
|
||||
| n -> begin
|
||||
match storage.(n) with
|
||||
| Some result -> Some result
|
||||
| None -> begin
|
||||
let data = loop (n-1) in
|
||||
match data with
|
||||
| None -> None
|
||||
| Some data -> begin
|
||||
(* Check convergence *)
|
||||
let converged =
|
||||
abs_float data.loc_value < convergence
|
||||
in
|
||||
if converged then
|
||||
None
|
||||
else
|
||||
begin
|
||||
storage.(n-1) <- Some data ;
|
||||
storage.(n) <- Some (iteration data);
|
||||
storage.(n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
in
|
||||
Array.init max_iter (fun i -> lazy (loop i))
|
||||
in
|
||||
{ kind ; mo_basis ; data = array_data ; selected_mos }
|
||||
|
||||
|
||||
|
||||
let to_basis t =
|
||||
let mo_basis = t.mo_basis in
|
||||
let simulation = Basis.simulation mo_basis in
|
||||
let mo_occupation = Basis.mo_occupation mo_basis in
|
||||
|
||||
let data = last_iteration t in
|
||||
|
||||
let mo_coef_array = Matrix.to_col_vecs (Basis.mo_coef mo_basis) in
|
||||
let new_mos =
|
||||
Matrix.to_col_vecs data.coefficients
|
||||
in
|
||||
selected_mos t
|
||||
|> List.iteri (fun i j -> mo_coef_array.(j) <- new_mos.(i)) ;
|
||||
let mo_coef = Matrix.of_col_vecs mo_coef_array in
|
||||
Basis.make ~simulation ~mo_type:(Localized "Boys") ~mo_occupation ~mo_coef ()
|
||||
|
||||
#+end_src
|
||||
|
||||
** Printers
|
||||
|
||||
#+begin_src ocaml :tangle (eval mli)
|
||||
(*
|
||||
val pp : Format.formatter -> t -> unit
|
||||
*)
|
||||
#+end_src
|
||||
|
||||
#+begin_src ocaml :tangle (eval ml) :exports none
|
||||
|
||||
#+end_src
|
||||
|
||||
** Tests
|
||||
|
||||
#+begin_src ocaml :tangle (eval test-ml) :exports none
|
||||
|
||||
let test_localization =
|
||||
|
||||
let nuclei =
|
||||
Particles.Nuclei.of_xyz_string
|
||||
" 10
|
||||
Hydrogen chain, d=1.8 Angstrom
|
||||
H -4.286335 0.000000 0.000000
|
||||
H -3.333816 0.000000 0.000000
|
||||
H -2.381297 0.000000 0.000000
|
||||
H -1.428778 0.000000 0.000000
|
||||
H -0.476259 0.000000 0.000000
|
||||
H 0.476259 0.000000 0.000000
|
||||
H 1.428778 0.000000 0.000000
|
||||
H 2.381297 0.000000 0.000000
|
||||
H 3.333816 0.000000 0.000000
|
||||
H 4.286335 0.000000 0.000000
|
||||
" in
|
||||
|
||||
let basis_file = "/home/scemama/qp2/data/basis/sto-6g" in
|
||||
|
||||
let ao_basis =
|
||||
Ao.Basis.of_nuclei_and_basis_filename ~nuclei basis_file
|
||||
in
|
||||
|
||||
|
||||
let charge = 0 in
|
||||
|
||||
let multiplicity = 1 in
|
||||
|
||||
let simulation =
|
||||
Simulation.make ~charge ~multiplicity ~nuclei ao_basis
|
||||
in
|
||||
|
||||
let hf =
|
||||
Mo.Hartree_fock.make ~guess:`Hcore simulation
|
||||
in
|
||||
|
||||
let mo_basis =
|
||||
Mo.Basis.of_hartree_fock hf
|
||||
in
|
||||
|
||||
let localized_mo_basis =
|
||||
Mo.Localization.make
|
||||
~kind:Mo.Localization.Boys
|
||||
mo_basis
|
||||
[4;5;6;7;8]
|
||||
|> Mo.Localization.to_basis
|
||||
in
|
||||
|
||||
Format.printf "%a" (Mo.Basis.pp ~start:1 ~finish:10) localized_mo_basis
|
||||
|
||||
|
||||
(*
|
||||
open Common
|
||||
open Alcotest
|
||||
let wd = Qcaml.root ^ Filename.dir_sep ^ "test" in
|
||||
|
||||
let test_xyz molecule length repulsion charge core =
|
||||
let xyz = Nuclei.of_xyz_file (wd^Filename.dir_sep^molecule^".xyz") in
|
||||
check int "length" length (Array.length xyz);
|
||||
check (float 1.e-4) "repulsion" repulsion (Nuclei.repulsion xyz);
|
||||
check int "charge" charge (Charge.to_int @@ Nuclei.charge xyz);
|
||||
check int "small_core" core (Nuclei.small_core xyz);
|
||||
()
|
||||
|
||||
let tests = [
|
||||
"caffeine", `Quick, (fun () -> test_xyz "caffeine" 24 917.0684 102 28);
|
||||
"water", `Quick, (fun () -> test_xyz "water" 3 9.19497 10 2);
|
||||
]
|
||||
,*)
|
||||
|
||||
#+end_src
|
@ -15,6 +15,7 @@ let printers =
|
||||
"Gaussian.Atomic_shell_pair.pp" ;
|
||||
"Gaussian.Atomic_shell_pair_couple.pp" ;
|
||||
"Mo.Frozen_core.pp" ;
|
||||
"Mo.Localization.pp" ;
|
||||
"Particles.Electrons.pp" ;
|
||||
"Particles.Element.pp" ;
|
||||
"Particles.Nuclei.pp" ;
|
||||
|
Loading…
Reference in New Issue
Block a user