Update html

This commit is contained in:
Sylvain Tricot 2025-07-21 17:20:03 +02:00
parent f1af473b10
commit a7c5876bf4
8 changed files with 362 additions and 9 deletions

View File

@ -355,7 +355,7 @@ document.write(`
<article class="bd-article">
<section class="tex2jax_ignore mathjax_ignore" id="activity-9-comparing-simulation-and-experiment-with-r-factors">
<h1>Activity 9: Comparing simulation and experiment with R-factors<a class="headerlink" href="#activity-9-comparing-simulation-and-experiment-with-r-factors" title="Link to this heading">#</a></h1>
<span id="rfactor"></span><h1>Activity 9: Comparing simulation and experiment with R-factors<a class="headerlink" href="#activity-9-comparing-simulation-and-experiment-with-r-factors" title="Link to this heading">#</a></h1>
<p>In order to extract precise crystallographic information from electronic spectroscopy, we need to compare MsSpec calculations with experimental results and adjust the modelling parameters to simulate the experiment as accurately as possible.</p>
<p><em>R-factors</em> (reliability factors) are commonly used for this task. In the following example, we will see how MsSpec can extract the adsorption geometry of a molecule.</p>
<section id="the-unusual-tilt-of-co-molecule-on-fe-001">

View File

@ -317,7 +317,9 @@ document.write(`
</button>
`);
</script>
<button class="sidebar-toggle secondary-toggle btn btn-sm" title="Toggle secondary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="fa-solid fa-list"></span>
</button>
</div></div>
</div>
@ -333,6 +335,15 @@ document.write(`
<div id="print-main-content">
<div id="jb-print-toc">
<div>
<h2> Contents </h2>
</div>
<nav aria-label="Page">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#matrix-inversion-parallelization">Matrix inversion parallelization</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#process-based-parallelism">Process-based parallelism</a></li>
</ul>
</nav>
</div>
</div>
</div>
@ -344,6 +355,103 @@ document.write(`
<section class="tex2jax_ignore mathjax_ignore" id="activity-10-parallelization-and-multi-processing-in-msspec">
<h1>Activity 10: Parallelization and multi-processing in MsSpec<a class="headerlink" href="#activity-10-parallelization-and-multi-processing-in-msspec" title="Link to this heading">#</a></h1>
<p>As you can see from the previous examples, a complete simulation may require several multiple scattering calculations, for instance to calculate the total intensity of a substrate or to optimize the geometry of a system. As the calculations are often time consuming, it can be useful to distribute these tasks over several processors to make the most of hardware resources.
Although MsSpec is not fully parallelized, the code does offer a number of features, which we will explore here.</p>
<section id="matrix-inversion-parallelization">
<h2>Matrix inversion parallelization<a class="headerlink" href="#matrix-inversion-parallelization" title="Link to this heading">#</a></h2>
<p>When available during installation, MsSpec will link with the system lapack library. It will be used to invert the matrix in the <code class="docutils literal notranslate"><span class="pre">inversion</span></code> option of the MsSpec <code class="docutils literal notranslate"><span class="pre">calculator</span></code>. To allow MsSpec to use this shared memory parallelism, you need to set the number of cores to be used in the <code class="docutils literal notranslate"><span class="pre">OMP_NUM_THREADS</span></code> environment variable.</p>
<p>You can set this variable just for the execution of your script. For example:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span><span class="nv">OMP_NUM_THREADS</span><span class="o">=</span><span class="m">12</span><span class="w"> </span>python<span class="w"> </span>my_script.py
</pre></div>
</div>
<p>will use 12 cores for inverting the matrix in your script.</p>
<p>It is also possible to set environment variable inside your python script.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;OMP_NUM_THREADS&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="mi">12</span>
</pre></div>
</div>
<p>It may be useful for technical reasons or to use different number of cores in some parts of your script.</p>
</section>
<section id="process-based-parallelism">
<h2>Process-based parallelism<a class="headerlink" href="#process-based-parallelism" title="Link to this heading">#</a></h2>
<p>Another kind of parallelization used in MsSpec is multiprocessing. Quite often, you need to run different <em>independent</em> calculations. MsSpec provides a simple <em>looper</em> that can be useful for multiprocessing. Lets demonstrate it with the previous example CO/Fe(001).</p>
<p><a class="reference download internal" download="" href="../_downloads/cd5e8362249e8155dffd698f9d924327/COFe_mp.py"><span class="xref download myst">This script</span></a> is the multiprocessed version of the previous one. You can see that the previous nested for loops are now replaced by some declarative content (lines 63-67) and the definition of a <code class="docutils literal notranslate"><span class="pre">process</span></code> function (whose name
can be changed).</p>
<p>With the <code class="docutils literal notranslate"><span class="pre">msspec.looper</span></code> package, the user define <code class="docutils literal notranslate"><span class="pre">Sweep</span></code> objects that are parameters of the calculation or of the cluster. The <code class="docutils literal notranslate"><span class="pre">process</span></code> function must accept as many arguments as parameters to sweep (+ the <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code>).</p>
<p>A <code class="docutils literal notranslate"><span class="pre">Looper</span></code> object is created (line 76) and the <code class="docutils literal notranslate"><span class="pre">process</span></code> function is set to its <code class="docutils literal notranslate"><span class="pre">pipeline</span></code> attribute (line 77). When MsSpec will run the <code class="docutils literal notranslate"><span class="pre">looper</span></code>, it will combine all parameters values to unique individual sets and MsSpec will distribute the calculations over the number of processors specified in the <code class="docutils literal notranslate"><span class="pre">ncpu</span></code> option.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="linenos">63</span><span class="c1"># 1) Multiprocess calculations </span>
<span class="linenos">64</span><span class="n">theta</span> <span class="o">=</span> <span class="n">Sweep</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;theta&#39;</span><span class="p">,</span> <span class="n">comments</span><span class="o">=</span><span class="s2">&quot;The molecule tilt angle&quot;</span><span class="p">,</span>
<span class="linenos">65</span> <span class="n">start</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="s1">&#39;degree&#39;</span><span class="p">)</span>
<span class="linenos">66</span><span class="n">phi</span> <span class="o">=</span> <span class="n">Sweep</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;phi&#39;</span><span class="p">,</span> <span class="n">comments</span><span class="o">=</span><span class="s2">&quot;The molecule azimuthal angle&quot;</span><span class="p">,</span>
<span class="linenos">67</span> <span class="n">values</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">45</span><span class="p">],</span> <span class="n">unit</span><span class="o">=</span><span class="s1">&#39;degree&#39;</span><span class="p">)</span>
<span class="linenos">68</span>
<span class="linenos">69</span><span class="k">def</span><span class="w"> </span><span class="nf">process</span><span class="p">(</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="linenos">70</span> <span class="n">cluster</span> <span class="o">=</span> <span class="n">create_cluster</span><span class="p">(</span><span class="n">theta</span><span class="o">=</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="o">=</span><span class="n">phi</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mf">0.6</span><span class="p">,</span> <span class="n">bond_length</span><span class="o">=</span><span class="mf">1.157</span><span class="p">)</span>
<span class="linenos">71</span> <span class="n">i</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;sweep_index&#39;</span><span class="p">)</span>
<span class="linenos">72</span> <span class="n">data</span> <span class="o">=</span> <span class="n">compute_polar_scan</span><span class="p">(</span><span class="n">cluster</span><span class="p">,</span> <span class="n">folder</span><span class="o">=</span><span class="sa">f</span><span class="s1">&#39;calc_</span><span class="si">{</span><span class="n">i</span><span class="si">:</span><span class="s1">d</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="linenos">73</span> <span class="n">dset</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="linenos">74</span> <span class="k">return</span> <span class="n">dset</span><span class="o">.</span><span class="n">theta</span><span class="p">,</span> <span class="n">dset</span><span class="o">.</span><span class="n">cross_section</span>
<span class="linenos">75</span>
<span class="linenos">76</span><span class="n">looper</span> <span class="o">=</span> <span class="n">Looper</span><span class="p">()</span>
<span class="linenos">77</span><span class="n">looper</span><span class="o">.</span><span class="n">pipeline</span> <span class="o">=</span> <span class="n">process</span>
<span class="linenos">78</span><span class="n">df</span> <span class="o">=</span> <span class="n">looper</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="n">ncpu</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="linenos">79</span>
<span class="linenos">80</span><span class="c1"># Black magic to convert the pandas dataframe object &#39;df&#39; to the </span>
<span class="linenos">81</span><span class="c1"># parameters dict and the resulst list (will be easier in a future</span>
<span class="linenos">82</span><span class="c1"># version ;-) ).</span>
<span class="linenos">83</span><span class="n">parameters</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">to_dict</span><span class="p">(</span><span class="s1">&#39;list&#39;</span><span class="p">)</span>
<span class="linenos">84</span><span class="n">results</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">parameters</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">),</span> <span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
<div class="sd-tab-set docutils">
<input checked="checked" id="sd-tab-item-0" name="sd-tab-set-0" type="radio">
<label class="sd-tab-label" for="sd-tab-item-0">
<i class="fa-solid fa-circle-question"></i> Quiz</label><div class="sd-tab-content docutils">
<p>In the paper discussed in <a class="reference internal" href="../Activity09/Activity09.html#rfactor"><span class="std std-ref">Activity 9: Comparing simulation and experiment with R-factors</span></a>, experimental values of the anisotropy suggest an adsorption height between 0.2 and 0.6 Å. Modify the script to add another sweep for variying the adsorption height of the CO molecule.</p>
</div>
</div>
<div class="cell docutils container">
<div class="cell_input docutils container">
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\U0000212B</span><span class="s1">&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>
</pre></div>
</div>
</div>
</div>
<div class="toggle docutils container">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="linenos">63</span><span class="c1"># 1) Multiprocess calculations </span>
<span class="linenos">64</span><span class="n">theta</span> <span class="o">=</span> <span class="n">Sweep</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;theta&#39;</span><span class="p">,</span> <span class="n">comments</span><span class="o">=</span><span class="s2">&quot;The molecule tilt angle&quot;</span><span class="p">,</span>
<span class="linenos">65</span> <span class="n">start</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="s1">&#39;degree&#39;</span><span class="p">)</span>
<span class="linenos">66</span><span class="n">phi</span> <span class="o">=</span> <span class="n">Sweep</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;phi&#39;</span><span class="p">,</span> <span class="n">comments</span><span class="o">=</span><span class="s2">&quot;The molecule azimuthal angle&quot;</span><span class="p">,</span>
<span class="linenos">67</span> <span class="n">values</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">45</span><span class="p">],</span> <span class="n">unit</span><span class="o">=</span><span class="s1">&#39;degree&#39;</span><span class="p">)</span>
<span class="hll"><span class="linenos">68</span><span class="n">height</span> <span class="o">=</span> <span class="n">Sweep</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;height&#39;</span><span class="p">,</span> <span class="n">comments</span><span class="o">=</span><span class="s2">&quot;The molecule adsorption height&quot;</span><span class="p">,</span>
</span><span class="hll"><span class="linenos">69</span> <span class="n">start</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="mf">0.6</span><span class="p">,</span> <span class="n">num</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="s1">&#39;angström&#39;</span><span class="p">)</span>
</span><span class="linenos">70</span>
<span class="hll"><span class="linenos">71</span><span class="k">def</span><span class="w"> </span><span class="nf">process</span><span class="p">(</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span><span class="hll"><span class="linenos">72</span> <span class="n">cluster</span> <span class="o">=</span> <span class="n">create_cluster</span><span class="p">(</span><span class="n">theta</span><span class="o">=</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="o">=</span><span class="n">phi</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span> <span class="n">bond_length</span><span class="o">=</span><span class="mf">1.157</span><span class="p">)</span>
</span><span class="linenos">73</span> <span class="n">i</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;sweep_index&#39;</span><span class="p">)</span>
<span class="linenos">74</span> <span class="n">data</span> <span class="o">=</span> <span class="n">compute_polar_scan</span><span class="p">(</span><span class="n">cluster</span><span class="p">,</span> <span class="n">folder</span><span class="o">=</span><span class="sa">f</span><span class="s1">&#39;calc_</span><span class="si">{</span><span class="n">i</span><span class="si">:</span><span class="s1">d</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="linenos">75</span> <span class="n">dset</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="linenos">76</span> <span class="k">return</span> <span class="n">dset</span><span class="o">.</span><span class="n">theta</span><span class="p">,</span> <span class="n">dset</span><span class="o">.</span><span class="n">cross_section</span>
<span class="linenos">77</span>
<span class="linenos">78</span><span class="n">looper</span> <span class="o">=</span> <span class="n">Looper</span><span class="p">()</span>
<span class="linenos">79</span><span class="n">looper</span><span class="o">.</span><span class="n">pipeline</span> <span class="o">=</span> <span class="n">process</span>
<span class="hll"><span class="linenos">80</span><span class="n">df</span> <span class="o">=</span> <span class="n">looper</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">theta</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">ncpu</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</span><span class="linenos">81</span>
<span class="linenos">82</span><span class="c1"># Black magic to convert the pandas dataframe object &#39;df&#39; to the </span>
<span class="linenos">83</span><span class="c1"># parameters dict and the resulst list (will be easier in a future</span>
<span class="linenos">84</span><span class="c1"># version ;-) ).</span>
<span class="linenos">85</span><span class="n">parameters</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">to_dict</span><span class="p">(</span><span class="s1">&#39;list&#39;</span><span class="p">)</span>
<span class="linenos">86</span><span class="n">results</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">parameters</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">),</span> <span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
</div>
</section>
</section>
<script type="text/x-thebe-config">
@ -401,6 +509,22 @@ document.write(`
<div class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> Contents
</div>
<nav class="bd-toc-nav page-toc">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#matrix-inversion-parallelization">Matrix inversion parallelization</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#process-based-parallelism">Process-based parallelism</a></li>
</ul>
</nav></div>
</div></div>
</div>
<footer class="bd-footer-content">

View File

@ -0,0 +1,96 @@
from ase import Atoms
from ase.build import add_adsorbate, bulk
from msspec.calculator import MSSPEC, RFACTOR
from msspec.utils import hemispherical_cluster
from msspec.looper import Sweep, Looper
import numpy as np
def create_cluster(height=1., theta=45, phi=0, bond_length=1.15):
# Fill the body of this function. The 'cluster' object in built according to
# values provided by the keyword arguments:
# height (in angströms): the 'z' distance between the Fe surface and the C atom
# theta and phi (in degrees): the polar and azimuthal orientation of the CP molecule
# (theta=0° aligns the molecule withe the surface normal
# phi=0° corresponds to the [100] direction of iron)
# bond_length (in angströms): the C-O distance
iron = bulk('Fe', cubic=True)
cluster = hemispherical_cluster(iron, diameter=5, planes=2, emitter_plane=1)
t = np.radians(theta)
p = np.radians(phi)
z = bond_length * np.cos(t)
x = bond_length * np.sin(t) * np.cos(p)
y = bond_length * np.sin(t) * np.sin(p)
CO=Atoms('CO',positions=[(0,0,0),(x,y,z)])
add_adsorbate(cluster,CO, height=height)
# Keep those 2 lines at the end of your function
# Store some information in the cluster object
cluster.info.update(adsorbate={'theta': theta, 'phi': phi, 'height': height,
'bond_length': bond_length})
return cluster
def compute_polar_scan(cluster, folder='calc'):
calc = MSSPEC(spectroscopy='PED', algorithm='expansion', folder=folder)
calc.set_atoms(cluster)
# SSC calculations
calc.calculation_parameters.scattering_order = 1
# Add temperature effects
[atom.set('mean_square_vibration', 0.005) for atom in cluster]
calc.calculation_parameters.vibrational_damping = 'averaged_tl'
polar_angles = np.arange(-5, 85, 0.5)
# set the Carbon as absorber and compute the polar scan
cluster.absorber = cluster.get_chemical_symbols().index('C')
data = calc.get_theta_scan(level='1s', theta=polar_angles, kinetic_energy=1202)
calc.shutdown()
return data
###############################################################################
# Main part
###############################################################################
# 1) Multiprocess calculations
theta = Sweep(key='theta', comments="The molecule tilt angle",
start=50, stop=60, step=1, unit='degree')
phi = Sweep(key='phi', comments="The molecule azimuthal angle",
values=[0,45], unit='degree')
def process(theta, phi, **kwargs):
cluster = create_cluster(theta=theta, phi=phi, height=0.6, bond_length=1.157)
i = kwargs.get('sweep_index')
data = compute_polar_scan(cluster, folder=f'calc_{i:d}')
dset = data[-1]
return dset.theta, dset.cross_section
looper = Looper()
looper.pipeline = process
df = looper.run(theta, phi, ncpu=4)
# Black magic to convert the pandas dataframe object 'df' to the
# parameters dict and the resulst list (will be easier in a future
# version ;-) ).
parameters = df.to_dict('list')
results = np.reshape(parameters.pop('output'), (df.shape[0]*2,-1))
# 2) R-Factor analysis
# Load the experimental data
exp_data = np.loadtxt('experimental_data.txt')
# Create an R-Factor calculator
rfc = RFACTOR()
rfc.set_references(exp_data[:,0], exp_data[:,1])
# Perform the R-Factor analysis
data = rfc.run(*results, **parameters)
data.view()

View File

@ -6,6 +6,7 @@
"id": "aa43e0e7-0c18-4750-9e2b-3a48f106d2ca",
"metadata": {},
"source": [
"(RFactor)=\n",
"# Activity 9: Comparing simulation and experiment with R-factors\n",
"In order to extract precise crystallographic information from electronic spectroscopy, we need to compare MsSpec calculations with experimental results and adjust the modelling parameters to simulate the experiment as accurately as possible.\n",
"\n",

View File

@ -9,12 +9,97 @@
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "526d98f6-5a18-4ed9-9870-29b08b54e073",
"cell_type": "markdown",
"id": "1dccb5e3-1cd3-4732-a7ba-81a8a94c89dc",
"metadata": {},
"outputs": [],
"source": []
"source": [
"As you can see from the previous examples, a complete simulation may require several multiple scattering calculations, for instance to calculate the total intensity of a substrate or to optimize the geometry of a system. As the calculations are often time consuming, it can be useful to distribute these tasks over several processors to make the most of hardware resources.\n",
"Although MsSpec is not fully parallelized, the code does offer a number of features, which we will explore here.\n",
"\n",
"## Matrix inversion parallelization\n",
"\n",
"When available during installation, MsSpec will link with the system lapack library. It will be used to invert the matrix in the `inversion` option of the MsSpec `calculator`. To allow MsSpec to use this shared memory parallelism, you need to set the number of cores to be used in the `OMP_NUM_THREADS` environment variable.\n",
"\n",
"You can set this variable just for the execution of your script. For example:\n",
"\n",
"```sh\n",
"$ OMP_NUM_THREADS=12 python my_script.py\n",
"```\n",
"\n",
"will use 12 cores for inverting the matrix in your script.\n",
"\n",
"It is also possible to set environment variable inside your python script.\n",
"\n",
"```python\n",
"import os\n",
"\n",
"os.environ['OMP_NUM_THREADS'] = 12\n",
"```\n",
"\n",
"It may be useful for technical reasons or to use different number of cores in some parts of your script.\n",
"\n",
"## Process-based parallelism\n",
"\n",
"Another kind of parallelization used in MsSpec is multiprocessing. Quite often, you need to run different *independent* calculations. MsSpec provides a simple *looper* that can be useful for multiprocessing. Let's demonstrate it with the previous example CO/Fe(001).\n",
"\n",
"[This script](COFe_mp.py) is the multiprocessed version of the previous one. You can see that the previous nested for loops are now replaced by some declarative content (lines 63-67) and the definition of a `process` function (whose name \n",
"can be changed).\n",
"\n",
"With the `msspec.looper` package, the user define `Sweep` objects that are parameters of the calculation or of the cluster. The `process` function must accept as many arguments as parameters to sweep (+ the `**kwargs`).\n",
"\n",
"A `Looper` object is created (line 76) and the `process` function is set to its `pipeline` attribute (line 77). When MsSpec will run the `looper`, it will combine all parameters values to unique individual sets and MsSpec will distribute the calculations over the number of processors specified in the `ncpu` option.\n",
"\n",
":::{literalinclude} COFe_mp.py\n",
":lineno-start: 63\n",
":linenos: true\n",
":lines: 63-84\n",
":::\n",
"\n",
"\n",
"::::{tab-set}\n",
"\n",
":::{tab-item} <i class=\"fa-solid fa-circle-question\"></i> Quiz\n",
"In the paper discussed in {ref}`RFactor`, experimental values of the anisotropy suggest an adsorption height between 0.2 and 0.6 Å. Modify the script to add another sweep for variying the adsorption height of the CO molecule.\n",
":::\n",
"\n",
"::::"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "9da716db-069f-422b-a5fd-2c2b509eb621",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Å\n"
]
}
],
"source": [
"print('\\U0000212B')"
]
},
{
"cell_type": "markdown",
"id": "0a1fabce-c42d-4cb4-9720-bcd21ff0cd09",
"metadata": {},
"source": [
"```{toggle}\n",
"\n",
":::{literalinclude} COFe_mp_completed.py\n",
":lineno-start: 63\n",
":linenos: true\n",
":lines: 63-86\n",
":emphasize-lines: 6,7, 9,10, 18\n",
":::\n",
"\n",
"\n",
"```"
]
}
],
"metadata": {
@ -33,7 +118,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
"version": "3.11.3"
}
},
"nbformat": 4,

Binary file not shown.

View File

@ -0,0 +1,47 @@
Traceback (most recent call last):
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/jupyter_core/utils/__init__.py", line 154, in wrapped
asyncio.get_running_loop()
RuntimeError: no running event loop
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/jupyter_cache/executors/utils.py", line 58, in single_nb_execution
executenb(
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/nbclient/client.py", line 1319, in execute
return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/jupyter_core/utils/__init__.py", line 158, in wrapped
return loop.run_until_complete(inner)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pyenv/versions/3.11.3/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/nbclient/client.py", line 709, in async_execute
await self.async_execute_cell(
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/nbclient/client.py", line 1062, in async_execute_cell
await self._check_raise_for_error(cell, cell_index, exec_reply)
File "/opt/msspec/msspec_venv/lib/python3.11/site-packages/nbclient/client.py", line 918, in _check_raise_for_error
raise CellExecutionError.from_cell_and_msg(cell, exec_reply_content)
nbclient.exceptions.CellExecutionError: An error occurred while executing the following cell:
------------------
```{toggle}
:::{literalinclude} COFe_mp_completed.py
:lineno-start: 63
:linenos: true
:lines: 63-86
:emphasize-lines: 6,7, 9,10, 18
:::
```
------------------
Cell In[2], line 1
 ```{toggle}
^
SyntaxError: invalid syntax

File diff suppressed because one or more lines are too long