-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.html
More file actions
427 lines (426 loc) · 19 KB
/
README.html
File metadata and controls
427 lines (426 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>KPFM simulation tools</title>
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
h1 {
font-size: 1.8em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC ul {
padding-left: 1.3em;
}
#TOC > ul {
padding-left: 0;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">KPFM simulation tools</h1>
</header>
<h1 id="description">Description</h1>
<p>A set of Python modules for running DFT level KPFM simulations using
CP2k and storing the results to a relational database (SQLite). Works
for AFM simulations as well since they are just KPFM simulations without
bias modulation. Contains three main components to help you with the
simulations: 1. Planning CP2k calculation tasks and storing them to a
database for later execution. 2. Running previously planned tasks
automatically exploiting the results of the previous task step to reduce
computation time. 3. Storing the essential results (total energy, atomic
geometry...) in a structured form to a relational database and
extracting those results easily within Python scripts. These tools
expect you to set up your atomic configuration using Atomic Simulation
Environment (ASE). If you do not like ASE, you can use whatever modeling
tools you like and read the atomic configuration with ASE to an Atoms
object and use it.</p>
<p>The original plan of this project was to simulate KPFM above a
non-conducting surface, and this part of code should in princicple
working if a former version of the code: <a
href="https://github.com/SINGROUP/KPFM_sim/tree/138df5e02210501efdd09237fb0e2642816c6ccb">https://github.com/SINGROUP/KPFM_sim/tree/138df5e02210501efdd09237fb0e2642816c6ccb</a>,
which was at least translated to python3.</p>
<p>In the latest development it was used for calculations of KPFM of
metallic sample with molecule on it and metallic tip with a flexible-tip
apex, like -CO molecule. The latest version was producing results of
forces under sample-bias, however these were not in agreement with other
theories. The calculations as such were also rather noisy!</p>
<h1 id="requirements">Requirements</h1>
<ul>
<li>Python 3.x</li>
<li>NumPy</li>
<li>SciPy</li>
<li>Atomic Simulation Environment (ASE), <a
href="https://wiki.fysik.dtu.dk/ase/">https://wiki.fysik.dtu.dk/ase/</a></li>
<li><a href="https://github.com/SINGROUP/CP2k_mtools">CP2k_mtools</a>
(python base)</li>
</ul>
<p>In the latest version the electric field is calculated through C++
procedures stored in <a
href="https://github.com/SINGROUP/KPFM_sim/tree/master/E_field">E_field</a>;
for their compilation:</p>
<ul>
<li>g++</li>
</ul>
<p>Not directly used in the latest version, but still important due to
dependencies:</p>
<ul>
<li>Cython (<a href="http://cython.org/">http://cython.org/</a>)</li>
<li><a href="https://github.com/SINGROUP/DFT_gridIO">DFT_gridIO</a>
(python base)</li>
</ul>
<p>In the latest vestion totally ommited - For calculating electrostatic
potential of non-conducting tip and sample:</p>
<ul>
<li><a href="https://github.com/SINGROUP/KPFM_FEM">KPFM_FEM_tools</a>
(python base)</li>
</ul>
<h1 id="wiki">WIKI</h1>
<p>Newest description, installation guide and examples for running in
the under development <a
href="https://github.com/SINGROUP/KPFM_sim/wiki">wiki pages</a></p>
<h1 id="installation">Installation</h1>
<p>Put this directory containing the Python and Cython (.pyx) modules to
your <code>PYTHONPATH</code> environment variable. The Cython modules
should be compiled automatically at runtime if the line as long as you
have Cython installed. If not, you can try running the setup scripts as
<code>python setup_x.py build_ext --inplace</code> Create a new
environment variable called <code>KPFM_GLOBAL_SCRIPTS</code> and store
the path to the <code>scripts</code> folder to it. These are scripts
that have no system dependent parameters so you can call them from a
centralized location, and adding that location to an environment
variable makes your life easier.</p>
<h1 id="usage">Usage</h1>
<p>This is an introduction to using these tools to run KPFM simulations.
For more information about multiscale KPFM simulations in general, see
the <code>docs</code> folder. If you have access to the shared archive
folder of the SIN group, you can find a complete usage example in
<code>/path_to_archive/jritala/KPFM_sim</code>. You should use the
scripts in <code>control_script_templates</code> folder as a starting
point for your own simulations since they are part of the user interface
to these tools. See also <code>slurm_script_templates</code> folder for
examples of Slurm scripts to actually run the simulations on a
supercomputer. The user interface to these tools is far from refined so
I do not mind if you choose to improve it or write your own. The
underlying functionality works very well, in my opinion.</p>
<h2 id="setting-up-initial-atomic-configuration">Setting up initial
atomic configuration</h2>
<p>Use the <code>kpfm_init_cu_tip_on_nacl.py</code> script as a template
for creating your initial atomic configuration. This configuration
should contain a tip model at the maximum distance from the sample. It
does not matter how you create the model, as long as you have it stored
in an ASE Atoms object in the end. To optimize the initial geometry,
call</p>
<pre><code>cp2k_initializer = CP2k_init(project_name, atoms)
cp2k_calc = cp2k_initializer.init_desc_tip()
cp2k_calc.run()</code></pre>
<p>where <code>project_name</code> is whatever name you choose and
<code>atoms</code> is an Atoms object containing your tip-sample model.
See the documentation of <a href="">CP2k_tools</a> for more information.
After that, you should read the optimized geometry and CP2k output file,
label the "roles" of the atoms in the model and store all this
information to a results database defined by <code>Result_db</code>
class in the <code>kpfm_sim_result_db</code> module. Now you should have
an SQLite database file containing information on atoms and unit cell of
your model and the initial geometry in the directory where you ran the
initialization script. <code>Result_db</code> class represents the
database in Python and it contains many methods for extracting data from
it without any knowlegde of relational databases. If you want to see the
actual structure of the database file and its contents, use
<code>sqlite3</code> command line tool (requires knowledge of SQL
language) or <code>Sqliteman</code> which has a GUI.</p>
<h2
id="probing-the-sample-at-different-positions-afm-simulation">Probing
the sample at different positions (AFM simulation)</h2>
<p>Now that you have initialized the result database and stored the
initial atomic configuration to it, you can easily run a geometry
optimization at multiple positions of the tip above the sample to get
the total energy, atomic geometry and forces on atoms at those
positions. These tools allow you to plan multiple tasks and store them
to a database, and when you submit a batch job, one of these tasks is
fetched for execution. Each task typically consists of multiple steps
that each correspond to a single CP2k calculation. The task type to
sample different positions above the sample is called "descend tip" and
it is defined by the <code>Descend_tip_task</code> class in
<code>kpfm_sim_tasks</code> module. The descend tip task samples a range
of tip-sample distances starting from a position far away and moving the
tip closer by constant amount at each step.</p>
<p>To create a descend tip task, use the
<code>plan_descend_tip_task.py</code> script template in
<code>control_script_templates</code> folder and change the parameters
to match your simulation. Make sure <code>V = 0</code> to run without
bias voltage. Then call</p>
<p><code>python plan_descend_tip_task.py -f <task_db_file> <result_db_file> <global_res_db_file></code></p>
<p>where <code><task_db_file></code>,
<code><result_db_file></code> and
<code><global_res_db_file></code> are relative paths to task,
result and global result database files respectively.</p>
<p><strong>Important implementation note:</strong> In principle, the
SQLite database handles concurrent writes to it correctly. However, in
an environment with a parallel file system, as in many supercomputers
like the CSC clusters, concurrent writes to the same database file from
processes running on different nodes may result in corruption of the
database. The workaround I have used is to create separate task and
result database files for each concurrently running job and copy the
results from the separate result databases to a global result database
at the end. I suggest you create as many subfolders as there are
concurrent jobs that you want to run, and call them
<code>worker_n</code>, for example, where <code>n</code> labels the
different jobs.</p>
<p>If you want to execute multiple tasks at the same time in an
environment with a parallel file system, the <code>task_db_file</code>
and <code>result_db_file</code> should be separate for each concurrently
running job as described in the implementation note above. If you follow
the suggested scheme, you should call
<code>plan_descend_tip_task.py</code> with arguments</p>
<p><code>python plan_descend_tip_task.py -f worker_1/tasks.db worker_1/results.db your_simulation_results.db</code></p>
<p>where <code>worker_1</code> is a subfolder you created and
<code>your_simulation_results.db</code> is the database file containing
the initial atomic configuration. <code>tasks.db</code> and
<code>results.db</code> files are created automatically if they do not
exist and the task you planned is saved to the <code>tasks.db</code>
database file.</p>
<p>To execute a task you have planned, run the <code>run_task.py</code>
script found in the <code>scripts</code> folder as</p>
<p><code>python run_task.py -f <task_db_file> <project_path> -s <slurm_id> [type_constraint] [status_constraint]</code></p>
<p>where <code><task_db_file></code> is a relative path from
<code><project_path></code> to the task database file and
<code><project_path></code> is the absolute path to the root
directory of the simulations. <code>project_path</code> is needed in
cases where the CP2k is run on a local file system of a node but the
database files are on the shared file system. Since the tasks are
typically executed in Slurm batch jobs, the
<code><slurm_id></code> should be set to the ID of the slurm job
executing the task. <code>[type_constraint]</code>
and<code>[status_constraint]</code> are optional and can be used to
restrict the type of the task to be run if there are multiple different
kinds of tasks waiting and you want to run a specific one. See the
<code>worker_task_batch.sh</code> script in
<code>slurm_script_templates</code> for an example of a Slurm script
(written for CSC Taito cluster). In particular, you should have the line
<code>trap "python $KPFM_GLOBAL_SCRIPTS/call_error_handler.py $SLURM_JOB_ID $ORIG_DIR $TASK_DB_FILE; exit" ERR TERM</code>
in the Slurm script if you want to have the error handler working. It is
not necessary, but makes restarting possible in the case of an error or
exceeded time limit. Otherwise you have to modify the task database by
hand. You may have to do that anyway, if the cause of termination is
something else than time limit. In that case, open the task database
file using sqlite3 or Sqliteman and change the task state to
waiting.</p>
<h2
id="probing-the-sample-with-different-bias-voltages-kpfm-simulation">Probing
the sample with different bias voltages (KPFM simulation)</h2>
<p>The way how the bias voltage between the probe and the sample holder
is applied to the KPFM simulation depends on the type of the system you
are studying. In particular, there are two entirely different cases:</p>
<ol type="1">
<li>Thick dielectric sample (thick meaning that you cannot model the
whole sample within DFT)</li>
<li>Thin dielectric sample on metallic substrate (thin meaning that you
can model the whole sample as well as some layers of the metal
substrate)</li>
</ol>
<p>In the case of a thick dielectric sample, you should calculate the
electrostatic potential generated by the macroscopic part of the
probe-sample model using <a href="">KPFM_FEM_tools</a>. See the
documentation of that package for instructions. When you have calculated
the potential at sufficient range of tip-sample distances and have them
stored into a FEM results database file, you should copy the data into
the KPFM results database that was created during initialization of the
atomic configuration. You can do that using
<code>copy_pot_to_result_db.py</code> script. When you execute a task
with a non-zero bias voltage, the electrostatic potential is read from
the database and written into a cube file by a function in the
<code>axisym_pot_to_cube</code> module. That cube file is read by CP2k
and added as an external potential to the DFT calculation.</p>
<p>If you have a thin sample, however, the electrostatic potential
between the tip and the metallic substrate is entirely defined by the
atomic model. The correct potential/field between the tip and the
substrate is generated if a suitable amount of charge is transferred
between them. This happens if one is able to shift the Fermi levels of
the tip and the substrate with respect to each other. One way to do this
is to apply step-like external potential to the DFT calculation so that
the tip is at a different potential than the substrate. You can use
<code>piecewise_linear_potential</code> module to create the step-like
potential. There is no option to use this method automatically within
the simulation tools environment yet. Find the TODO comment in
<code>kpfm_sim_tasks</code> if you want to implement it.</p>
<p>Independent of the way of applying the bias voltage, you can either
go through the zero bias scan points and vary the bias at each of those
points or fix the bias voltage and descend the tip with that bias. You
can use the <code>plan_tune_bias_task.py</code> or
<code>plan_tune_bias_tasks_srange.py</code> as a template for a script
for planning tasks which have varying bias voltage. Descending the tip
using a fixed bias voltage works by planning tasks using
<code>plan_descend_tip_task.py</code> script with a non-zero
<code>V</code>. Descending with a fixed bias seems to work better
because varying the bias changes the atomic geometry globally and thus
the previous step with a different bias voltage is not a good guess for
the initial geometry of a geometry optimization.</p>
<h2 id="calculating-atomic-forces">Calculating atomic forces</h2>
<p>The forces on atoms must be calculated during a separate run because
the forces on fixed atoms are zero during geometry optimization. Use
<code>calc_atomic_forces.py</code> script to do it.</p>
<h2 id="combining-the-results-into-one-database-file">Combining the
results into one database file</h2>
<p>If you executed multiple tasks in parallel and have multiple separate
database files, you can combine them into one database using the
<code>copy_scan_points.py</code> script.</p>
<h2 id="analysing-the-results-in-the-database">Analysing the results in
the database</h2>
<p>The Result_db class defined in kpfm_sim_result_db module contains
many methods for extracting data from the SQLite result database without
any knowledge of relational databases. You can also use the ready-made
<code>extract_*</code> scripts in the scripts folder or use them as an
example.</p>
<h1 id="author">Author</h1>
<p>Ondrej Krejci (2021) <a href="/cdn-cgi/l/email-protection#cfa0a1abbdaaa5e1a4bdaaa5aca68faeaea3bba0e1a9a6"><span class="__cf_email__" data-cfemail="0b64656f796e612560796e6168624b6a6a677f64256d62">[email protected]</span></a></p>
<p>Juha Ritala (2016) <a href="/cdn-cgi/l/email-protection#660c140f12070a0726010b070f0a4805090b"><span class="__cf_email__" data-cfemail="660c140f12070a0726010b070f0a4805090b">[email protected]</span></a></p>
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script></body>
</html>