Compare commits
1 Commits
master
...
latticegen
Author | SHA1 | Date |
---|---|---|
Marek Nečada | 08b8a1a315 |
83
.drone.yml
83
.drone.yml
|
@ -1,83 +0,0 @@
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: buildqpms-alpine-preinstlibs
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
path: /home/qpmsbuild/qpms
|
|
||||||
|
|
||||||
# don't run in master until the python/lapacke linking problem is resolved
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
exclude:
|
|
||||||
- master
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: chown
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
commands:
|
|
||||||
- chown -R qpmsbuild.qpmsbuild .
|
|
||||||
- name: submodules
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- git submodule init
|
|
||||||
- git submodule update
|
|
||||||
- name: build
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .
|
|
||||||
- make install
|
|
||||||
- export LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- python3 setup.py install --user
|
|
||||||
- cd examples/rectangular/modes
|
|
||||||
- pip3 install --user matplotlib #needed to run the example
|
|
||||||
- export LD_LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- ./01a_realfreq_svd.sh
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: buildqpms-debian-preinstlibs
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
path: /home/qpmsbuild/qpms
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: chown
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
commands:
|
|
||||||
- chown -R qpmsbuild.qpmsbuild .
|
|
||||||
- name: submodules
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- git submodule init
|
|
||||||
- git submodule update
|
|
||||||
- name: build
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/home/qpmsbuild/.local .
|
|
||||||
- make install
|
|
||||||
- export LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- python3 setup.py install --user
|
|
||||||
- pip3 install --user matplotlib #needed to run the examples
|
|
||||||
- export LD_LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- cd examples/rectangular/modes
|
|
||||||
- ./01a_realfreq_svd.sh
|
|
||||||
- cd -
|
|
||||||
- cd examples/hexagonal/modes
|
|
||||||
#- ./01a_realfreq_svd.sh
|
|
||||||
#- ./01_compute_modes.sh
|
|
||||||
#- ./02b_compute_disp_0M.sh
|
|
||||||
#- ./02_compute_disp.sh
|
|
||||||
#- ./02x_compute_disp.sh
|
|
||||||
|
|
|
@ -5,29 +5,4 @@
|
||||||
*.pdf
|
*.pdf
|
||||||
*.o
|
*.o
|
||||||
docs/*
|
docs/*
|
||||||
|
|
||||||
qpms/qpms_c.c
|
qpms/qpms_c.c
|
||||||
qpms/cy*.c
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles/*
|
|
||||||
faddeeva/*
|
|
||||||
qpms/CMakeFiles/*
|
|
||||||
qpms/libqpms.so
|
|
||||||
qpms/cmake_install.cmake
|
|
||||||
qpms_version.c
|
|
||||||
qpms.egg_info/*
|
|
||||||
dist/*
|
|
||||||
build/*
|
|
||||||
Makefile
|
|
||||||
CTestTestfile.cmake
|
|
||||||
|
|
||||||
amos/CMakeFiles/*
|
|
||||||
amos/Makefile
|
|
||||||
amos/amos_mangling.h
|
|
||||||
cmake_install.cmake
|
|
||||||
cython_debug/*
|
|
||||||
qpms.egg-info/*
|
|
||||||
tests/CmakeFiles/*
|
|
||||||
tests/cmake_install.cmake
|
|
||||||
tests/CMakeFiles/*
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[submodule "camos"]
|
|
||||||
path = camos
|
|
||||||
url = https://codeberg.org/QPMS/zbessel.git
|
|
||||||
branch = purec
|
|
43
CLIUTILS.md
43
CLIUTILS.md
|
@ -1,43 +0,0 @@
|
||||||
Overview of QPMS command line utilities
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
The utilities are located in the `misc` directory. Run the
|
|
||||||
utility with `-h` argument to get more info.
|
|
||||||
|
|
||||||
|
|
||||||
Rectangular and square 2D lattices
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
These scripts deal with simple 2D rectangular lattices,
|
|
||||||
finite or infinite, one scatterer per unit cell.
|
|
||||||
\f$ D_{2h} \f$ or \f$ D_{4h} \f$ symmetric adapted bases
|
|
||||||
are used where applicable.
|
|
||||||
|
|
||||||
### Finite lattices
|
|
||||||
|
|
||||||
* `finiterectlat-modes.py`: Search for resonances using Beyn's algorithm.
|
|
||||||
* `finiterectlat-scatter.py`: Plane wave scattering.
|
|
||||||
* `finiterectlat-constant-driving.py`: Rectangular array response to
|
|
||||||
a driving where a subset of particles are excited by basis VSWFs with the
|
|
||||||
same phase.
|
|
||||||
|
|
||||||
### Infinite lattices
|
|
||||||
|
|
||||||
* `rectlat_simple_modes.py`: Search for lattice modes using Beyn's algorithm.
|
|
||||||
* `infiniterectlat-k0realfreqsvd.py`:
|
|
||||||
Evaluate the lattice mode problem singular values at the Γ point for a real frequency interval.
|
|
||||||
Useful as a starting point in lattice mode search before using Beyn's algorithm.
|
|
||||||
* `infiniterectlat-scatter.py`: Plane wave scattering.
|
|
||||||
|
|
||||||
|
|
||||||
General 2D lattices
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
### Infinite lattices
|
|
||||||
|
|
||||||
These can contain several scatterers per unit cell. Symmetry adapted bases currently not implemented.
|
|
||||||
|
|
||||||
* `lat2d_modes.py`: Search for lattice modes using Beyn's algorithm.
|
|
||||||
* `lat2d_realfreqsvd.py`:
|
|
||||||
Evaluate the lattice mode problem singular values at the Γ point for a real frequency interval.
|
|
||||||
Useful as a starting point in lattice mode search before using Beyn's algorithm.
|
|
|
@ -1,16 +1,11 @@
|
||||||
cmake_minimum_required(VERSION 3.0.2)
|
cmake_minimum_required(VERSION 3.0.2)
|
||||||
|
|
||||||
option(QPMS_USE_FORTRAN_AMOS "Use the original AMOS Fortran libraries instead of the C ones" OFF)
|
|
||||||
|
|
||||||
if (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
include(CMakeAddFortranSubdirectory)
|
include(CMakeAddFortranSubdirectory)
|
||||||
endif (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
include(version.cmake)
|
include(version.cmake)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
project (QPMS)
|
project (QPMS)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
|
||||||
macro(use_c99)
|
macro(use_c99)
|
||||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||||
|
@ -29,23 +24,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
set (QPMS_VERSION_MAJOR 0)
|
set (QPMS_VERSION_MAJOR 0)
|
||||||
#set (QPMS_VERSION_MINOR 3)
|
#set (QPMS_VERSION_MINOR 3)
|
||||||
|
|
||||||
if (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
cmake_add_fortran_subdirectory (amos
|
cmake_add_fortran_subdirectory (amos
|
||||||
PROJECT amos
|
PROJECT amos
|
||||||
LIBRARIES amos
|
LIBRARIES amos
|
||||||
NO_EXTERNAL_INSTALL)
|
NO_EXTERNAL_INSTALL)
|
||||||
set(QPMS_AMOSLIB amos)
|
|
||||||
else (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
set(CAMOS_BUILD_STATIC ON)
|
|
||||||
add_subdirectory (camos)
|
|
||||||
set(QPMS_AMOSLIB camos)
|
|
||||||
endif (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
|
|
||||||
|
|
||||||
set(FADDEEVA_BUILD_STATIC ON)
|
|
||||||
add_subdirectory(faddeeva)
|
|
||||||
|
|
||||||
add_subdirectory (qpms)
|
add_subdirectory (qpms)
|
||||||
|
|
||||||
|
|
||||||
|
|
675
COPYING.md
675
COPYING.md
|
@ -1,675 +0,0 @@
|
||||||
### GNU GENERAL PUBLIC LICENSE
|
|
||||||
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
|
||||||
<https://fsf.org/>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this
|
|
||||||
license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
### Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom
|
|
||||||
to share and change all versions of a program--to make sure it remains
|
|
||||||
free software for all its users. We, the Free Software Foundation, use
|
|
||||||
the GNU General Public License for most of our software; it applies
|
|
||||||
also to any other work released this way by its authors. You can apply
|
|
||||||
it to your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you
|
|
||||||
have certain responsibilities if you distribute copies of the
|
|
||||||
software, or if you modify it: responsibilities to respect the freedom
|
|
||||||
of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the
|
|
||||||
manufacturer can do so. This is fundamentally incompatible with the
|
|
||||||
aim of protecting users' freedom to change the software. The
|
|
||||||
systematic pattern of such abuse occurs in the area of products for
|
|
||||||
individuals to use, which is precisely where it is most unacceptable.
|
|
||||||
Therefore, we have designed this version of the GPL to prohibit the
|
|
||||||
practice for those products. If such problems arise substantially in
|
|
||||||
other domains, we stand ready to extend this provision to those
|
|
||||||
domains in future versions of the GPL, as needed to protect the
|
|
||||||
freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish
|
|
||||||
to avoid the special danger that patents applied to a free program
|
|
||||||
could make it effectively proprietary. To prevent this, the GPL
|
|
||||||
assures that patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
### TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
#### 0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds
|
|
||||||
of works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of
|
|
||||||
an exact copy. The resulting work is called a "modified version" of
|
|
||||||
the earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user
|
|
||||||
through a computer network, with no transfer of a copy, is not
|
|
||||||
conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices" to
|
|
||||||
the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
#### 1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. "Object code" means any non-source form of
|
|
||||||
a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users can
|
|
||||||
regenerate automatically from other parts of the Corresponding Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that same
|
|
||||||
work.
|
|
||||||
|
|
||||||
#### 2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not convey,
|
|
||||||
without conditions so long as your license otherwise remains in force.
|
|
||||||
You may convey covered works to others for the sole purpose of having
|
|
||||||
them make modifications exclusively for you, or provide you with
|
|
||||||
facilities for running those works, provided that you comply with the
|
|
||||||
terms of this License in conveying all material for which you do not
|
|
||||||
control copyright. Those thus making or running the covered works for
|
|
||||||
you must do so exclusively on your behalf, under your direction and
|
|
||||||
control, on terms that prohibit them from making any copies of your
|
|
||||||
copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under the
|
|
||||||
conditions stated below. Sublicensing is not allowed; section 10 makes
|
|
||||||
it unnecessary.
|
|
||||||
|
|
||||||
#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such
|
|
||||||
circumvention is effected by exercising rights under this License with
|
|
||||||
respect to the covered work, and you disclaim any intention to limit
|
|
||||||
operation or modification of the work as a means of enforcing, against
|
|
||||||
the work's users, your or third parties' legal rights to forbid
|
|
||||||
circumvention of technological measures.
|
|
||||||
|
|
||||||
#### 4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
#### 5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
- a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
- b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under
|
|
||||||
section 7. This requirement modifies the requirement in section 4
|
|
||||||
to "keep intact all notices".
|
|
||||||
- c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
- d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
#### 6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms of
|
|
||||||
sections 4 and 5, provided that you also convey the machine-readable
|
|
||||||
Corresponding Source under the terms of this License, in one of these
|
|
||||||
ways:
|
|
||||||
|
|
||||||
- a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
- b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the Corresponding
|
|
||||||
Source from a network server at no charge.
|
|
||||||
- c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
- d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
- e) Convey the object code using peer-to-peer transmission,
|
|
||||||
provided you inform other peers where the object code and
|
|
||||||
Corresponding Source of the work are being offered to the general
|
|
||||||
public at no charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal,
|
|
||||||
family, or household purposes, or (2) anything designed or sold for
|
|
||||||
incorporation into a dwelling. In determining whether a product is a
|
|
||||||
consumer product, doubtful cases shall be resolved in favor of
|
|
||||||
coverage. For a particular product received by a particular user,
|
|
||||||
"normally used" refers to a typical or common use of that class of
|
|
||||||
product, regardless of the status of the particular user or of the way
|
|
||||||
in which the particular user actually uses, or expects or is expected
|
|
||||||
to use, the product. A product is a consumer product regardless of
|
|
||||||
whether the product has substantial commercial, industrial or
|
|
||||||
non-consumer uses, unless such uses represent the only significant
|
|
||||||
mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to
|
|
||||||
install and execute modified versions of a covered work in that User
|
|
||||||
Product from a modified version of its Corresponding Source. The
|
|
||||||
information must suffice to ensure that the continued functioning of
|
|
||||||
the modified object code is in no case prevented or interfered with
|
|
||||||
solely because modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or
|
|
||||||
updates for a work that has been modified or installed by the
|
|
||||||
recipient, or for the User Product in which it has been modified or
|
|
||||||
installed. Access to a network may be denied when the modification
|
|
||||||
itself materially and adversely affects the operation of the network
|
|
||||||
or violates the rules and protocols for communication across the
|
|
||||||
network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
#### 7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders
|
|
||||||
of that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
- a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
- b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
- c) Prohibiting misrepresentation of the origin of that material,
|
|
||||||
or requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
- d) Limiting the use for publicity purposes of names of licensors
|
|
||||||
or authors of the material; or
|
|
||||||
- e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
- f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions
|
|
||||||
of it) with contractual assumptions of liability to the recipient,
|
|
||||||
for any liability that these contractual assumptions directly
|
|
||||||
impose on those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions; the
|
|
||||||
above requirements apply either way.
|
|
||||||
|
|
||||||
#### 8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your license
|
|
||||||
from a particular copyright holder is reinstated (a) provisionally,
|
|
||||||
unless and until the copyright holder explicitly and finally
|
|
||||||
terminates your license, and (b) permanently, if the copyright holder
|
|
||||||
fails to notify you of the violation by some reasonable means prior to
|
|
||||||
60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
#### 9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or run
|
|
||||||
a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
#### 10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
#### 11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims owned
|
|
||||||
or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within the
|
|
||||||
scope of its coverage, prohibits the exercise of, or is conditioned on
|
|
||||||
the non-exercise of one or more of the rights that are specifically
|
|
||||||
granted under this License. You may not convey a covered work if you
|
|
||||||
are a party to an arrangement with a third party that is in the
|
|
||||||
business of distributing software, under which you make payment to the
|
|
||||||
third party based on the extent of your activity of conveying the
|
|
||||||
work, and under which the third party grants, to any of the parties
|
|
||||||
who would receive the covered work from you, a discriminatory patent
|
|
||||||
license (a) in connection with copies of the covered work conveyed by
|
|
||||||
you (or copies made from those copies), or (b) primarily for and in
|
|
||||||
connection with specific products or compilations that contain the
|
|
||||||
covered work, unless you entered into that arrangement, or that patent
|
|
||||||
license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
#### 12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under
|
|
||||||
this License and any other pertinent obligations, then as a
|
|
||||||
consequence you may not convey it at all. For example, if you agree to
|
|
||||||
terms that obligate you to collect a royalty for further conveying
|
|
||||||
from those to whom you convey the Program, the only way you could
|
|
||||||
satisfy both those terms and this License would be to refrain entirely
|
|
||||||
from conveying the Program.
|
|
||||||
|
|
||||||
#### 13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
#### 14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU General Public License from time to time. Such new versions
|
|
||||||
will be similar in spirit to the present version, but may differ in
|
|
||||||
detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies that a certain numbered version of the GNU General Public
|
|
||||||
License "or any later version" applies to it, you have the option of
|
|
||||||
following the terms and conditions either of that numbered version or
|
|
||||||
of any later version published by the Free Software Foundation. If the
|
|
||||||
Program does not specify a version number of the GNU General Public
|
|
||||||
License, you may choose any version ever published by the Free
|
|
||||||
Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future versions
|
|
||||||
of the GNU General Public License can be used, that proxy's public
|
|
||||||
statement of acceptance of a version permanently authorizes you to
|
|
||||||
choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
#### 15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
|
||||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
|
||||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
|
||||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
|
||||||
CORRECTION.
|
|
||||||
|
|
||||||
#### 16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
|
|
||||||
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
|
||||||
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
|
|
||||||
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
|
||||||
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
|
|
||||||
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
|
||||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
#### 17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
### How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these
|
|
||||||
terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to
|
|
||||||
attach them to the start of each source file to most effectively state
|
|
||||||
the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper
|
|
||||||
mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands \`show w' and \`show c' should show the
|
|
||||||
appropriate parts of the General Public License. Of course, your
|
|
||||||
program's commands might be different; for a GUI interface, you would
|
|
||||||
use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. For more information on this, and how to apply and follow
|
|
||||||
the GNU GPL, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your
|
|
||||||
program into proprietary programs. If your program is a subroutine
|
|
||||||
library, you may consider it more useful to permit linking proprietary
|
|
||||||
applications with the library. If this is what you want to do, use the
|
|
||||||
GNU Lesser General Public License instead of this License. But first,
|
|
||||||
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
6
Doxyfile
6
Doxyfile
|
@ -51,7 +51,7 @@ PROJECT_BRIEF = "Electromagnetic multiple scattering library and toolki
|
||||||
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
||||||
# to the output directory.
|
# to the output directory.
|
||||||
|
|
||||||
PROJECT_LOGO = farfield.png
|
PROJECT_LOGO =
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||||
# into which the generated documentation will be written. If a relative path is
|
# into which the generated documentation will be written. If a relative path is
|
||||||
|
@ -753,7 +753,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = qpms notes misc finite_systems.md MIRRORS.md CLIUTILS.md README.md README.Triton.md finite_systems.md lattices.md TODO.md
|
INPUT = qpms notes finite_systems.md README.md README.Triton.md finite_systems.md lattices.md TODO.md
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
@ -1462,7 +1462,7 @@ MATHJAX_FORMAT = HTML-CSS
|
||||||
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = https://uslugi.necada.org/js/mathjax
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
||||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
# extension names that should be enabled during MathJax rendering. For example
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
|
|
14
MIRRORS.md
14
MIRRORS.md
|
@ -1,14 +0,0 @@
|
||||||
QPMS source code mirrors
|
|
||||||
========================
|
|
||||||
|
|
||||||
QPMS source code is available at several locations; in all of the following,
|
|
||||||
upstream `master` branch is kept up-to-date. Various development branches
|
|
||||||
are not necessarily pushed everywhere (and they should be considered
|
|
||||||
unstable in the sense that rebases and forced pushes are possible).
|
|
||||||
|
|
||||||
mirror | note | provider | backend
|
|
||||||
----------------------------------------------- | ----------------------- | ------------------------------------------------- | ------
|
|
||||||
<https://repo.or.cz/qpms.git> | primary public upstream | [repo.or.cz](https://repo.or.cz/) | girocco
|
|
||||||
<https://codeberg.org/QPMS/qpms> | | [Codeberg](https://codeberg.org) | gitea
|
|
||||||
<https://git.piraattipuolue.fi/QPMS/qpms.git> | | [Pirate Party Finland](https://piraattipuolue.fi) | gitea
|
|
||||||
<https://version.aalto.fi/gitlab/qpms/qpms.git> | | [Aalto University](https://aalto.fi) | gitlab
|
|
127
README.md
127
README.md
|
@ -1,14 +1,10 @@
|
||||||
[![Build Status](https://drone.perkele.eu/api/badges/QPMS/qpms/status.svg)](https://drone.perkele.eu/QPMS/qpms)
|
|
||||||
|
|
||||||
QPMS README
|
QPMS README
|
||||||
===========
|
===========
|
||||||
|
|
||||||
[QPMS][homepage] (standing for QPMS Photonic Multiple Scattering)
|
QPMS is a toolkit for frequency-domain simulations of photonic systems
|
||||||
is a toolkit for frequency-domain simulations of photonic systems
|
|
||||||
consisting of compact objects (particles) inside a homogeneous medium. Scattering
|
consisting of compact objects (particles) inside a homogeneous medium. Scattering
|
||||||
properties of the individual particles are described by their T-matrices
|
properties of the individual particles are described by their T-matrices
|
||||||
(which can be obtained using one of the built-in generators or
|
(which can be obtained e.g. with the `scuff-tmatrix` tool from
|
||||||
e.g. with the `scuff-tmatrix` tool from
|
|
||||||
the [SCUFF-EM] suite).
|
the [SCUFF-EM] suite).
|
||||||
|
|
||||||
QPMS handles the multiple scattering of electromagnetic radiation between
|
QPMS handles the multiple scattering of electromagnetic radiation between
|
||||||
|
@ -16,39 +12,26 @@ the particles. The system can consist either of a finite number of particles
|
||||||
or an infinite number of periodically arranged lattices (with finite number
|
or an infinite number of periodically arranged lattices (with finite number
|
||||||
of particles in a single unit cell).
|
of particles in a single unit cell).
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
||||||
Finite systems
|
Finite systems
|
||||||
--------------
|
--------------
|
||||||
* Computing multipole excitations and fields scattered from nanoparticle
|
* Computing multipole excitations *and fields (TODO)* scattered from nanoparticle
|
||||||
clusters illuminated by plane, spherical or *cylindrical (TODO)* waves.
|
clusters illuminated by plane, spherical or *cylindrical (TODO)* waves.
|
||||||
* Finding eigenmodes (optical resonances).
|
* Finding eigenmodes.
|
||||||
* Calculating cross sections.
|
* *Calculating cross sections (TODO).*
|
||||||
* Reducing numerical complexity of the computations by exploiting
|
* Reducing numerical complexity of the computations by exploiting
|
||||||
symmetries of the cluster (decomposition to irreducible representations).
|
symmetries of the cluster (decomposition to irreducible representations).
|
||||||
|
|
||||||
|
|
||||||
Infinite systems (lattices)
|
Infinite systems (lattices)
|
||||||
---------------------------
|
---------------------------
|
||||||
* 2D-periodic systems with arbitrary unit cell geometry supported. (TODO 1D and 3D.)
|
* 2D-periodic systems supported. (TODO 1D and 3D.)
|
||||||
* Computing multipole excitations and fields scattered from nanoparticle
|
* *Calculation of transmission and reflection properties (TODO).*
|
||||||
* Finding eigenmodes and calculating dispersion relations.
|
* Finding eigenmodes and calculating dispersion relations.
|
||||||
* Calculation of the scattered fields.
|
* *Calculation of far-field radiation patterns of an excited array (TODO).*
|
||||||
* *Calculation of total transmission and reflection properties (TODO).*
|
* Reducing numerical complexity of the computations by exploiting
|
||||||
* *Reducing numerical complexity of the computations by exploiting
|
symmetries of the lattice (decomposition to irreducible representations).
|
||||||
symmetries of the lattice (decomposition to irreducible representations) (in development).*
|
|
||||||
|
|
||||||
|
|
||||||
Getting the code
|
|
||||||
================
|
|
||||||
|
|
||||||
The codebase is available at the main upstream public repository
|
|
||||||
<https://repo.or.cz/qpms.git> or any of the [maintained mirrors][MIRRORS].
|
|
||||||
Just clone the repository with `git` and proceed to the installation instructions
|
|
||||||
below.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
@ -64,16 +47,7 @@ you can [get the source and compile it yourself][GSL].
|
||||||
|
|
||||||
You also need a fresh enough version of [cmake][].
|
You also need a fresh enough version of [cmake][].
|
||||||
|
|
||||||
QPMS uses a C version of the Amos library for calculating Bessel function
|
After GSL is installed, you can install qpms to your local python library using
|
||||||
from a submodule. Before proceeding with running `cmake`, the submodules
|
|
||||||
need to be downloaded first (in the QPMS source root directory):
|
|
||||||
|
|
||||||
```{.sh}
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
```
|
|
||||||
|
|
||||||
After GSL is installed and submodules updated, you can install qpms to your local python library using
|
|
||||||
|
|
||||||
```{.sh}
|
```{.sh}
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=${YOUR_PREFIX} .
|
cmake -DCMAKE_INSTALL_PREFIX=${YOUR_PREFIX} .
|
||||||
|
@ -92,21 +66,13 @@ Special care might need to be taken when installing QPMS in cluster environments
|
||||||
Specific installation instructions for Aalto University's Triton cluster
|
Specific installation instructions for Aalto University's Triton cluster
|
||||||
can be found in a [separate document][TRITON-README].
|
can be found in a [separate document][TRITON-README].
|
||||||
|
|
||||||
Instructions for installation on Android-based devices are
|
|
||||||
in [another document][INSTALL-ANDROID].
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
|
||||||
[QPMS documentation][homepage] is a work in progress. Most of the newer code
|
Documentation of QPMS is a work in progress. Most of the newer code
|
||||||
is documented using [doxygen][] comments. Documentation generated for the
|
is documented using [doxygen][] comments. To build the documentation, just run
|
||||||
upstream version is hosted on the QPMS homepage <https://qpms.necada.org>.
|
|
||||||
|
|
||||||
To build the documentation yourself,
|
|
||||||
just run
|
|
||||||
`doxygen`
|
`doxygen`
|
||||||
in the QPMS source root directory; the documentation will then be found in
|
in the root directory; the documentation will then be found in
|
||||||
`docs/html/index.html`.
|
`docs/html/index.html`.
|
||||||
|
|
||||||
Of course, the prerequisite of this is having doxygen installed.
|
Of course, the prerequisite of this is having doxygen installed.
|
||||||
|
@ -118,77 +84,14 @@ under root.
|
||||||
Tutorials
|
Tutorials
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
* [Infinite system (lattice) tutorial][tutorial-infinite]
|
||||||
* [Finite system tutorial][tutorial-finite]
|
* [Finite system tutorial][tutorial-finite]
|
||||||
|
|
||||||
See also the examples directory in the source repository.
|
|
||||||
|
|
||||||
|
|
||||||
Command line utilities
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
* [Overview of the Python command line utilities][cliutils]
|
|
||||||
|
|
||||||
|
|
||||||
Acknowledgments
|
|
||||||
================
|
|
||||||
|
|
||||||
This software has been developed in the [Quantum Dynamics research group][QD],
|
|
||||||
Aalto University, Finland. If you use the code in your work, please cite
|
|
||||||
**M. Nečada and P. Törmä, Multiple-scattering T-matrix simulations for nanophotonics: symmetries and periodic lattices, [arXiv: 2006.12968][lepaper] (2020)**
|
|
||||||
in your publications, presentations, and similar.
|
|
||||||
|
|
||||||
Please also have a look at other publications by the group
|
|
||||||
(google scholar Päivi Törmä), they may be useful for your work as well.
|
|
||||||
|
|
||||||
|
|
||||||
Bug reports
|
|
||||||
===========
|
|
||||||
|
|
||||||
If you believe that some parts of QPMS behave incorrectly, please mail
|
|
||||||
a bug report to [marek@necada.org][authormail]. To ensure that your message is not
|
|
||||||
considered spam, please start the subject line with `QPMS`.
|
|
||||||
|
|
||||||
If you were able to fix a bug yourself, please include the patch as well,
|
|
||||||
see below.
|
|
||||||
|
|
||||||
|
|
||||||
Contributions
|
|
||||||
=============
|
|
||||||
|
|
||||||
Contributions to QPMS are welcome, be it bug fixes, improvements to the
|
|
||||||
documentation, code quality, or new features.
|
|
||||||
|
|
||||||
You can send patches prepared using the
|
|
||||||
[`git format-patch`](https://git-scm.com/docs/git-format-patch) tool
|
|
||||||
to [marek@necada.org][authormail].
|
|
||||||
|
|
||||||
If you plan to contribute with major changes to the codebase, it is
|
|
||||||
recommended to discuss that first (see the contact information below).
|
|
||||||
|
|
||||||
|
|
||||||
Contact & discussion
|
|
||||||
====================
|
|
||||||
|
|
||||||
You can contact the main author e.g. via [e-mail][authormail]
|
|
||||||
or [Telegram](https://t.me/necadam).
|
|
||||||
|
|
||||||
You are also warmly welcome to the [QPMS user chat][telegramchat]
|
|
||||||
in Telegram!
|
|
||||||
|
|
||||||
|
|
||||||
[homepage]: https://qpms.necada.org
|
|
||||||
[SCUFF-EM]: https://homerreid.github.io/scuff-em-documentation/
|
[SCUFF-EM]: https://homerreid.github.io/scuff-em-documentation/
|
||||||
[OpenBLAS]: https://www.openblas.net/
|
[OpenBLAS]: https://www.openblas.net/
|
||||||
[GSL]: https://www.gnu.org/software/gsl/
|
[GSL]: https://www.gnu.org/software/gsl/
|
||||||
[cmake]: https://cmake.org
|
[cmake]: https://cmake.org
|
||||||
[TRITON-README]: README.Triton.md
|
[TRITON-README]: README.Triton.md
|
||||||
[INSTALL-ANDROID]: notes/INSTALL_ANDROID.md
|
|
||||||
[tutorial-finite]: finite_systems.md
|
[tutorial-finite]: finite_systems.md
|
||||||
[tutorial-infinite]: lattices.md
|
[tutorial-infinite]: lattices.md
|
||||||
[doxygen]: http://doxygen.nl/
|
[doxygen]: http://doxygen.nl/
|
||||||
[QD]: https://www.aalto.fi/en/department-of-applied-physics/quantum-dynamics-qd
|
|
||||||
[lepaper]: https://arxiv.org/abs/2006.12968
|
|
||||||
[telegramchat]: https://t.me/QPMScattering
|
|
||||||
[authormail]: mailto:marek@necada.org
|
|
||||||
[cliutils]: CLIUTILS.md
|
|
||||||
[MIRRORS]: MIRRORS.md
|
|
||||||
|
|
30
TODO.md
30
TODO.md
|
@ -1,12 +1,11 @@
|
||||||
TODO list before 1.0 release
|
TODO list before public release
|
||||||
============================
|
===============================
|
||||||
|
|
||||||
- Tests!
|
- Tests!
|
||||||
- Docs!
|
- Docs!
|
||||||
- Cross section calculations. (Done in some Python scripts.)
|
- Cross section calculations.
|
||||||
- Field calculations. (Partly done, needs more testing.)
|
- Field calculations.
|
||||||
* Also test periodic vs. nonperiodic consistence (big finite lattice + absorbing medium vs. infinite lattice + absorbing medium).
|
- Complex frequencies, n's, k's.
|
||||||
- Complex frequencies, n's, k's. (Mostly done.)
|
|
||||||
- Transforming point (meta)generators.
|
- Transforming point (meta)generators.
|
||||||
- Check whether moble's quaternions and my
|
- Check whether moble's quaternions and my
|
||||||
quaternions give the same results in tmatrices.py
|
quaternions give the same results in tmatrices.py
|
||||||
|
@ -25,12 +24,8 @@ TODO list before 1.0 release
|
||||||
* As a description of a T-matrix / particle metadata.
|
* As a description of a T-matrix / particle metadata.
|
||||||
- Nice CLI for all general enough utilities.
|
- Nice CLI for all general enough utilities.
|
||||||
- Remove legacy code.
|
- Remove legacy code.
|
||||||
- Split `qpms_c.pyx`.
|
- Split qpms_c.pyx.
|
||||||
- Reduce compiler warnings.
|
- Reduce compiler warnings.
|
||||||
- Serialisation (saving, loading) of `ScatteringSystem` and other structures.
|
|
||||||
- Python exceptions instead of hard crashes in the C library where possible.
|
|
||||||
- Scatsystem init sometimes fail due to rounding errors and hardcoded absolute tolerance
|
|
||||||
in the `qpms_tmatrix_isclose()` call.
|
|
||||||
- Prefix all identifiers. Maybe think about a different prefix than qpms?
|
- Prefix all identifiers. Maybe think about a different prefix than qpms?
|
||||||
- Consistent indentation and style overall.
|
- Consistent indentation and style overall.
|
||||||
- Rewrite the parallelized translation matrix, mode problem matrix generators
|
- Rewrite the parallelized translation matrix, mode problem matrix generators
|
||||||
|
@ -41,16 +36,3 @@ Nice but less important features
|
||||||
|
|
||||||
- Static, thread-safe caches of constant coefficients + API without the current "calculators".
|
- Static, thread-safe caches of constant coefficients + API without the current "calculators".
|
||||||
|
|
||||||
|
|
||||||
Optimisations
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- Leaving out the irrelevant elements if a "rectangular" block of the translations matrix is needed.
|
|
||||||
- Ewald sums with "non-parallel" shifts (are about 20 times slower than the purely parallel ones).
|
|
||||||
- Reusing intermediate results (profiling needed)
|
|
||||||
* Bessel, Legendre functions (see also branch `finite_lattice_speedup`)
|
|
||||||
* Lattice points (sorting and scaling)
|
|
||||||
* Γ/Δ functions (for periodic lattices)
|
|
||||||
- More parallelisation.
|
|
||||||
- Possibly pre-calculation of the (precise) coefficients in Bessel and Legendre functions (using gmp)
|
|
||||||
- Asymptotic approximations of the Bessel functions for far fields.
|
|
||||||
|
|
30
amos/camos.h
30
amos/camos.h
|
@ -1,30 +0,0 @@
|
||||||
#ifndef CAMOS_H_
|
|
||||||
#define CAMOS_H_
|
|
||||||
#include "amos.h"
|
|
||||||
|
|
||||||
// TODO what about all the INTEGER_t and DOUBLE_PRECISION_t?
|
|
||||||
|
|
||||||
static inline int camos_zbesh(double zr, double zi, double fnu, int kode, int m,
|
|
||||||
int n, double *cyr, double *cyi, int *nz) {
|
|
||||||
int ierr;
|
|
||||||
amos_zbesh(&zr, &zi, &fnu, &kode, &m, &n, cyr, cyi, nz, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int camos_zbesj(double zr, double zi, double fnu, int kode, int n, double *cyr,
|
|
||||||
double *cyi, int *nz) {
|
|
||||||
int ierr;
|
|
||||||
double cwrkr[n], cwrki[n];
|
|
||||||
amos_zbesj(&zr, &zi, &fnu, &kode, &n, cyr, cyi, nz, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int camos_zbesy(double zr, double zi, double fnu, int kode, int n, double *cyr,
|
|
||||||
double *cyi, int *nz, double *cwrkr, double *cwrki) {
|
|
||||||
int ierr;
|
|
||||||
amos_zbesy(&zr, &zi, &fnu, &kode, &n, cyr, cyi, nz, cwrkr, cwrki, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CAMOS_H_
|
|
1
camos
1
camos
|
@ -1 +0,0 @@
|
||||||
Subproject commit 19e7ae82e7e0b436bd273557a87d288f8f338221
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
DP=Dockerfile_parts
|
|
||||||
# "Build environment" Dockerfiles
|
|
||||||
cat >Dockerfile.benv.debian.bnl ${DP}/00_common.debian ${DP}/01_numlibs.built
|
|
||||||
cat >Dockerfile.benv.debian.pnl ${DP}/00_common.debian ${DP}/01_numlibs.debian.pkgd
|
|
||||||
cat >Dockerfile.benv.alpine.bnl ${DP}/00_common.alpine ${DP}/01_numlibs.built
|
|
||||||
cat >Dockerfile.benv.alpine.pnl ${DP}/00_common.alpine ${DP}/01_numlibs.alpine.pkgd
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
docker build -t qpms/buildenv/debian/builtnumlib -f Dockerfile.benv.debian.bnl .
|
|
||||||
docker build -t qpms/buildenv/debian/pkgdnumlib -f Dockerfile.benv.debian.pnl .
|
|
||||||
docker build -t qpms/buildenv/alpine/builtnumlib -f Dockerfile.benv.alpine.bnl .
|
|
||||||
docker build -t qpms/buildenv/alpine/pkgdnumlib -f Dockerfile.benv.alpine.pnl .
|
|
|
@ -1,5 +0,0 @@
|
||||||
FROM alpine:latest AS commondeps
|
|
||||||
RUN apk update \
|
|
||||||
&& apk add cmake python3-dev py3-pip gcc g++ wget git make libc-dev bc \
|
|
||||||
&& adduser -D qpmsbuild
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
FROM debian:stable AS commondeps
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get -y install --no-install-recommends build-essential cmake python3 python3-pip git wget python3-dev bc \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& useradd -m qpmsbuild
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
FROM commondeps AS numlibs
|
|
||||||
# openblas-dev adds gfortran :(
|
|
||||||
RUN apk add openblas-dev gsl-dev
|
|
|
@ -1,16 +0,0 @@
|
||||||
FROM commondeps AS buildopenblas
|
|
||||||
USER qpmsbuild
|
|
||||||
RUN cd && git clone --depth 1 https://github.com/xianyi/OpenBLAS.git \
|
|
||||||
&& cd OpenBLAS && make \
|
|
||||||
&& make install PREFIX=$HOME/.local/ \
|
|
||||||
&& make clean \
|
|
||||||
&& cd .. && rm -rf OpenBLAS
|
|
||||||
|
|
||||||
FROM buildopenblas AS numlibs
|
|
||||||
USER qpmsbuild
|
|
||||||
RUN cd && wget https://ftp.gnu.org/gnu/gsl/gsl-latest.tar.gz \
|
|
||||||
&& tar xf gsl-latest.tar.gz \
|
|
||||||
&& cd $( tar tf gsl-latest.tar.gz | head -n 1 ) \
|
|
||||||
&& ./configure --prefix=$HOME/.local \
|
|
||||||
&& make && make install && make clean \
|
|
||||||
&& cd .. && rm -rf $OLDPWD gsl-latest.tar.gz
|
|
|
@ -1,4 +0,0 @@
|
||||||
FROM commondeps AS numlibs
|
|
||||||
RUN apt-get -y install --no-install-recommends libopenblas-dev libgsl-dev liblapacke-dev \
|
|
||||||
&& apt-get clean
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
FROM numlibs AS buildqpms
|
|
||||||
USER qpmsbuild
|
|
||||||
ENV LD_LIBRARY_PATH /home/qpmsbuild/.local/lib
|
|
||||||
ENV LIBRARY_PATH /home/qpmsbuild/.local/lib
|
|
||||||
ENV C_INCLUDE_PATH /home/qpmsbuild/.local/include
|
|
||||||
RUN cd && git clone --depth 1 https://repo.or.cz/qpms.git \
|
|
||||||
&& cd qpms && git submodule init && git submodule update
|
|
||||||
RUN cd ~/qpms && cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local . \
|
|
||||||
&& make \
|
|
||||||
&& make install
|
|
||||||
RUN cd ~/qpms && python3 setup.py install --user
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../.drone.yml
|
|
|
@ -1,284 +0,0 @@
|
||||||
# - Returns a version string from Git
|
|
||||||
#
|
|
||||||
# These functions force a re-configure on each git commit so that you can
|
|
||||||
# trust the values of the variables in your build system.
|
|
||||||
#
|
|
||||||
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
|
|
||||||
#
|
|
||||||
# Returns the refspec and sha hash of the current head revision
|
|
||||||
#
|
|
||||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe on the source tree, and adjusting
|
|
||||||
# the output so that it tests false if an error occurs.
|
|
||||||
#
|
|
||||||
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe on the working tree (--dirty option),
|
|
||||||
# and adjusting the output so that it tests false if an error occurs.
|
|
||||||
#
|
|
||||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe --exact-match on the source tree,
|
|
||||||
# and adjusting the output so that it tests false if there was no exact
|
|
||||||
# matching tag.
|
|
||||||
#
|
|
||||||
# git_local_changes(<var>)
|
|
||||||
#
|
|
||||||
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
|
|
||||||
# Uses the return code of "git diff-index --quiet HEAD --".
|
|
||||||
# Does not regard untracked files.
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
#
|
|
||||||
# Copyright 2009-2013, Iowa State University.
|
|
||||||
# Copyright 2013-2020, Ryan Pavlik
|
|
||||||
# Copyright 2013-2020, Contributors
|
|
||||||
# SPDX-License-Identifier: BSL-1.0
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
if(__get_git_revision_description)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(__get_git_revision_description YES)
|
|
||||||
|
|
||||||
# We must run the following at "include" time, not at function call time,
|
|
||||||
# to find the path to this module rather than the path to a calling list file
|
|
||||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|
||||||
|
|
||||||
# Function _git_find_closest_git_dir finds the next closest .git directory
|
|
||||||
# that is part of any directory in the path defined by _start_dir.
|
|
||||||
# The result is returned in the parent scope variable whose name is passed
|
|
||||||
# as variable _git_dir_var. If no .git directory can be found, the
|
|
||||||
# function returns an empty string via _git_dir_var.
|
|
||||||
#
|
|
||||||
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
|
||||||
# neither foo nor bar contain a file/directory .git. This wil return
|
|
||||||
# C:/bla/.git
|
|
||||||
#
|
|
||||||
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
|
||||||
set(cur_dir "${_start_dir}")
|
|
||||||
set(git_dir "${_start_dir}/.git")
|
|
||||||
while(NOT EXISTS "${git_dir}")
|
|
||||||
# .git dir not found, search parent directories
|
|
||||||
set(git_previous_parent "${cur_dir}")
|
|
||||||
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
|
|
||||||
if(cur_dir STREQUAL git_previous_parent)
|
|
||||||
# We have reached the root directory, we are not in git
|
|
||||||
set(${_git_dir_var}
|
|
||||||
""
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(git_dir "${cur_dir}/.git")
|
|
||||||
endwhile()
|
|
||||||
set(${_git_dir_var}
|
|
||||||
"${git_dir}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(get_git_head_revision _refspecvar _hashvar)
|
|
||||||
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
|
|
||||||
|
|
||||||
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
|
|
||||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
|
|
||||||
else()
|
|
||||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
|
|
||||||
endif()
|
|
||||||
if(NOT "${GIT_DIR}" STREQUAL "")
|
|
||||||
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
|
|
||||||
"${GIT_DIR}")
|
|
||||||
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
|
|
||||||
# We've gone above the CMake root dir.
|
|
||||||
set(GIT_DIR "")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if("${GIT_DIR}" STREQUAL "")
|
|
||||||
set(${_refspecvar}
|
|
||||||
"GITDIR-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
set(${_hashvar}
|
|
||||||
"GITDIR-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Check if the current source dir is a git submodule or a worktree.
|
|
||||||
# In both cases .git is a file instead of a directory.
|
|
||||||
#
|
|
||||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
|
||||||
# The following git command will return a non empty string that
|
|
||||||
# points to the super project working tree if the current
|
|
||||||
# source dir is inside a git submodule.
|
|
||||||
# Otherwise the command will return an empty string.
|
|
||||||
#
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" rev-parse
|
|
||||||
--show-superproject-working-tree
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT "${out}" STREQUAL "")
|
|
||||||
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
|
|
||||||
file(READ ${GIT_DIR} submodule)
|
|
||||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
|
|
||||||
${submodule})
|
|
||||||
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
|
|
||||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
|
||||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
|
|
||||||
ABSOLUTE)
|
|
||||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
|
||||||
else()
|
|
||||||
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
|
|
||||||
file(READ ${GIT_DIR} worktree_ref)
|
|
||||||
# The .git directory contains a path to the worktree information directory
|
|
||||||
# inside the parent git repo of the worktree.
|
|
||||||
#
|
|
||||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
|
|
||||||
${worktree_ref})
|
|
||||||
string(STRIP ${git_worktree_dir} git_worktree_dir)
|
|
||||||
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
|
|
||||||
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
|
||||||
endif()
|
|
||||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
|
||||||
if(NOT EXISTS "${GIT_DATA}")
|
|
||||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
|
||||||
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
|
|
||||||
|
|
||||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
|
||||||
"${GIT_DATA}/grabRef.cmake" @ONLY)
|
|
||||||
include("${GIT_DATA}/grabRef.cmake")
|
|
||||||
|
|
||||||
set(${_refspecvar}
|
|
||||||
"${HEAD_REF}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
set(${_hashvar}
|
|
||||||
"${HEAD_HASH}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_describe _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
get_git_head_revision(refspec hash)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
if(NOT hash)
|
|
||||||
set(${_var}
|
|
||||||
"HEAD-HASH-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TODO sanitize
|
|
||||||
#if((${ARGN}" MATCHES "&&") OR
|
|
||||||
# (ARGN MATCHES "||") OR
|
|
||||||
# (ARGN MATCHES "\\;"))
|
|
||||||
# message("Please report the following error to the project!")
|
|
||||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT res EQUAL 0)
|
|
||||||
set(out "${out}-${res}-NOTFOUND")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_describe_working_tree _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT res EQUAL 0)
|
|
||||||
set(out "${out}-${res}-NOTFOUND")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_get_exact_tag _var)
|
|
||||||
git_describe(out --exact-match ${ARGN})
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_local_changes _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
get_git_head_revision(refspec hash)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
if(NOT hash)
|
|
||||||
set(${_var}
|
|
||||||
"HEAD-HASH-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(res EQUAL 0)
|
|
||||||
set(${_var}
|
|
||||||
"CLEAN"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${_var}
|
|
||||||
"DIRTY"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
|
@ -1,43 +0,0 @@
|
||||||
#
|
|
||||||
# Internal file for GetGitRevisionDescription.cmake
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
# Iowa State University HCI Graduate Program/VRAC
|
|
||||||
#
|
|
||||||
# Copyright 2009-2012, Iowa State University
|
|
||||||
# Copyright 2011-2015, Contributors
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
# SPDX-License-Identifier: BSL-1.0
|
|
||||||
|
|
||||||
set(HEAD_HASH)
|
|
||||||
|
|
||||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
|
||||||
|
|
||||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
|
||||||
if(HEAD_CONTENTS MATCHES "ref")
|
|
||||||
# named branch
|
|
||||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
|
||||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
|
||||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
else()
|
|
||||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
|
||||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
|
||||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
|
||||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# detached HEAD
|
|
||||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT HEAD_HASH)
|
|
||||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
|
||||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
|
||||||
endif()
|
|
|
@ -1,23 +0,0 @@
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
from qpms import TMatrixGenerator, BaseSpec, eV, hbar
|
|
||||||
import numpy as np
|
|
||||||
import sys
|
|
||||||
|
|
||||||
errors = 0
|
|
||||||
|
|
||||||
def tmg_diagonal_fun(tmatrix, omega):
|
|
||||||
'''
|
|
||||||
Example of a python function used as a custom T-matrix generator
|
|
||||||
|
|
||||||
It receives a CTMatrix argument with pre-filled BaseSpec
|
|
||||||
(in tmatrix.spec) and angular frequency.
|
|
||||||
|
|
||||||
It has to fill in the T-matrix elements tmatrix[...]
|
|
||||||
(a numpy array of shape (len(tmatrix.spec),len(tmatrix.spec)))
|
|
||||||
and return zero (on success) or other integral value on error.
|
|
||||||
|
|
||||||
Note that this in justa an example of using the API,
|
|
||||||
not supposed to be anything physical.
|
|
||||||
'''
|
|
||||||
l = tmatrix.spec.l()
|
|
||||||
tmatrix[...] = np.diag(1./l**2)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Wrap the function as an actual TMatrixGenerator
|
|
||||||
tmg_diagonal = TMatrixGenerator(tmg_diagonal_fun)
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax=2)
|
|
||||||
|
|
||||||
tmatrix = tmg_diagonal(bspec, (2.0+.01j) * eV/hbar)
|
|
||||||
|
|
||||||
errors += np.sum(tmatrix[...] != np.diag(1./bspec.l()**2))
|
|
||||||
|
|
||||||
sys.exit(errors)
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
echo 'scale=20;pi=3.14159265358979323846;' > bc_env
|
|
||||||
export BC_ENV_ARGS="bc_env"
|
|
||||||
|
|
||||||
# We put those into bc, which does not understant exponential notation
|
|
||||||
SEPARATION_nm=576
|
|
||||||
|
|
||||||
# Particle positions within unit cell
|
|
||||||
export P1X_nm=0
|
|
||||||
export P1Y_nm=$(bc <<< ${SEPARATION_nm}/2)
|
|
||||||
export P2X_nm=0
|
|
||||||
export P2Y_nm=-$P1Y_nm
|
|
||||||
|
|
||||||
# Lattice vectors
|
|
||||||
export A1X_nm=$(bc <<< ${SEPARATION_nm}'*sqrt(3)')
|
|
||||||
export A1Y_nm=0
|
|
||||||
export A2X_nm=$(bc <<< ${SEPARATION_nm}'*sqrt(3)/2')
|
|
||||||
export A2Y_nm=$(bc <<< ${SEPARATION_nm}'*3/2')
|
|
||||||
|
|
||||||
# Reciprocal lattice vectors
|
|
||||||
export B1X_nmi=$(bc <<< '2*pi/sqrt(3)/'${SEPARATION_nm})
|
|
||||||
export B1Y_nmi=$(bc <<< '-2*pi/3/'${SEPARATION_nm})
|
|
||||||
export B2X_nmi=0
|
|
||||||
export B2Y_nmi=$(bc <<< '4*pi/3/'${SEPARATION_nm})
|
|
||||||
|
|
||||||
# a K-point coordinates
|
|
||||||
export KPOINTX_nmi=$(bc <<< '4*pi/3/sqrt(3)'/${SEPARATION_nm})
|
|
||||||
export KPOINTY_nmi=0.0 #$(bc <<< '4*pi/3/sqrt(3)'/${SEPARATION_nm})
|
|
||||||
|
|
||||||
# a M-point coordinates
|
|
||||||
export MPOINTX_nmi=0.0
|
|
||||||
export MPOINTY_nmi=$(bc <<< '2*pi/3'/${SEPARATION_nm})
|
|
||||||
|
|
||||||
|
|
||||||
export RADIUS_nm=50
|
|
||||||
export HEIGHT_nm=50
|
|
||||||
export METAL=Au
|
|
||||||
export BG_REFINDEX=1.52
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-d -3 \
|
|
||||||
-t 0.01 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-F 1.3 0.001 1.5 \
|
|
||||||
-P
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 1.50 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e13 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.00 0.01 1.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${MPOINTX_nmi}*${coeff})e9 s$(bc <<< ${MPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.3 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 2 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 2.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d -$bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
scale=20;pi=3.14159265358979323846;
|
|
|
@ -1,37 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Common parameters for a rectangular array
|
|
||||||
# N.B. We put those into bc, which does not understant exponential notation
|
|
||||||
|
|
||||||
export PX_nm=375
|
|
||||||
export PY_nm=375
|
|
||||||
export RADIUS_nm=30
|
|
||||||
export HEIGHT_nm=30
|
|
||||||
export METAL=Ag
|
|
||||||
export BG_REFINDEX=1.52
|
|
||||||
|
|
||||||
|
|
||||||
# Setup bc
|
|
||||||
|
|
||||||
echo 'scale=20;pi=3.14159265358979323846;' > bc_env
|
|
||||||
export BC_ENV_ARGS="bc_env"
|
|
||||||
|
|
||||||
|
|
||||||
# We have only one particle per unit cell here
|
|
||||||
export P1X_nm=0
|
|
||||||
export P1Y_nm=0
|
|
||||||
|
|
||||||
|
|
||||||
# Lattice vectors (for the general scripts)
|
|
||||||
export A1X_nm=${PX_nm}
|
|
||||||
export A1Y_nm=0
|
|
||||||
export A2X_nm=0
|
|
||||||
export A2Y_nm=${PY_nm}
|
|
||||||
|
|
||||||
# Reciprocal lattice vectors
|
|
||||||
export B1X_nmi=$(bc <<< '1/'${PX_nm})
|
|
||||||
export B1Y_nmi=0
|
|
||||||
export B2X_nmi=0
|
|
||||||
export B2Y_nmi=$(bc <<< '1/'${PY_nm})
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-d -3 \
|
|
||||||
-t 0.01 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
# try several lMaxes
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k 0 0 \
|
|
||||||
-F 2.001 0.001 2.250 \
|
|
||||||
-P
|
|
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
|
|
||||||
for LMAX in 1 2 3 ; do # try several cutoffs
|
|
||||||
${MISCDIR}/infiniterectlat-k0realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L $LMAX -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-F 2.001 0.001 2.250 \
|
|
||||||
-P
|
|
||||||
done
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 1.50 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e13 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.00 0.01 1.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${MPOINTX_nmi}*${coeff})e9 s$(bc <<< ${MPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.3 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 2 -3 ; do
|
|
||||||
for coeff in $(seq -0.200 0.010 0.200 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${B1X_nmi}*${coeff})e9 s$(bc <<< ${B1Y_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
../modes/00_params.sh
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/infiniterectlat-scatter.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.015:0.015|201" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-f "s2.110:2.230|100" \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 5 5\
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/infiniterectlat-scatter.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=50000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 140 100 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 140x100.npz -O 140x100.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=30000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 100 100 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 100x100.npz -O 100x100.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=50000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 140 140 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 140x140.npz -O 140x140.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 20 20 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.005:0.005|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-P \
|
|
||||||
-f "s2.150:2.180|100" \
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,54 +0,0 @@
|
||||||
# Drude-Lorentz models, with the same constants as in qpms.
|
|
||||||
# Compared to qpms, sign of the imaginary part is swapped here due
|
|
||||||
# to different time-frequency transform convention.
|
|
||||||
|
|
||||||
MATERIAL LDSilver
|
|
||||||
# Electronvolt over reduced Planck's constant; the omegas and gammas
|
|
||||||
# are defined in these units.
|
|
||||||
eh = 1519267460583196.5;
|
|
||||||
omegap = 9.01
|
|
||||||
f0 = 0.84
|
|
||||||
f1 = 0.065
|
|
||||||
f2 = 0.124
|
|
||||||
f3 = 0.111
|
|
||||||
f4 = 0.84
|
|
||||||
f5 = 5.646
|
|
||||||
omega0 = 0.0
|
|
||||||
omega1 = 0.816
|
|
||||||
omega2 = 4.481
|
|
||||||
omega3 = 8.185
|
|
||||||
omega4 = 9.083
|
|
||||||
omega5 = 20.29
|
|
||||||
gamma0 = 0.053
|
|
||||||
gamma1 = 3.886
|
|
||||||
gamma2 = 0.452
|
|
||||||
gamma3 = 0.065
|
|
||||||
gamma4 = 0.916
|
|
||||||
gamma5 = 2.419
|
|
||||||
Eps(w) = f0 * (omegap * eh)^2 / ((omega0 * eh)^2 - w^2 + I * w * gamma0) + f1 * (omegap * eh)^2 / ((omega1 * eh)^2 - w^2 + I * w * gamma1) + f2 * (omegap * eh)^2 / ((omega2 * eh)^2 - w^2 + I * w * gamma2) + f3 * (omegap * eh)^2 / ((omega3 * eh)^2 - w^2 + I * w * gamma3) + f4 * (omegap * eh)^2 / ((omega4 * eh)^2 - w^2 + I * w * gamma4) + f5 * (omegap * eh)^2 / ((omega5 * eh)^2 - w^2 + I * w * gamma5);
|
|
||||||
ENDMATERIAL
|
|
||||||
|
|
||||||
MATERIAL LDGold
|
|
||||||
eh = 1519267460583196.5;
|
|
||||||
omegap = 9.03
|
|
||||||
f0 = 0.76
|
|
||||||
f1 = 0.024
|
|
||||||
f2 = 0.010
|
|
||||||
f3 = 0.071
|
|
||||||
f4 = 0.601
|
|
||||||
f5 = 4.384
|
|
||||||
omega0 = 0.0
|
|
||||||
omega1 = 0.415
|
|
||||||
omega2 = 0.83
|
|
||||||
omega3 = 2.969
|
|
||||||
omega4 = 4.304
|
|
||||||
omega5 = 13.32
|
|
||||||
gamma0 = 0.053
|
|
||||||
gamma1 = 0.241
|
|
||||||
gamma2 = 0.345
|
|
||||||
gamma3 = 0.87
|
|
||||||
gamma4 = 2.494
|
|
||||||
gamma5 = 2.214
|
|
||||||
Eps(w) = f0 * (omegap * eh)^2 / ((omega0 * eh)^2 - w^2 + I * w * gamma0) + f1 * (omegap * eh)^2 / ((omega1 * eh)^2 - w^2 + I * w * gamma1) + f2 * (omegap * eh)^2 / ((omega2 * eh)^2 - w^2 + I * w * gamma2) + f3 * (omegap * eh)^2 / ((omega3 * eh)^2 - w^2 + I * w * gamma3) + f4 * (omegap * eh)^2 / ((omega4 * eh)^2 - w^2 + I * w * gamma4) + f5 * (omegap * eh)^2 / ((omega5 * eh)^2 - w^2 + I * w * gamma5);
|
|
||||||
ENDMATERIAL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
2.0
|
|
||||||
2.1
|
|
||||||
2.2
|
|
||||||
2.3
|
|
||||||
2.4
|
|
|
@ -1,10 +0,0 @@
|
||||||
1.32
|
|
||||||
1.34
|
|
||||||
1.35
|
|
||||||
1.38
|
|
||||||
1.4
|
|
||||||
1.5
|
|
||||||
1.6
|
|
||||||
1.65
|
|
||||||
1.7
|
|
||||||
3.5
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
freqlist_scuff: freqlist_eV
|
|
||||||
../../../../misc/omega_eV2scuff.py -o freqlist_scuff freqlist_eV
|
|
|
@ -1,3 +0,0 @@
|
||||||
1.0
|
|
||||||
1.5
|
|
||||||
2.0
|
|
|
@ -1,62 +0,0 @@
|
||||||
// radius, height in nanometers
|
|
||||||
R=RADIUS/1000.;
|
|
||||||
h=HEIGHT/1000.;
|
|
||||||
|
|
||||||
|
|
||||||
l=ELEMSIZ/1000.;
|
|
||||||
|
|
||||||
// Circle centers
|
|
||||||
Point(1) = { 0, 0, h/2.,l};
|
|
||||||
Point(2) = { 0, 0, -h/2.,l};
|
|
||||||
|
|
||||||
// Upper circle arc limits
|
|
||||||
Point(3) = { R, 0, h/2.,l};
|
|
||||||
Point(4) = { 0, R, h/2.,l};
|
|
||||||
Point(5) = {-R, 0, h/2.,l};
|
|
||||||
Point(6) = { 0, -R, h/2.,l};
|
|
||||||
|
|
||||||
// Upper circle
|
|
||||||
Circle(1) = {3, 1, 4};
|
|
||||||
Circle(2) = {4, 1, 5};
|
|
||||||
Circle(3) = {5, 1, 6};
|
|
||||||
Circle(4) = {6, 1, 3};
|
|
||||||
|
|
||||||
// Lower circle arc limits
|
|
||||||
Point(7) = { R, 0, -h/2.,l};
|
|
||||||
Point(8) = { 0, R, -h/2.,l};
|
|
||||||
Point(9) = {-R, 0, -h/2.,l};
|
|
||||||
Point(10) = { 0, -R, -h/2.,l};
|
|
||||||
|
|
||||||
// Lower circle
|
|
||||||
Circle(5) = { 7, 2, 8};
|
|
||||||
Circle(6) = { 8, 2, 9};
|
|
||||||
Circle(7) = { 9, 2, 10};
|
|
||||||
Circle(8) = {10, 2, 7};
|
|
||||||
|
|
||||||
Line( 9) = {3,7};
|
|
||||||
Line(10) = {4,8};
|
|
||||||
Line(11) = {5,9};
|
|
||||||
Line(12) = {6,10};
|
|
||||||
|
|
||||||
Line Loop(13) = {1, 2, 3, 4};
|
|
||||||
Line Loop(14) = {5, 6, 7, 8};
|
|
||||||
|
|
||||||
Line Loop(15) = {1, 10, -5, -9};
|
|
||||||
Line Loop(16) = {2, 11, -6, -10};
|
|
||||||
Line Loop(17) = {3, 12, -7, -11};
|
|
||||||
Line Loop(18) = {4, 9, -8, -12};
|
|
||||||
|
|
||||||
Ruled Surface(19) = {13};
|
|
||||||
Ruled Surface(20) = {14};
|
|
||||||
Ruled Surface(21) = {15};
|
|
||||||
Ruled Surface(22) = {16};
|
|
||||||
Ruled Surface(23) = {17};
|
|
||||||
Ruled Surface(24) = {18};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Physical Surface(1) = {19,20,21,22,23,24};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/30./g" -e "s/HEIGHT/30./g" -e "s/ELEMSIZ/4./g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r30_h30_fine.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/30./g" -e "s/HEIGHT/30./g" -e "s/ELEMSIZ/7./g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r30_h30.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/30./g" -e "s/HEIGHT/30./g" -e "s/ELEMSIZ/15./g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r30_h30_rough.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/30./g" -e "s/HEIGHT/30./g" -e "s/ELEMSIZ/25./g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r30_h30_veryrough.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/100./g" -e "s/HEIGHT/50./g" -e "s/ELEMSIZ/13.3/g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r100_h50_fine.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/100./g" -e "s/HEIGHT/50./g" -e "s/ELEMSIZ/23.3/g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r100_h50.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/100./g" -e "s/HEIGHT/50./g" -e "s/ELEMSIZ/50./g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r100_h50_rough.msh -2
|
|
||||||
|
|
||||||
sed -e "s/RADIUS/100./g" -e "s/HEIGHT/50./g" -e "s/ELEMSIZ/83.3/g" cylinder.geo.template >tmp.geo \
|
|
||||||
&& gmsh tmp.geo -o cylinder_r100_h50_veryrough.msh -2
|
|
||||||
|
|
||||||
rm tmp.geo
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
//
|
|
||||||
// gmsh geometry specification for a sphere of radius R = RADIUS nm
|
|
||||||
//
|
|
||||||
|
|
||||||
//************************************************************
|
|
||||||
//* input parameters
|
|
||||||
//************************************************************
|
|
||||||
R = RADIUS/1000.; // radius
|
|
||||||
|
|
||||||
//************************************************************
|
|
||||||
//* meshing finenesses ***************************************
|
|
||||||
//************************************************************
|
|
||||||
l3 = ELEMSIZ/1000.; // fineness at north pole
|
|
||||||
l2 = ELEMSIZ/1000.; // fineness at equator
|
|
||||||
l1 = ELEMSIZ/1000.; // fineness at south pole
|
|
||||||
|
|
||||||
//************************************************************
|
|
||||||
//* upper sphere *********************************************
|
|
||||||
//************************************************************
|
|
||||||
Point(1) = { 0 , 0, 0.0, l2};
|
|
||||||
Point(2) = { R, 0, 0.0, l2};
|
|
||||||
Point(3) = { 0 , R, 0.0, l2};
|
|
||||||
Circle(1) = {2,1,3};
|
|
||||||
Point(4) = { -R, 0, 0.0, l2};
|
|
||||||
Point(5) = { 0, -R, 0.0, l2};
|
|
||||||
Circle(2) = {3,1,4};
|
|
||||||
Circle(3) = {4,1,5};
|
|
||||||
Circle(4) = {5,1,2};
|
|
||||||
Point(6) = { 0, 0, 0.0+R, l3};
|
|
||||||
Point(7) = { 0, 0, 0.0-R, l1};
|
|
||||||
Circle(5) = {3,1,6};
|
|
||||||
Circle(6) = {6,1,5};
|
|
||||||
Circle(7) = {5,1,7};
|
|
||||||
Circle(8) = {7,1,3};
|
|
||||||
Circle(9) = {2,1,7};
|
|
||||||
Circle(10) = {7,1,4};
|
|
||||||
Circle(11) = {4,1,6};
|
|
||||||
Circle(12) = {6,1,2};
|
|
||||||
Line Loop(13) = {2,8,-10};
|
|
||||||
Ruled Surface(14) = {13};
|
|
||||||
Line Loop(15) = {10,3,7};
|
|
||||||
Ruled Surface(16) = {15};
|
|
||||||
Line Loop(17) = {-8,-9,1};
|
|
||||||
Ruled Surface(18) = {17};
|
|
||||||
Line Loop(19) = {-11,-2,5};
|
|
||||||
Ruled Surface(20) = {19};
|
|
||||||
Line Loop(21) = {-5,-12,-1};
|
|
||||||
Ruled Surface(22) = {21};
|
|
||||||
Line Loop(23) = {-3,11,6};
|
|
||||||
Ruled Surface(24) = {23};
|
|
||||||
Line Loop(25) = {-7,4,9};
|
|
||||||
Ruled Surface(26) = {25};
|
|
||||||
Line Loop(27) = {-4,12,-6};
|
|
||||||
Ruled Surface(28) = {27};
|
|
||||||
Physical Surface(1) = {28,26,16,14,20,24,22,18};
|
|
||||||
|
|
||||||
//************************************************************
|
|
||||||
//* reference point to get outward-pointing surface normals right
|
|
||||||
//************************************************************
|
|
||||||
Physical Point(1) = {1};
|
|
|
@ -1,65 +0,0 @@
|
||||||
tmatrices: tmatrices_veryrough tmatrices_rough tmatrices_normal tmatrices_fine
|
|
||||||
|
|
||||||
omegalists_scuff: omegalist2_scuff omegalist1_scuff
|
|
||||||
|
|
||||||
omegalist1_scuff: omegalist1_eV
|
|
||||||
../../../misc/omega_eV2scuff.py -o omegalist1_scuff omegalist1_eV
|
|
||||||
|
|
||||||
omegalist2_scuff: omegalist2_eV
|
|
||||||
../../../misc/omega_eV2scuff.py -o omegalist2_scuff omegalist2_eV
|
|
||||||
|
|
||||||
tmatrices_veryrough: cylinderAu_r100_h50_lMax3_veryrough.TMatrix cylinderAg_r30_h30_lMax3_veryrough.TMatrix
|
|
||||||
|
|
||||||
tmatrices_rough: cylinderAu_r100_h50_lMax3_rough.TMatrix cylinderAg_r30_h30_lMax3_rough.TMatrix
|
|
||||||
|
|
||||||
tmatrices_fine: cylinderAu_r100_h50_lMax3_fine.TMatrix cylinderAg_r30_h30_lMax3_fine.TMatrix
|
|
||||||
|
|
||||||
tmatrices_normal: cylinderAu_r100_h50_lMax3.TMatrix cylinderAg_r30_h30_lMax3.TMatrix
|
|
||||||
|
|
||||||
cylinderAu_r100_h50.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r100_h50.msh/' -e 's/__THEMATERIAL__/LDGold/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_veryrough.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r100_h50_veryrough.msh/' -e 's/__THEMATERIAL__/LDGold/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_rough.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r100_h50_rough.msh/' -e 's/__THEMATERIAL__/LDGold/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_fine.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r100_h50_fine.msh/' -e 's/__THEMATERIAL__/LDGold/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAg_r30_h30.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r30_h30.msh/' -e 's/__THEMATERIAL__/LDSilver/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_veryrough.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r30_h30_veryrough.msh/' -e 's/__THEMATERIAL__/LDSilver/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_rough.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r30_h30_rough.msh/' -e 's/__THEMATERIAL__/LDSilver/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_fine.scuffgeo: cylinder.scuffgeo.template
|
|
||||||
sed -e 's/__THEMESHFILE__/cylinder_r30_h30_fine.msh/' -e 's/__THEMATERIAL__/LDSilver/' cylinder.scuffgeo.template > $@
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_lMax3.TMatrix: omegalist1_scuff cylinder_r100_h50.msh cylinderAu_r100_h50.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAu_r100_h50.scuffgeo --OmegaFile omegalist1_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_lMax3_veryrough.TMatrix: omegalist1_scuff cylinder_r100_h50_veryrough.msh cylinderAu_r100_h50_veryrough.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAu_r100_h50_veryrough.scuffgeo --OmegaFile omegalist1_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_lMax3_rough.TMatrix: omegalist1_scuff cylinder_r100_h50_rough.msh cylinderAu_r100_h50_rough.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAu_r100_h50_rough.scuffgeo --OmegaFile omegalist1_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAu_r100_h50_lMax3_fine.TMatrix: omegalist1_scuff cylinder_r100_h50_fine.msh cylinderAu_r100_h50_fine.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAu_r100_h50_fine.scuffgeo --OmegaFile omegalist1_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_lMax3_veryrough.TMatrix: omegalist2_scuff cylinder_r30_h30_veryrough.msh cylinderAg_r30_h30_veryrough.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAg_r30_h30_veryrough.scuffgeo --OmegaFile omegalist2_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_lMax3_rough.TMatrix: omegalist2_scuff cylinder_r30_h30_rough.msh cylinderAg_r30_h30_rough.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAg_r30_h30_rough.scuffgeo --OmegaFile omegalist2_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_lMax3_fine.TMatrix: omegalist2_scuff cylinder_r30_h30_fine.msh cylinderAg_r30_h30_fine.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAg_r30_h30_fine.scuffgeo --OmegaFile omegalist2_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
||||||
|
|
||||||
cylinderAg_r30_h30_lMax3.TMatrix: omegalist2_scuff cylinder_r30_h30.msh cylinderAg_r30_h30.scuffgeo
|
|
||||||
scuff-tmatrix --geometry cylinderAg_r30_h30.scuffgeo --OmegaFile omegalist2_scuff --FileBase $(@:.TMatrix=) --LMax 3
|
|
|
@ -1,7 +0,0 @@
|
||||||
REGION Exterior MATERIAL CONST_EPS_2.3104
|
|
||||||
|
|
||||||
OBJECT TheParticle
|
|
||||||
MESHFILE __THEMESHFILE__
|
|
||||||
MATERIAL __THEMATERIAL__
|
|
||||||
ENDOBJECT
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r100_h50.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r100_h50_fine.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r100_h50_rough.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r100_h50_veryrough.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r30_h30.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r30_h30_fine.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r30_h30_rough.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../shapes/cylinder_r30_h30_veryrough.msh
|
|
|
@ -1 +0,0 @@
|
||||||
../materials/matprop.dat
|
|
|
@ -1 +0,0 @@
|
||||||
../omegalist1_eV
|
|
|
@ -1 +0,0 @@
|
||||||
../omegalist2_eV
|
|
File diff suppressed because one or more lines are too long
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#SBATCH --mem=200
|
|
||||||
#SBATCH -t 30:00
|
|
||||||
#SBATCH -c 4
|
|
||||||
#SBATCH -p short-ivb
|
|
||||||
#SBATCH --array=0-250
|
|
||||||
|
|
||||||
cat $0
|
|
||||||
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
#radii_nm=(`seq 80 1 150`)
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for lMax in $(seq 1 5); do
|
|
||||||
srun rectlat_simple_modes.py -p 580e-9 -m '4+0.7j' -r ${radius_nm}e-9 -k 0 0 --kpi -n 1.52 -L lMax -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points}
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kx=0.0
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for lMax in $(seq 1 5) ; do
|
|
||||||
for radius_nm in $(seq 50 1 300) ; do
|
|
||||||
rectlat_simple_modes.py -p 580e-9 -m 'Au' -r ${radius_nm}e-9 -k $kx 0 --kpi -n 1.52 -L $lMax -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points} --lMax-extend 10
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kx=0.0
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for radius_nm in $(seq 50 1 300) ; do
|
|
||||||
rectlat_simple_modes.py -p 580e-9 -m 'Au' -r ${radius_nm}e-9 -k $kx 0 --kpi -n 1.52 -L 1 -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points}
|
|
||||||
done
|
|
|
@ -1,300 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"%matplotlib inline\n",
|
|
||||||
"import re\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import matplotlib\n",
|
|
||||||
"from matplotlib import pyplot as plt\n",
|
|
||||||
"from scipy.constants import hbar, e as eV, c\n",
|
|
||||||
"eh = eV/hbar\n",
|
|
||||||
"import glob\n",
|
|
||||||
"def ri(z): return (z.real, z.imag)\n",
|
|
||||||
"#m = re.compile(r\"([^_]+)_r([0-9.]+)nm_\")\n",
|
|
||||||
"#removek = re.compile(r\"(k\\([^)]+\\)um-1_)\")\n",
|
|
||||||
"remover = re.compile(r\"r[0-9.]+nm_\")\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"markerdict = {\n",
|
|
||||||
" 4: \"3\",\n",
|
|
||||||
" -4: \"4\",\n",
|
|
||||||
" 3: \"^\",\n",
|
|
||||||
" -3: \"v\",\n",
|
|
||||||
" -2: 'x',\n",
|
|
||||||
" 2: '+',\n",
|
|
||||||
" 1: 's',\n",
|
|
||||||
" -1: 'd',\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"prop_cycle = plt.rcParams['axes.prop_cycle']\n",
|
|
||||||
"colors = prop_cycle.by_key()['color']\n",
|
|
||||||
"colordict = {i: colors[(i+1)] for i in range(-4,8)}\n",
|
|
||||||
"\n",
|
|
||||||
"def markerfun(b):\n",
|
|
||||||
" if b in markerdict.keys():\n",
|
|
||||||
" return markerdict[b]\n",
|
|
||||||
" else: return 'X'\n",
|
|
||||||
"\n",
|
|
||||||
"def colorfun(b):\n",
|
|
||||||
" if (b+1) in colordict.keys():\n",
|
|
||||||
" return colordict[b+1]\n",
|
|
||||||
" else: return colordict[0]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"allfiles=glob.glob('*sph*k(0_0)*.npz')\n",
|
|
||||||
"allgraphs=dict()\n",
|
|
||||||
"for f in allfiles:\n",
|
|
||||||
" base = remover.sub('', f)\n",
|
|
||||||
" if base in allgraphs.keys():\n",
|
|
||||||
" allgraphs[base] += 1\n",
|
|
||||||
" else:\n",
|
|
||||||
" allgraphs[base] = 1\n",
|
|
||||||
"for k in sorted(allgraphs.keys()):\n",
|
|
||||||
" print(k, allgraphs[k])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"ename": "FileNotFoundError",
|
|
||||||
"evalue": "[Errno 2] No such file or directory: 'projectors_D4h_lMax1.npz'",
|
|
||||||
"output_type": "error",
|
|
||||||
"traceback": [
|
|
||||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
||||||
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
|
|
||||||
"\u001b[0;32m<ipython-input-3-0c266089be08>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mlMaxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mlMax\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mlMax\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mlMax\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mlMaxes\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mproj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'projectors_D4h_lMax%d.npz'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mlMax\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mirlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mproj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mproj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mirlabels\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
||||||
"\u001b[0;32m~/.local/lib/python3.7/site-packages/numpy-1.17.3-py3.7-linux-x86_64.egg/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)\u001b[0m\n\u001b[1;32m 426\u001b[0m \u001b[0mown_fid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 427\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 428\u001b[0;31m \u001b[0mfid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mos_fspath\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"rb\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 429\u001b[0m \u001b[0mown_fid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 430\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
||||||
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'projectors_D4h_lMax1.npz'"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"projectors = dict()\n",
|
|
||||||
"projectors_list = dict()\n",
|
|
||||||
"lMaxes = [lMax for lMax in range(1,6)]\n",
|
|
||||||
"for lMax in lMaxes:\n",
|
|
||||||
" proj = np.load('projectors_D4h_lMax%d.npz' % lMax)\n",
|
|
||||||
" irlabels = sorted(proj.keys())\n",
|
|
||||||
" proj = {f: proj[f] for f in irlabels}\n",
|
|
||||||
" proj_list = [proj[irlabels[i]] for i in range(len(proj))]\n",
|
|
||||||
" projectors[lMax] = proj\n",
|
|
||||||
" projectors_list[lMax] = proj_list\n",
|
|
||||||
"globpattern = '*sph_r*_p580nmx580nm_mAu_n1.52_b?2_k(0_0)um-1_L?_cn???.npz'\n",
|
|
||||||
"filenames=glob.glob(globpattern)\n",
|
|
||||||
"plotfilename = 'collected_' + globpattern.replace('*', 'XXX').replace('?', 'X').replace('npz','pdf')\n",
|
|
||||||
"print(filenames[:4], plotfilename)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 41,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#projectors\n",
|
|
||||||
"#glob.glob('cyl_r100nm*L3*3100.npz')\n",
|
|
||||||
"#glob.glob('sph_r100*m5*.npz')\n",
|
|
||||||
"#dat['meta'][()],list(dat.keys())"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 42,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"inpure result detected [1. 0.99999999 1. 0.97991334 0.99999996 0.9999989\n",
|
|
||||||
" 0.99999983 0.99999966 0.99999322 0.99999721 0.99999653] [3.28735741e-04 2.66532534e-05 2.47011478e-05 1.45012420e-01\n",
|
|
||||||
" 2.44785416e-04 7.05405359e-04 1.60203586e-03 1.71245137e-03\n",
|
|
||||||
" 1.03244480e-02 9.18732728e-03 1.18651583e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.99999998 0.99999999 0.99999996 0.96608887\n",
|
|
||||||
" 0.99999852 0.99999397 0.99998951 0.99999912 0.99982435] [2.66223026e-04 2.12357147e-05 3.54211968e-05 1.06651057e-04\n",
|
|
||||||
" 2.79595790e-04 2.41939163e-01 2.17645058e-03 3.41541473e-03\n",
|
|
||||||
" 1.14507609e-02 1.49639498e-02 2.33483138e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.92521572 1. 0.99999627 0.99990293\n",
|
|
||||||
" 0.99946049] [1.59712906e-05 3.60193407e-05 2.48341492e-01 1.21848930e-03\n",
|
|
||||||
" 3.81805601e-03 2.42649228e-02 2.99534246e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.99999998 0.99999961 0.93267685 0.99999964\n",
|
|
||||||
" 0.99999822 0.99921774 0.99995547 0.99997301] [5.22490396e-04 3.01556792e-05 4.88795563e-05 6.29703960e-04\n",
|
|
||||||
" 2.34414238e-01 3.72766210e-03 4.72444059e-03 7.62106094e-02\n",
|
|
||||||
" 6.32796684e-02 5.63231562e-02]\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"plotdata = {}\n",
|
|
||||||
"for file in filenames:\n",
|
|
||||||
" dat = np.load(file, allow_pickle=True)\n",
|
|
||||||
" kx = dat['meta'][()]['k'][0]\n",
|
|
||||||
" radius = dat['meta'][()]['radius']\n",
|
|
||||||
" b = dat['meta'][()]['band_index']\n",
|
|
||||||
" eigvals = dat['eigval']\n",
|
|
||||||
" lMax = dat['meta'][()]['lMax']\n",
|
|
||||||
" residuals = dat['residuals']\n",
|
|
||||||
" ef =dat['empty_freqs']\n",
|
|
||||||
" eigvecs = dat['eigvec']\n",
|
|
||||||
" irweights = []\n",
|
|
||||||
" #for proj in projectors_list[lMax]:\n",
|
|
||||||
" # try:\n",
|
|
||||||
" # irweights.append(np.linalg.norm(np.tensordot(proj, eigvecs, axes=(-1, -1)), axis=0,ord=2) if len(proj) != 0 else np.zeros((len(eigvecs),)))\n",
|
|
||||||
" # except ValueError as err:\n",
|
|
||||||
" # print(proj, len(proj))\n",
|
|
||||||
" # raise err\n",
|
|
||||||
" irweights = np.array(irweights)\n",
|
|
||||||
" #print(irweights)\n",
|
|
||||||
" irweights = np.array([np.linalg.norm(np.tensordot(proj, eigvecs, axes=(-1, -1)), axis=0,ord=2) if len(proj) != 0 else np.zeros((len(eigvecs),)) for proj in projectors_list[lMax]]).T\n",
|
|
||||||
" irclass = np.argmax(irweights, axis=-1)\n",
|
|
||||||
" purities = np.amax(irweights, axis=-1)\n",
|
|
||||||
" if (np.any(purities < 0.98)):\n",
|
|
||||||
" print(\"inpure result detected\", purities, residuals)\n",
|
|
||||||
" #print(purities)\n",
|
|
||||||
" \n",
|
|
||||||
" #for i in range(len(residuals)): \n",
|
|
||||||
" # if residuals[i] < 0.01:\n",
|
|
||||||
" # vec = eigvecs[i]\n",
|
|
||||||
" # for irlabel, proj in projectors.items():\n",
|
|
||||||
" # print(irlabel, np.linalg.norm(np.dot(proj, vec))) #maybe some conj() here?\n",
|
|
||||||
" # print('--->', irlabels[irclass[i]])\n",
|
|
||||||
"\n",
|
|
||||||
" \n",
|
|
||||||
" plotdata[(lMax,radius)] = (eigvals, residuals, b, ef, irclass,)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"fig = plt.figure(figsize=(15,6))\n",
|
|
||||||
"axesR = {}\n",
|
|
||||||
"axesI = {}\n",
|
|
||||||
"for i, lMax in enumerate(lMaxes):\n",
|
|
||||||
" axesR[lMax] = fig.add_subplot(2,len(lMaxes),i+1)\n",
|
|
||||||
" axesR[lMax].set_xlim([50,300])\n",
|
|
||||||
" axesR[lMax].set_ylim([1.25, ef[1]/eh])\n",
|
|
||||||
" axesI[lMax] = fig.add_subplot(2,len(lMaxes),len(lMaxes)+i+1)\n",
|
|
||||||
" axesI[lMax].set_xlim([50,300])\n",
|
|
||||||
" axesI[lMax].set_ylim([-60, 30])\n",
|
|
||||||
" axesR[lMax].set_title('$l_\\max = %d $' % lMax) \n",
|
|
||||||
" axesR[lMax].tick_params(labelbottom=False) \n",
|
|
||||||
" if i == len(lMaxes)//2:\n",
|
|
||||||
" axesI[lMax].set_xlabel(\"Particle base radius / nm\")\n",
|
|
||||||
" if i == 0:\n",
|
|
||||||
" axesR[lMax].set_ylabel('$\\hbar \\Re \\omega / \\mathrm{eV}$')\n",
|
|
||||||
" axesI[lMax].set_ylabel('$\\hbar \\Im \\omega / \\mathrm{meV}$')\n",
|
|
||||||
" else:\n",
|
|
||||||
" axesR[lMax].tick_params(labelleft=False) \n",
|
|
||||||
" axesI[lMax].tick_params(labelleft=False) \n",
|
|
||||||
"\n",
|
|
||||||
"res_thr = 0.005\n",
|
|
||||||
"\n",
|
|
||||||
"ir_labeled=set()\n",
|
|
||||||
"if True:\n",
|
|
||||||
" for (lMax, radius), (eigvals, residuals, b, ef, irclass) in plotdata.items():\n",
|
|
||||||
" for i, (e, res, iri) in enumerate(zip(eigvals, residuals, irclass)):\n",
|
|
||||||
" #if i == 0:\n",
|
|
||||||
" if res < res_thr:# and e.real < 2.14e15:\n",
|
|
||||||
" if iri in ir_labeled: \n",
|
|
||||||
" label=None\n",
|
|
||||||
" else:\n",
|
|
||||||
" ir_labeled.add(iri)\n",
|
|
||||||
" label=irlabels[iri]\n",
|
|
||||||
" axesR[lMax].plot(radius*1e9, e.real/eh, \n",
|
|
||||||
" marker='.',\n",
|
|
||||||
" #marker=markerfun(b),\n",
|
|
||||||
" ms=4, #c=colorfun(b)\n",
|
|
||||||
" c=matplotlib.cm.hsv(iri/9),\n",
|
|
||||||
" #c = colorfun(iri),\n",
|
|
||||||
" label=label,\n",
|
|
||||||
" )\n",
|
|
||||||
" axesI[lMax].plot(radius*1e9, e.imag/eh*1000, \n",
|
|
||||||
" #marker='x', \n",
|
|
||||||
" #c=colorfun(b), \n",
|
|
||||||
" c=matplotlib.cm.hsv(iri/9),#colorfun(iri),\n",
|
|
||||||
" marker='.', #markerfun(b),\n",
|
|
||||||
" ms=4,\n",
|
|
||||||
" #label=label\n",
|
|
||||||
" )\n",
|
|
||||||
"fig.legend(title=\"Irrep\", loc=\"center right\")\n",
|
|
||||||
"#fig.suptitle('$l_\\mathrm{max}=%d$, residual threshold = %g' % (lMax, res_thr) )\n",
|
|
||||||
"fig.savefig(plotfilename)\n",
|
|
||||||
"fig.savefig(plotfilename.replace('pdf', 'png'))\n",
|
|
||||||
"print(plotfilename)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([0. , 1.40635433, 1.98888536, 2.81270865, 3.14470387,\n",
|
|
||||||
" 3.97777072, 4.21906298, 4.44728287])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"ef / eh"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.7.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 4
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
project(Faddeeva VERSION 1.0 LANGUAGES C)
|
|
||||||
|
|
||||||
option(FADDEEVA_BUILD_STATIC "Build Faddeeva as static library" OFF)
|
|
||||||
|
|
||||||
if (FADDEEVA_BUILD_STATIC)
|
|
||||||
add_library(Faddeeva STATIC Faddeeva.h Faddeeva.c Faddeeva.cc)
|
|
||||||
else (FADDEEVA_BUILD_STATIC)
|
|
||||||
add_library(Faddeeva SHARED Faddeeva.c)
|
|
||||||
set_target_properties(Faddeeva PROPERTIES PUBLIC_HEADER "Faddeeva.h")
|
|
||||||
install(TARGETS Faddeeva
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
endif (FADDEEVA_BUILD_STATIC)
|
|
||||||
target_include_directories(Faddeeva PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
/* The Faddeeva.cc file contains macros to let it compile as C code
|
|
||||||
(assuming C99 complex-number support), so just #include it. */
|
|
||||||
#include "Faddeeva.cc"
|
|
2517
faddeeva/Faddeeva.cc
2517
faddeeva/Faddeeva.cc
File diff suppressed because it is too large
Load Diff
|
@ -1,68 +0,0 @@
|
||||||
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Available at: http://ab-initio.mit.edu/Faddeeva
|
|
||||||
|
|
||||||
Header file for Faddeeva.c; see Faddeeva.cc for more information. */
|
|
||||||
|
|
||||||
#ifndef FADDEEVA_H
|
|
||||||
#define FADDEEVA_H 1
|
|
||||||
|
|
||||||
// Require C99 complex-number support
|
|
||||||
#include <complex.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
// compute w(z) = exp(-z^2) erfc(-iz) [ Faddeeva / scaled complex error func ]
|
|
||||||
extern double complex Faddeeva_w(double complex z,double relerr);
|
|
||||||
extern double Faddeeva_w_im(double x); // special-case code for Im[w(x)] of real x
|
|
||||||
|
|
||||||
// Various functions that we can compute with the help of w(z)
|
|
||||||
|
|
||||||
// compute erfcx(z) = exp(z^2) erfc(z)
|
|
||||||
extern double complex Faddeeva_erfcx(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfcx_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erf(z), the error function of complex arguments
|
|
||||||
extern double complex Faddeeva_erf(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erf_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfi(z) = -i erf(iz), the imaginary error function
|
|
||||||
extern double complex Faddeeva_erfi(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfi_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfc(z) = 1 - erf(z), the complementary error function
|
|
||||||
extern double complex Faddeeva_erfc(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfc_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute Dawson(z) = sqrt(pi)/2 * exp(-z^2) * erfi(z)
|
|
||||||
extern double complex Faddeeva_Dawson(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_Dawson_re(double x); // special case for real x
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif // FADDEEVA_H
|
|
|
@ -1,62 +0,0 @@
|
||||||
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Available at: http://ab-initio.mit.edu/Faddeeva
|
|
||||||
|
|
||||||
Header file for Faddeeva.cc; see that file for more information. */
|
|
||||||
|
|
||||||
#ifndef FADDEEVA_HH
|
|
||||||
#define FADDEEVA_HH 1
|
|
||||||
|
|
||||||
#include <complex>
|
|
||||||
|
|
||||||
namespace Faddeeva {
|
|
||||||
|
|
||||||
// compute w(z) = exp(-z^2) erfc(-iz) [ Faddeeva / scaled complex error func ]
|
|
||||||
extern std::complex<double> w(std::complex<double> z,double relerr=0);
|
|
||||||
extern double w_im(double x); // special-case code for Im[w(x)] of real x
|
|
||||||
|
|
||||||
// Various functions that we can compute with the help of w(z)
|
|
||||||
|
|
||||||
// compute erfcx(z) = exp(z^2) erfc(z)
|
|
||||||
extern std::complex<double> erfcx(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfcx(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erf(z), the error function of complex arguments
|
|
||||||
extern std::complex<double> erf(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erf(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfi(z) = -i erf(iz), the imaginary error function
|
|
||||||
extern std::complex<double> erfi(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfi(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfc(z) = 1 - erf(z), the complementary error function
|
|
||||||
extern std::complex<double> erfc(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfc(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute Dawson(z) = sqrt(pi)/2 * exp(-z^2) * erfi(z)
|
|
||||||
extern std::complex<double> Dawson(std::complex<double> z, double relerr=0);
|
|
||||||
extern double Dawson(double x); // special case for real x
|
|
||||||
|
|
||||||
} // namespace Faddeeva
|
|
||||||
|
|
||||||
#endif // FADDEEVA_HH
|
|
BIN
farfield.png
BIN
farfield.png
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
|
@ -1,8 +1,6 @@
|
||||||
Using QPMS library for simulating finite systems
|
Using QPMS library for simulating finite systems
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
*** This tutorial is partly obsolete, the interpolators are no longer the first choice of getting the T-matrices. ***
|
|
||||||
|
|
||||||
The main C API for finite systems is defined in [scatsystem.h][], and the
|
The main C API for finite systems is defined in [scatsystem.h][], and the
|
||||||
most relevant parts are wrapped into python modules. The central data structure
|
most relevant parts are wrapped into python modules. The central data structure
|
||||||
defining the system of scatterers is [qpms_scatsys_t][],
|
defining the system of scatterers is [qpms_scatsys_t][],
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
Using QPMS library for finding modes of 2D-periodic systems
|
||||||
|
===========================================================
|
||||||
|
|
||||||
|
Calculating modes of infinite 2D arrays is now done
|
||||||
|
in several steps (assuming the T-matrices have already
|
||||||
|
been obtained using `scuff-tmatrix` or can be obtained
|
||||||
|
from Lorenz-Mie solution (spherical particles)):
|
||||||
|
|
||||||
|
1. Sampling the *k*, *ω* space.
|
||||||
|
2. Pre-calculating the
|
||||||
|
Ewald-summed translation operators.
|
||||||
|
3. For each *k*, *ω* pair, build the LHS operator
|
||||||
|
for the scattering problem (TODO reference), optionally decomposed
|
||||||
|
into suitable irreducible representation subspaces.
|
||||||
|
4. Evaluating the singular values and finding their minima.
|
||||||
|
|
||||||
|
The steps above may (and will) change as more user-friendly interface
|
||||||
|
will be developed.
|
||||||
|
|
||||||
|
|
||||||
|
Preparation: compile the `ew_gen_kin` utility
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
This will change, but at this point, the lattice-summed
|
||||||
|
translation operators are computed using the `ew_gen_kin`
|
||||||
|
utility located in the `qpms/apps` directory. It has to be built
|
||||||
|
manually like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd qpms/apps
|
||||||
|
c99 -o ew_gen_kin -Wall -I ../.. -I ../../amos/ -O2 -ggdb -DQPMS_VECTORS_NICE_TRANSFORMATIONS -DLATTICESUMS32 2dlattice_ewald.c ../translations.c ../ewald.c ../ewaldsf.c ../gaunt.c ../lattices2d.c ../latticegens.c ../bessel.c -lgsl -lm -lblas ../../amos/libamos.a -lgfortran ../error.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 1: Sampling the *k*, *ω* space
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
`ew_gen_kin` expects a list of (*k_x*, *k_y*)
|
||||||
|
pairs on standard input (separated by whitespaces),
|
||||||
|
the rest is specified via command line arguments.
|
||||||
|
|
||||||
|
So if we want to examine the line between the Г point and the point
|
||||||
|
\f$ k = (0, 10^5\,\mathrm{m}^{-1}) \f$, we can generate an input
|
||||||
|
running
|
||||||
|
```bash
|
||||||
|
for ky in $(seq 0 1e3 1e5); do
|
||||||
|
echo 0 $ky >> klist
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
It also make sense to pre-generate the list of *ω* values,
|
||||||
|
e.g.
|
||||||
|
```bash
|
||||||
|
seq 6.900 0.002 7.3 | sed -e 's/,/./g' > omegalist
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Step 2: Pre-calculating the translation operators
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
`ew_gen_kin` currently uses command-line arguments in
|
||||||
|
an atrocious way with a hard-coded order:
|
||||||
|
```
|
||||||
|
ew_gen_kin outfile b1.x b1.y b2.x b2.y lMax scuffomega refindex npart part0.x part0.y [part1.x part1.y [...]]
|
||||||
|
```
|
||||||
|
where `outfile` specifies the path to the output, `b1` and `b2` are the
|
||||||
|
direct lattice vectors, `lMax` is the multipole degree cutoff,
|
||||||
|
`scuffomega` is the frequency in the units used by `scuff-tmatrix`
|
||||||
|
(TODO specify), `refindex` is the refractive index of the background
|
||||||
|
medium, `npart` number of particles in the unit cell, and `partN` are
|
||||||
|
the positions of these particles inside the unit cell.
|
||||||
|
|
||||||
|
Assuming we have the `ew_gen_kin` binary in our `${PATH}`, we can
|
||||||
|
now run e.g.
|
||||||
|
```bash
|
||||||
|
for omega in $(cat omegalist); do
|
||||||
|
ew_gen_kin $omega 621e-9 0 0 571e-9 3 w_$omega 1.52 1 0 0 < klist
|
||||||
|
done
|
||||||
|
```
|
||||||
|
This pre-calculates the translation operators for a simple (one particle per unit cell)
|
||||||
|
621 nm × 571 nm rectangular lattice inside a medium with refractive index 1.52,
|
||||||
|
up to the octupole (`lMax` = 3) order, yielding one file per frequency.
|
||||||
|
This can take some time and
|
||||||
|
it makes sense to run a parallelised `for`-loop instead; this is a stupid but working
|
||||||
|
way to do it in bash:
|
||||||
|
```bash
|
||||||
|
N=4 # number of parallel processes
|
||||||
|
for omega in $(cat omegalist); do
|
||||||
|
((i=i%N)); ((i++==0)) && wait
|
||||||
|
ew_gen_kin $omega 621e-9 0 0 571e-9 3 w_$omega 1.52 1 0 0 < klist
|
||||||
|
echo $omega # optional, to follow progress
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
When this is done, we convert all the text output files into
|
||||||
|
numpy's binary format in order to speed up loading in the following steps.
|
||||||
|
This is done using the processWfiles_sortnames.py script located in the
|
||||||
|
`misc` directory. Its usage pattern is
|
||||||
|
```
|
||||||
|
processWfiles_sortnames.py npart dest src1 [src2 ...]
|
||||||
|
```
|
||||||
|
where `npart` is the number of particles in the unit cell, `dest`
|
||||||
|
is the destination path for the converted data (this will be
|
||||||
|
a directory), and the remaining arguments are paths to the
|
||||||
|
files generated by `ew_gen_kin`. In the case above, one could use
|
||||||
|
```
|
||||||
|
processWfiles_sortnames.py 1 all w_*
|
||||||
|
```
|
||||||
|
which would create a directory named `all` containing several
|
||||||
|
.npy files.
|
||||||
|
|
||||||
|
|
||||||
|
Steps 3, 4
|
||||||
|
----------
|
||||||
|
|
||||||
|
TODO. For the time being, see e.g. the `SaraRect/dispersions.ipynb` jupyter notebook
|
||||||
|
from the `qpms_ipynotebooks` repository
|
||||||
|
for the remaining steps.
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_longer.TMatrix'
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_new'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
tmatrix = interp(omega)
|
||||||
|
#print(tmatrix.m)
|
||||||
|
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.npz'%(Nx, Ny, omega/eV*hbar, iri,))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.done'%(Nx, Ny, omega/eV*hbar, iri,))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
#print(mm_iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
from pathlib import Path
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
cyr_part_height = 50*nm
|
||||||
|
cyr_part_radius = 50*nm
|
||||||
|
cyr_part_volume = cyr_part_height * np.pi * cyr_part_radius**2
|
||||||
|
eqv_sph_radius = (3/4/np.pi*cyr_part_volume)**(1/3)
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
#tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_cleaned.TMatrix'
|
||||||
|
materialfile = '/home/necadam1/wrkdir/repo/refractiveindex.info-database/database/data/main/Au/Johnson.yml'
|
||||||
|
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
#outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_sph'
|
||||||
|
outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_sph'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
mi = MaterialInterpolator(materialfile)
|
||||||
|
#interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
#tmatrix = interp(omega)
|
||||||
|
tmatrix = CTMatrix.spherical_perm(bspec, eqv_sph_radius, omega, mi(omega), n**2)
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.npz'%(Nx, Ny, omega/eV*hbar, iri))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.done'%(Nx, Ny, omega/eV*hbar, iri))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
radiusfactor = float(sys.argv[5])
|
||||||
|
|
||||||
|
cyr_part_height = 50*nm
|
||||||
|
cyr_part_radius = 50*nm
|
||||||
|
cyr_part_volume = cyr_part_height * np.pi * cyr_part_radius**2
|
||||||
|
eqv_sph_radius = (3/4/np.pi*cyr_part_volume)**(1/3) * radiusfactor
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
#tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_cleaned.TMatrix'
|
||||||
|
materialfile = '/home/necadam1/wrkdir/repo/refractiveindex.info-database/database/data/main/Au/Johnson.yml'
|
||||||
|
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
#outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_sph'
|
||||||
|
outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_fatsph'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
mi = MaterialInterpolator(materialfile)
|
||||||
|
#interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
#tmatrix = interp(omega)
|
||||||
|
tmatrix = CTMatrix.spherical_perm(bspec, eqv_sph_radius, omega, mi(omega), n**2)
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d_r%gnm.npz'%(Nx, Ny, omega/eV*hbar, iri, eqv_sph_radius/nm))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d_r%gnm.done'%(Nx, Ny, omega/eV*hbar, iri, eqv_sph_radius/nm))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,547 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--output', action='store', help='Path to output PDF')
|
||||||
|
parser.add_argument('--store_SVD', action='store_true', help='If specified without --SVD_output, it will save the data in a file named as the PDF output, but with .npz extension instead')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--nSV', action='store', metavar='N', type=int, default=1, help='Store and draw N minimun singular values')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--sparse', action='store', type=int, help='Skip frequencies for preview')
|
||||||
|
parser.add_argument('--eVmax', action='store', type=float, help='Skip frequencies above this value')
|
||||||
|
parser.add_argument('--eVmin', action='store', type=float, help='Skip frequencies below this value')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=66, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
|
||||||
|
translations_dir = pargs.griddir
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
pdfout = pargs.output if pargs.output else (''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) + '.pdf')
|
||||||
|
print(pdfout)
|
||||||
|
if(pargs.store_SVD):
|
||||||
|
if re.search('.pdf$', pdfout):
|
||||||
|
svdout = re.sub('.pdf$', r'.npz', pdfout)
|
||||||
|
else:
|
||||||
|
svdout = pdfout + '.npz'
|
||||||
|
else:
|
||||||
|
svdout = None
|
||||||
|
|
||||||
|
|
||||||
|
hexside = pargs.hexside #375e-9
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
minfreq = pargs.eVmin*eV/hbar if pargs.eVmin else None
|
||||||
|
maxfreq = pargs.eVmax*eV/hbar if pargs.eVmax else None
|
||||||
|
skipfreq = pargs.sparse if pargs.sparse else None
|
||||||
|
svn = pargs.nSV
|
||||||
|
|
||||||
|
# TODO multiplier operation definitions and parsing
|
||||||
|
#factor13inc = 10
|
||||||
|
#factor13scat=10
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
#ops = (
|
||||||
|
# # co, typ operace (symetrizace / transformace / kopie), specifikace (operace nebo zdroj),
|
||||||
|
# # co: 0, 1, (0,1), (0,), (1,), #NI: 'all'
|
||||||
|
# # typ operace: sym, tr, copy
|
||||||
|
# # specifikace:
|
||||||
|
# # sym, tr: 'σ_z', 'σ_y', 'C2'; sym: 'C3',
|
||||||
|
# # copy: 0, 1 (zdroj)
|
||||||
|
# ((0,1), 'sym', 'σ_z'),
|
||||||
|
# #((0,1), 'sym', 'σ_x'),
|
||||||
|
# #((0,1), 'sym', 'σ_y'),
|
||||||
|
# ((0,1), 'sym', 'C3'),
|
||||||
|
# ((1), 'tr', 'C2'),
|
||||||
|
#
|
||||||
|
#)
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
import time
|
||||||
|
begtime=time.time()
|
||||||
|
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from matplotlib.backends.backend_pdf import PdfPages
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdf = PdfPages(pdfout)
|
||||||
|
|
||||||
|
# In[3]:
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
ž = np.arange(2*nelem)
|
||||||
|
tž = ž // nelem
|
||||||
|
mž = my[ž%nelem]
|
||||||
|
nž = ny[ž%nelem]
|
||||||
|
TEž = ž[(mž+nž+tž) % 2 == 0]
|
||||||
|
TMž = ž[(mž+nž+tž) % 2 == 1]
|
||||||
|
|
||||||
|
č = np.arange(2*2*nelem)
|
||||||
|
žč = č % (2* nelem)
|
||||||
|
tč = tž[žč]
|
||||||
|
mč = mž[žč]
|
||||||
|
nč = nž[žč]
|
||||||
|
TEč = č[(mč+nč+tč) % 2 == 0]
|
||||||
|
TMč = č[(mč+nč+tč) % 2 == 1]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# In[4]:
|
||||||
|
|
||||||
|
om = np.linspace(np.min(freqs_orig), np.max(freqs_orig),100)
|
||||||
|
TMatrix0ip = np.reshape(TMatrices_interp(om)[:,0], (len(om), 2*nelem*2*nelem))
|
||||||
|
f, axa = plt.subplots(2, 2, figsize=(15,15))
|
||||||
|
|
||||||
|
#print(TMatrices.shape)
|
||||||
|
#plt.plot(om, TMatrices[:,0,0,0,0].imag,'r',om, TMatrices[:,0,0,0,0].real,'r--',om, TMatrices[:,0,2,0,2].imag,'b',om, TMatrices[:,0,2,0,2].real,'b--'))
|
||||||
|
|
||||||
|
ax = axa[0,0]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, TMatrix0ip[:,:].imag,'-',om, TMatrix0ip[:,:].real,'--',
|
||||||
|
)
|
||||||
|
ax = axa[0,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, abs(TMatrix0ip[:,:]),'-'
|
||||||
|
)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
|
||||||
|
ax = axa[1,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, np.unwrap(np.angle(TMatrix0ip[:,:]),axis=0),'-'
|
||||||
|
)
|
||||||
|
|
||||||
|
ax = axa[1,0]
|
||||||
|
ax.text(0.5,0.5,str(pargs).replace(',',',\n'),horizontalalignment='center',verticalalignment='center',transform=ax.transAxes)
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
#kdensity = 66 #defined from cl arguments
|
||||||
|
bz_0 = np.array((0,0,0.,))
|
||||||
|
bz_K1 = np.array((1.,0,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4,0))*4*np.pi/3/hexside/s3
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(klist, axis=0), axis=-1))))
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
n2id = np.identity(2*nelem)
|
||||||
|
n2id.shape = (2,nelem,2,nelem)
|
||||||
|
extlistlist = list()
|
||||||
|
leftmatrixlistlist = list()
|
||||||
|
minsvTElistlist=list()
|
||||||
|
minsvTMlistlist=list()
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistlist = list()
|
||||||
|
svVfullTElistlist = list()
|
||||||
|
svSfullTElistlist = list()
|
||||||
|
svUfullTMlistlist = list()
|
||||||
|
svVfullTMlistlist = list()
|
||||||
|
svSfullTMlistlist = list()
|
||||||
|
|
||||||
|
nan = float('nan')
|
||||||
|
omegalist = list()
|
||||||
|
filecount = 0
|
||||||
|
for trfile in os.scandir(translations_dir):
|
||||||
|
filecount += 1
|
||||||
|
if (skipfreq and filecount % skipfreq):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
npz = np.load(trfile.path, mmap_mode='r')
|
||||||
|
k_0 = npz['precalc_params'][()]['k_hexside'] / hexside
|
||||||
|
omega = k_0 * c / math.sqrt(epsilon_b)
|
||||||
|
if((minfreq and omega < minfreq) or (maxfreq and omega > maxfreq)):
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
print ("Unexpected error, trying to continue with another file:", sys.exc_info()[0])
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
tdic = qpms.hexlattice_precalc_AB_loadunwrap(trfile.path, return_points=True)
|
||||||
|
except:
|
||||||
|
print ("Unexpected error, trying to continue with another file:", sys.exc_info()[0])
|
||||||
|
continue
|
||||||
|
k_0 = tdic['k_hexside'] / hexside
|
||||||
|
omega = k_0 * c / math.sqrt(epsilon_b)
|
||||||
|
omegalist.append(omega)
|
||||||
|
print(filecount, omega/eV*hbar)
|
||||||
|
sys.stdout.flush()
|
||||||
|
a_self = tdic['a_self'][:,:nelem,:nelem]
|
||||||
|
b_self = tdic['b_self'][:,:nelem,:nelem]
|
||||||
|
a_u2d = tdic['a_u2d'][:,:nelem,:nelem]
|
||||||
|
b_u2d = tdic['b_u2d'][:,:nelem,:nelem]
|
||||||
|
a_d2u = tdic['a_d2u'][:,:nelem,:nelem]
|
||||||
|
b_d2u = tdic['b_d2u'][:,:nelem,:nelem]
|
||||||
|
unitcell_translations = tdic['self_tr']*hexside*s3
|
||||||
|
u2d_translations = tdic['u2d_tr']*hexside*s3
|
||||||
|
d2u_translations = tdic['d2u_tr']*hexside*s3
|
||||||
|
if gaussianSigma:
|
||||||
|
unitcell_envelope = np.exp(-np.sum(tdic['self_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
u2d_envelope = np.exp(-np.sum(tdic['u2d_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
d2u_envelope = np.exp(-np.sum(tdic['d2u_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
|
||||||
|
|
||||||
|
TMatrices_om = TMatrices_interp(omega)
|
||||||
|
if svdout:
|
||||||
|
svUfullTElist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svVfullTElist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svSfullTElist = np.full((klist.shape[0], 2*nelem), np.nan, dtype=complex)
|
||||||
|
svUfullTMlist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svVfullTMlist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svSfullTMlist = np.full((klist.shape[0], 2*nelem), np.nan, dtype=complex)
|
||||||
|
|
||||||
|
|
||||||
|
minsvTElist = np.full((klist.shape[0], svn),np.nan)
|
||||||
|
minsvTMlist = np.full((klist.shape[0], svn),np.nan)
|
||||||
|
leftmatrixlist = np.full((klist.shape[0],2,2,nelem,2,2,nelem),np.nan,dtype=complex)
|
||||||
|
isNaNlist = np.zeros((klist.shape[0]), dtype=bool)
|
||||||
|
|
||||||
|
# sem nějaká rozumná smyčka
|
||||||
|
for ki in range(klist.shape[0]):
|
||||||
|
k = klist[ki]
|
||||||
|
if (k_0*k_0 - k[0]*k[0] - k[1]*k[1] < 0):
|
||||||
|
isNaNlist[ki] = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
phases_self = np.exp(1j*np.tensordot(k,unitcell_translations,axes=(0,-1)))
|
||||||
|
phases_u2d = np.exp(1j*np.tensordot(k,u2d_translations,axes=(0,-1)))
|
||||||
|
phases_d2u = np.exp(1j*np.tensordot(k,d2u_translations,axes=(0,-1)))
|
||||||
|
if gaussianSigma:
|
||||||
|
phases_self *= unitcell_envelope
|
||||||
|
phases_u2d *= u2d_envelope
|
||||||
|
phases_d2u *= d2u_envelope
|
||||||
|
leftmatrix = np.zeros((2,2,nelem, 2,2,nelem), dtype=complex)
|
||||||
|
|
||||||
|
leftmatrix[0,0,:,0,0,:] = np.tensordot(a_self,phases_self, axes=(0,-1)) # u2u, E2E
|
||||||
|
leftmatrix[1,0,:,1,0,:] = leftmatrix[0,0,:,0,0,:] # d2d, E2E
|
||||||
|
leftmatrix[0,1,:,0,1,:] = leftmatrix[0,0,:,0,0,:] # u2u, M2M
|
||||||
|
leftmatrix[1,1,:,1,1,:] = leftmatrix[0,0,:,0,0,:] # d2d, M2M
|
||||||
|
leftmatrix[0,0,:,0,1,:] = np.tensordot(b_self,phases_self, axes=(0,-1)) # u2u, M2E
|
||||||
|
leftmatrix[0,1,:,0,0,:] = leftmatrix[0,0,:,0,1,:] # u2u, E2M
|
||||||
|
leftmatrix[1,1,:,1,0,:] = leftmatrix[0,0,:,0,1,:] # d2d, E2M
|
||||||
|
leftmatrix[1,0,:,1,1,:] = leftmatrix[0,0,:,0,1,:] # d2d, M2E
|
||||||
|
leftmatrix[0,0,:,1,0,:] = np.tensordot(a_d2u, phases_d2u,axes=(0,-1)) #d2u,E2E
|
||||||
|
leftmatrix[0,1,:,1,1,:] = leftmatrix[0,0,:,1,0,:] #d2u, M2M
|
||||||
|
leftmatrix[1,0,:,0,0,:] = np.tensordot(a_u2d, phases_u2d,axes=(0,-1)) #u2d,E2E
|
||||||
|
leftmatrix[1,1,:,0,1,:] = leftmatrix[1,0,:,0,0,:] #u2d, M2M
|
||||||
|
leftmatrix[0,0,:,1,1,:] = np.tensordot(b_d2u, phases_d2u,axes=(0,-1)) #d2u,M2E
|
||||||
|
leftmatrix[0,1,:,1,0,:] = leftmatrix[0,0,:,1,1,:] #d2u, E2M
|
||||||
|
leftmatrix[1,0,:,0,1,:] = np.tensordot(b_u2d, phases_u2d,axes=(0,-1)) #u2d,M2E
|
||||||
|
leftmatrix[1,1,:,0,0,:] = leftmatrix[1,0,:,0,1,:] #u2d, E2M
|
||||||
|
#leftmatrix is now the translation matrix T
|
||||||
|
for j in range(2):
|
||||||
|
leftmatrix[j] = -np.tensordot(TMatrices_om[j], leftmatrix[j], axes=([-2,-1],[0,1]))
|
||||||
|
# at this point, jth row of leftmatrix is that of -MT
|
||||||
|
leftmatrix[j,:,:,j,:,:] += n2id
|
||||||
|
#now we are done, 1-MT
|
||||||
|
|
||||||
|
leftmatrixlist[ki] = leftmatrix
|
||||||
|
|
||||||
|
|
||||||
|
nnlist = np.logical_not(isNaNlist)
|
||||||
|
leftmatrixlist_s = np.reshape(leftmatrixlist,(klist.shape[0], 2*2*nelem,2*2*nelem))[nnlist]
|
||||||
|
leftmatrixlist_TE = leftmatrixlist_s[np.ix_(np.arange(leftmatrixlist_s.shape[0]),TEč,TEč)]
|
||||||
|
leftmatrixlist_TM = leftmatrixlist_s[np.ix_(np.arange(leftmatrixlist_s.shape[0]),TMč,TMč)]
|
||||||
|
#svarr = np.linalg.svd(leftmatrixlist_TE, compute_uv=False)
|
||||||
|
#argsortlist = np.argsort(svarr, axis=-1)[...,:svn]
|
||||||
|
#minsvTElist[nnlist] = svarr[...,argsortlist]
|
||||||
|
#minsvTElist[nnlist] = np.amin(np.linalg.svd(leftmatrixlist_TE, compute_uv=False), axis=-1)
|
||||||
|
if svdout:
|
||||||
|
svUfullTElist[nnlist], svSfullTElist[nnlist], svVfullTElist[nnlist] = np.linalg.svd(leftmatrixlist_TE, compute_uv=True)
|
||||||
|
svUfullTMlist[nnlist], svSfullTMlist[nnlist], svVfullTMlist[nnlist] = np.linalg.svd(leftmatrixlist_TM, compute_uv=True)
|
||||||
|
svUfullTElistlist.append(svUfullTElist)
|
||||||
|
svVfullTElistlist.append(svVfullTElist)
|
||||||
|
svSfullTElistlist.append(svSfullTElist)
|
||||||
|
svUfullTMlistlist.append(svUfullTMlist)
|
||||||
|
svVfullTMlistlist.append(svVfullTMlist)
|
||||||
|
svSfullTMlistlist.append(svSfullTMlist)
|
||||||
|
minsvTElist[nnlist] = np.linalg.svd(leftmatrixlist_TE, compute_uv=False)[...,-svn:]
|
||||||
|
#svarr = np.linalg.svd(leftmatrixlist_TM, compute_uv=False)
|
||||||
|
#argsortlist = np.argsort(svarr, axis=-1)[...,:svn]
|
||||||
|
#minsvTMlist[nnlist] = svarr[...,argsortlist]
|
||||||
|
#minsvTMlist[nnlist] = np.amin(np.linalg.svd(leftmatrixlist_TM, compute_uv=False), axis=-1)
|
||||||
|
minsvTMlist[nnlist] = np.linalg.svd(leftmatrixlist_TM, compute_uv=False)[...,-svn:]
|
||||||
|
minsvTMlistlist.append(minsvTMlist)
|
||||||
|
minsvTElistlist.append(minsvTElist)
|
||||||
|
|
||||||
|
minsvTElistarr = np.array(minsvTElistlist)
|
||||||
|
minsvTMlistarr = np.array(minsvTMlistlist)
|
||||||
|
del minsvTElistlist, minsvTMlistlist
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistarr = np.array(svUfullTElistlist)
|
||||||
|
svVfullTElistarr = np.array(svVfullTElistlist)
|
||||||
|
svSfullTElistarr = np.array(svSfullTElistlist)
|
||||||
|
del svUfullTElistlist, svVfullTElistlist, svSfullTElistlist
|
||||||
|
svUfullTMlistarr = np.array(svUfullTMlistlist)
|
||||||
|
svVfullTMlistarr = np.array(svVfullTMlistlist)
|
||||||
|
svSfullTMlistarr = np.array(svSfullTMlistlist)
|
||||||
|
del svUfullTMlistlist, svVfullTMlistlist, svSfullTMlistlist
|
||||||
|
omegalist = np.array(omegalist)
|
||||||
|
# order to make the scatter plots "nice"
|
||||||
|
omegaorder = np.argsort(omegalist)
|
||||||
|
omegalist = omegalist[omegaorder]
|
||||||
|
minsvTElistarr = minsvTElistarr[omegaorder]
|
||||||
|
minsvTMlistarr = minsvTMlistarr[omegaorder]
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistarr = svUfullTElistarr[omegaorder]
|
||||||
|
svVfullTElistarr = svVfullTElistarr[omegaorder]
|
||||||
|
svSfullTElistarr = svSfullTElistarr[omegaorder]
|
||||||
|
svUfullTMlistarr = svUfullTMlistarr[omegaorder]
|
||||||
|
svVfullTMlistarr = svVfullTMlistarr[omegaorder]
|
||||||
|
svSfullTMlistarr = svSfullTMlistarr[omegaorder]
|
||||||
|
np.savez(svdout, omega = omegalist, klist = klist, bzpoints = np.array([bz_0, bz_K1, bz_K2, bz_M, B1, B2]),
|
||||||
|
uTE = svUfullTElistarr,
|
||||||
|
vTE = svVfullTElistarr,
|
||||||
|
sTE = svSfullTElistarr,
|
||||||
|
uTM = svUfullTMlistarr,
|
||||||
|
vTM = svVfullTMlistarr,
|
||||||
|
sTM = svSfullTMlistarr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
omlist = np.broadcast_to(omegalist[:,nx], minsvTElistarr[...,0].shape)
|
||||||
|
kxmlarr = np.broadcast_to(kxmaplist[nx,:], minsvTElistarr[...,0].shape)
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
for minN in reversed(range(svn)):
|
||||||
|
f, ax = plt.subplots(1, figsize=(20,15))
|
||||||
|
sc = ax.scatter(kxmlarr, omlist/eV*hbar, c = np.sqrt(minsvTMlistarr[...,minN]), s =40, lw=0)
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(klist,axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B2-B1, axis=-1)*cdn, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B1-B2, axis=-1)*cdn, '-',
|
||||||
|
)
|
||||||
|
ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([2.15,2.30])
|
||||||
|
ax.set_ylim([np.min(omlist/eV*hbar),np.max(omlist/eV*hbar)])
|
||||||
|
ax.set_xticks([0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]])
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
f.colorbar(sc)
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
f, ax = plt.subplots(1, figsize=(20,15))
|
||||||
|
sc = ax.scatter(kxmlarr, omlist/eV*hbar, c = np.sqrt(minsvTElistarr[...,minN]), s =40, lw=0)
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(klist,axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B2-B1, axis=-1)*cdn, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B1-B2, axis=-1)*cdn, '-',
|
||||||
|
)
|
||||||
|
ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([2.15,2.30])
|
||||||
|
ax.set_ylim([np.min(omlist/eV*hbar),np.max(omlist/eV*hbar)])
|
||||||
|
ax.set_xticks([0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]])
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
f.colorbar(sc)
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
pdf.close()
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
subprocess.run(['scp', pdfout, scp_dest])
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,403 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the pdf and/or npz output (will be appended frequency and hexside)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--output', action='store', help='Path to output PDF')
|
||||||
|
parser.add_argument('--store_SVD', action='store_false', help='If specified without --SVD_output, it will save the data in a file named as the PDF output, but with .npz extension instead')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--nSV', action='store', metavar='N', type=int, default=1, help='Store and draw N minimun singular values')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
pdfout = pargs.output if pargs.output else (
|
||||||
|
'%s_%dnm_%.4f.pdf' % (pargs.output_prefix,hexside/1e-9,eVfreq) if pargs.output_prefix else
|
||||||
|
(''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) + '.pdf'))
|
||||||
|
print(pdfout)
|
||||||
|
if(pargs.store_SVD):
|
||||||
|
if re.search('.pdf$', pdfout):
|
||||||
|
svdout = re.sub('.pdf$', r'.npz', pdfout)
|
||||||
|
else:
|
||||||
|
svdout = pdfout + '.npz'
|
||||||
|
else:
|
||||||
|
svdout = None
|
||||||
|
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
svn = pargs.nSV
|
||||||
|
|
||||||
|
# TODO multiplier operation definitions and parsing
|
||||||
|
#factor13inc = 10
|
||||||
|
#factor13scat=10
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
#ops = (
|
||||||
|
# # co, typ operace (symetrizace / transformace / kopie), specifikace (operace nebo zdroj),
|
||||||
|
# # co: 0, 1, (0,1), (0,), (1,), #NI: 'all'
|
||||||
|
# # typ operace: sym, tr, copy
|
||||||
|
# # specifikace:
|
||||||
|
# # sym, tr: 'σ_z', 'σ_y', 'C2'; sym: 'C3',
|
||||||
|
# # copy: 0, 1 (zdroj)
|
||||||
|
# ((0,1), 'sym', 'σ_z'),
|
||||||
|
# #((0,1), 'sym', 'σ_x'),
|
||||||
|
# #((0,1), 'sym', 'σ_y'),
|
||||||
|
# ((0,1), 'sym', 'C3'),
|
||||||
|
# ((1), 'tr', 'C2'),
|
||||||
|
#
|
||||||
|
#)
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
import time
|
||||||
|
begtime=time.time()
|
||||||
|
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from matplotlib.backends.backend_pdf import PdfPages
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdf = PdfPages(pdfout)
|
||||||
|
|
||||||
|
# In[3]:
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# In[4]:
|
||||||
|
if(pargs.plot_TMatrix):
|
||||||
|
om = np.linspace(np.min(freqs_orig), np.max(freqs_orig),100)
|
||||||
|
TMatrix0ip = np.reshape(TMatrices_interp(om)[:,0], (len(om), 2*nelem*2*nelem))
|
||||||
|
f, axa = plt.subplots(2, 2, figsize=(15,15))
|
||||||
|
|
||||||
|
#print(TMatrices.shape)
|
||||||
|
#plt.plot(om, TMatrices[:,0,0,0,0].imag,'r',om, TMatrices[:,0,0,0,0].real,'r--',om, TMatrices[:,0,2,0,2].imag,'b',om, TMatrices[:,0,2,0,2].real,'b--'))
|
||||||
|
|
||||||
|
ax = axa[0,0]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, TMatrix0ip[:,:].imag,'-',om, TMatrix0ip[:,:].real,'--',
|
||||||
|
)
|
||||||
|
ax = axa[0,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, abs(TMatrix0ip[:,:]),'-'
|
||||||
|
)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
|
||||||
|
ax = axa[1,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, np.unwrap(np.angle(TMatrix0ip[:,:]),axis=0),'-'
|
||||||
|
)
|
||||||
|
|
||||||
|
ax = axa[1,0]
|
||||||
|
ax.text(0.5,0.5,str(pargs).replace(',',',\n'),horizontalalignment='center',verticalalignment='center',transform=ax.transAxes)
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
'''
|
||||||
|
#kdensity = 66 #defined from cl arguments
|
||||||
|
bz_0 = np.array((0,0,0.,))
|
||||||
|
bz_K1 = np.array((1.,0,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4,0))*4*np.pi/3/hexside/s3
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(klist, axis=0), axis=-1))))
|
||||||
|
'''
|
||||||
|
klist = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=(0 if svdout else svn))
|
||||||
|
if svdout:
|
||||||
|
((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
(minsvElist, minsvTMlist) = (svSfullTElist[...,-svn:], svSfullTMlist[...,-svn:])
|
||||||
|
else:
|
||||||
|
minsvTElist, minsvTMlist = svdres
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' The new pretty diffracted order drawing '''
|
||||||
|
maxlayer_reciprocal=4
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
bz_0 = np.array((0,0,))
|
||||||
|
bz_K1 = np.array((1.,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4))*4*np.pi/3/hexside/s3
|
||||||
|
|
||||||
|
# reciprocal lattice basis
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
|
||||||
|
if svdout:
|
||||||
|
np.savez(svdout, omega = freq, klist = klist, bzpoints = np.array([bz_0, bz_K1, bz_K2, bz_M, B1, B2]),
|
||||||
|
uTE = svUfullTElist,
|
||||||
|
vTE = svVfullTElist,
|
||||||
|
sTE = svSfullTElist,
|
||||||
|
uTM = svUfullTMlist,
|
||||||
|
vTM = svVfullTMlist,
|
||||||
|
sTM = svSfullTMlist,
|
||||||
|
)
|
||||||
|
|
||||||
|
k2density = 100
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
k2list = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(k2list, axis=0), axis=-1))))
|
||||||
|
|
||||||
|
centers2=qpms.generate_trianglepoints(maxlayer_reciprocal, v3d = False, include_origin= True)*4*np.pi/3/hexside
|
||||||
|
rot90 = np.array([[0,-1],[1,0]])
|
||||||
|
centers2=np.dot(centers2,rot90)
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
cmap = matplotlib.cm.prism
|
||||||
|
colormax = np.amax(np.linalg.norm(centers2,axis=0))
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
for minN in reversed(range(svn)):
|
||||||
|
f, axes = plt.subplots(1,3, figsize=(20,4.8))
|
||||||
|
ax = axes[0]
|
||||||
|
sc = ax.scatter(klist[:,0], klist[:,1], c = np.clip(np.abs(minsvTElist[:,minN]),0,1), lw=0)
|
||||||
|
for center in centers2:
|
||||||
|
circle=plt.Circle((center[0],center[1]),omega/cdn, facecolor='none', edgecolor=cmap(np.linalg.norm(center)/colormax),lw=0.5)
|
||||||
|
ax.add_artist(circle)
|
||||||
|
verts = [(math.cos(math.pi*i/3)*4*np.pi/3/hexside/s3,math.sin(math.pi*i/3)*4*np.pi/3/hexside/s3) for i in range(6 +1)]
|
||||||
|
codes = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.CLOSEPOLY,]
|
||||||
|
path = Path(verts, codes)
|
||||||
|
patch = patches.PathPatch(path, facecolor='none', edgecolor='black', lw=1)
|
||||||
|
ax.add_patch(patch)
|
||||||
|
ax.set_xticks([])
|
||||||
|
ax.set_yticks([])
|
||||||
|
ax.title.set_text('E in-plane ("TE")')
|
||||||
|
f.colorbar(sc,ax=ax)
|
||||||
|
|
||||||
|
|
||||||
|
ax = axes[1]
|
||||||
|
sc = ax.scatter(klist[:,0], klist[:,1], c = np.clip(np.abs(minsvTMlist[:,minN]),0,1), lw=0)
|
||||||
|
for center in centers2:
|
||||||
|
circle=plt.Circle((center[0],center[1]),omega/cdn, facecolor='none', edgecolor=cmap(np.linalg.norm(center)/colormax),lw=0.5)
|
||||||
|
ax.add_artist(circle)
|
||||||
|
verts = [(math.cos(math.pi*i/3)*4*np.pi/3/hexside/s3,math.sin(math.pi*i/3)*4*np.pi/3/hexside/s3) for i in range(6 +1)]
|
||||||
|
codes = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.CLOSEPOLY,]
|
||||||
|
path = Path(verts, codes)
|
||||||
|
patch = patches.PathPatch(path, facecolor='none', edgecolor='black', lw=1)
|
||||||
|
ax.add_patch(patch)
|
||||||
|
ax.set_xticks([])
|
||||||
|
ax.set_yticks([])
|
||||||
|
ax.title.set_text('E perpendicular ("TM")')
|
||||||
|
f.colorbar(sc,ax=ax)
|
||||||
|
|
||||||
|
ax = axes[2]
|
||||||
|
for center in centers2:
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(k2list-center,axis=-1)*cdn, '-', color=cmap(np.linalg.norm(center)/colormax))
|
||||||
|
|
||||||
|
#ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([np.min(omegalist),np.max(omegalist)])
|
||||||
|
xticklist = [0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]]
|
||||||
|
ax.set_xticks(xticklist)
|
||||||
|
for xt in xticklist:
|
||||||
|
ax.axvline(xt, ls='dotted', lw=0.3,c='k')
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
ax.axhline(omega, c='black')
|
||||||
|
ax.set_ylim([0,5e15])
|
||||||
|
ax2 = ax.twinx()
|
||||||
|
ax2.set_ylim([ax.get_ylim()[0]/eV*hbar,ax.get_ylim()[1]/eV*hbar])
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
pdf.close()
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
subprocess.run(['scp', pdfout, scp_dest])
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,239 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=1000, help='Number of k-points per output file (default 1000)')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
klist_full = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.shape[0] / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points in %d chunks' % (klist_full.shape[0], chunkn), file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'lMax' : lMax,
|
||||||
|
'maxlayer' : maxlayer,
|
||||||
|
'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
})
|
||||||
|
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
svdout = '%s_%dnm_%.4f_c%03d.npz' % (pargs.output_prefix, hexside/1e-9, eVfreq, chunki)
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=False, verbose=verbose)
|
||||||
|
|
||||||
|
#((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
|
||||||
|
np.savez(svdout, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
uTE = svdres[0][0],
|
||||||
|
vTE = svdres[0][2],
|
||||||
|
sTE = svdres[0][1],
|
||||||
|
uTM = svdres[1][0],
|
||||||
|
vTM = svdres[1][2],
|
||||||
|
sTM = svdres[1][1],
|
||||||
|
|
||||||
|
)
|
||||||
|
svdres=None
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
||||||
|
#print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -1,719 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import qpms\n",
|
|
||||||
"import warnings\n",
|
|
||||||
"from qpms.cybspec import BaseSpec\n",
|
|
||||||
"from qpms.cytmatrices import CTMatrix, TMatrixGenerator, TMatrixInterpolator\n",
|
|
||||||
"from qpms.qpms_c import Particle, pgsl_ignore_error\n",
|
|
||||||
"from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude\n",
|
|
||||||
"from qpms.cycommon import DebugFlags, dbgmsg_enable\n",
|
|
||||||
"from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar\n",
|
|
||||||
"import scipy.constants as sci\n",
|
|
||||||
"eh = eV/hbar"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#TODO\n",
|
|
||||||
"period = 520e-9\n",
|
|
||||||
"a1 = np.array([0,period]) \n",
|
|
||||||
"a2 = np.array([period,0])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Particle positions\n",
|
|
||||||
"orig_x = [0]\n",
|
|
||||||
"orig_y = [0]\n",
|
|
||||||
"orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"period = 0.52\n",
|
|
||||||
"refractive_index = 1.52 # for background medium\n",
|
|
||||||
"height = 50e-9 # Particle height\n",
|
|
||||||
"radius = 50e-9 # Particle radius\n",
|
|
||||||
"medium = EpsMu(refractive_index**2) # non-lossy background medium with constant refr. index #OK\n",
|
|
||||||
"# global symmetry group of the system\n",
|
|
||||||
"#sym = FinitePointGroup(point_group_info['D4h'])\n",
|
|
||||||
"omega = 1.58*eh\n",
|
|
||||||
"metal = lorentz_drude['Ag']\n",
|
|
||||||
"kx_lim = np.array([-0.2, 0.2], dtype=float)\n",
|
|
||||||
"N=501"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(7.59633723939313, 8.305328715069821, 7.94387469344152, 8.001475225494097)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"omega_scuff_min=1.5*eh/3e14\n",
|
|
||||||
"omega_scuff_max=1.64*eh/3e14\n",
|
|
||||||
"omega_scuff=omega/3e14\n",
|
|
||||||
"omega_scuff_slr=(2*np.pi*sci.c/(1.52*0.52e-6))/3e14\n",
|
|
||||||
"omega_scuff_min, omega_scuff_max, omega_scuff_slr, omega_scuff"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"bspec = BaseSpec(lMax = 1)\n",
|
|
||||||
"\n",
|
|
||||||
"tmfile_scuffOld = '/home/javier/tmatrices/sphereAg_50nm_oldScuff.TMatrix'\n",
|
|
||||||
"tmfile_scuffNew = '/home/javier/tmatrices/sphere50nm_newScuff.TMatrix'\n",
|
|
||||||
"interp_old = TMatrixInterpolator(tmfile_scuffOld, bspec, atol=1e-8) \n",
|
|
||||||
"interp_new = TMatrixInterpolator(tmfile_scuffNew, bspec, atol=1e-8) \n",
|
|
||||||
"tmscuff_not_fixed = interp_old(omega)\n",
|
|
||||||
"tmscuff_bugfixed = interp_new(omega)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 7,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"tmgen = TMatrixGenerator.sphere(medium, metal, radius)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 8,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"tmgen_omega=tmgen(bspec,omega)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 9,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , -0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , -0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j, 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j, 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 9,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmgen_omega.as_ndarray() # T-Matrix from generator"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-4.70886671e-03+1.79440815e-02j, 1.60098226e-13+4.20092462e-13j, 2.26455777e-07+3.98932962e-07j, -2.13258227e-14-6.01930824e-14j, 7.66251504e-08-1.32539814e-08j,\n",
|
|
||||||
" -7.76488937e-14+1.08532726e-13j],\n",
|
|
||||||
" [-4.41531068e-13+9.81757019e-14j, -4.70582367e-03+1.79389513e-02j, -1.60702588e-13-4.19762769e-13j, 6.32372612e-08+4.71302619e-08j, -2.36039655e-14+1.00983241e-13j,\n",
|
|
||||||
" 7.76590838e-08-1.38092126e-08j],\n",
|
|
||||||
" [-4.58579591e-07-7.49053314e-09j, 4.41175187e-13-9.87457125e-14j, -4.70886672e-03+1.79440815e-02j, 2.13790755e-14+1.31812722e-13j, 6.25535562e-08+4.61875295e-08j,\n",
|
|
||||||
" 4.59276044e-14-4.47400043e-14j],\n",
|
|
||||||
" [ 4.93366461e-14-4.29235249e-14j, -6.94450011e-09-1.60278760e-08j, -7.79609985e-14+1.07845028e-13j, -3.03166095e-05-2.01474828e-03j, -2.39253108e-13-1.34944425e-13j,\n",
|
|
||||||
" 1.16328171e-08+6.36863105e-09j],\n",
|
|
||||||
" [ 8.21008790e-09-1.53591010e-08j, -2.36580203e-14+1.00878213e-13j, -5.41800099e-09-1.65573897e-08j, 2.26431323e-13-1.55248143e-13j, -3.03231670e-05-2.01493037e-03j,\n",
|
|
||||||
" 2.38800352e-13+1.35401679e-13j],\n",
|
|
||||||
" [ 2.18731933e-14+1.31428484e-13j, 7.13657440e-09-1.65412452e-08j, -2.48667583e-14-6.12974376e-14j, -1.11447700e-08+7.19733229e-09j, -2.26916383e-13+1.54810715e-13j,\n",
|
|
||||||
" -3.03166170e-05-2.01474828e-03j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmscuff_not_fixed.as_ndarray() # T-Matrix of not fixed version of Scuff-EM"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-9.43033280e-02+3.59361755e-01j, 3.20658236e-12+8.41416904e-12j, 5.13892659e-06+8.57797510e-06j, -4.28949536e-13-1.20456867e-12j, 1.41239218e-06-2.46862181e-07j,\n",
|
|
||||||
" -1.55480479e-12+2.17400571e-12j],\n",
|
|
||||||
" [-8.84386127e-12+1.96169624e-12j, -9.42395846e-02+3.59248336e-01j, -3.22166474e-12-8.40342496e-12j, 1.16868119e-06+8.68484583e-07j, -4.72874254e-13+2.02296639e-12j,\n",
|
|
||||||
" 1.43308826e-06-2.58864855e-07j],\n",
|
|
||||||
" [-9.99885677e-06+6.63229466e-08j, 8.83605486e-12-1.97841571e-12j, -9.43033282e-02+3.59361755e-01j, 4.27888728e-13+2.63976219e-12j, 1.15544356e-06+8.48824647e-07j,\n",
|
|
||||||
" 9.21093604e-13-8.94225073e-13j],\n",
|
|
||||||
" [ 9.85267406e-13-8.59818272e-13j, -1.43866720e-06+2.57952214e-07j, -1.56233879e-12+2.15974773e-12j, -6.07143255e-04-4.03488631e-02j, -4.79139425e-12-2.70322093e-12j,\n",
|
|
||||||
" 1.52945653e-07+8.36194839e-08j],\n",
|
|
||||||
" [-1.15196465e-06-8.46913318e-07j, -4.73514628e-13+2.02574744e-12j, -1.40806670e-06+2.47097086e-07j, 4.53481568e-12-3.10854698e-12j, -6.07256494e-04-4.03513114e-02j,\n",
|
|
||||||
" 4.78231690e-12+2.71099900e-12j],\n",
|
|
||||||
" [ 4.39050064e-13+2.63269196e-12j, -1.17350730e-06-8.70822943e-07j, -4.95069921e-13-1.22744130e-12j, -1.44529174e-07+9.78280211e-08j, -4.54412580e-12+3.10101417e-12j,\n",
|
|
||||||
" -6.07143303e-04-4.03488631e-02j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmscuff_bugfixed.as_ndarray() # T-Matrix of FIXED version of Scuff-EM"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(matrix([[-9.43033280e-02+3.59361755e-01j, 3.20658236e-12+8.41416904e-12j],\n",
|
|
||||||
" [-8.84386127e-12+1.96169624e-12j, -9.42395846e-02+3.59248336e-01j]]),\n",
|
|
||||||
" matrix([[-9.43033280e-02-3.59361755e-01j, -8.84386127e-12-1.96169624e-12j],\n",
|
|
||||||
" [ 3.20658236e-12-8.41416904e-12j, -9.42395846e-02-3.59248336e-01j]]))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#I play around with the different operations so everything is correct\n",
|
|
||||||
"tmscuffnew = tmscuff_bugfixed.as_ndarray()\n",
|
|
||||||
"tmscuffnew_mat = np.asmatrix(tmscuffnew)\n",
|
|
||||||
"tmscuffnew_dag = tmscuffnew_mat.getH()\n",
|
|
||||||
"tmscuffnew_mat[0:2,0:2], tmscuffnew_dag[0:2,0:2]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 13,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(matrix([[1, 0],\n",
|
|
||||||
" [9, 4]]), matrix([[4, 9],\n",
|
|
||||||
" [0, 1]]))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 13,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"A = np.matrix([[0,1],[2,3]])\n",
|
|
||||||
"B = np.matrix([[3,2],[1,0]])\n",
|
|
||||||
"AB = np.dot(A,B)\n",
|
|
||||||
"BA = np.dot(B,A)\n",
|
|
||||||
"AB,BA"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 14,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"sum1new = np.dot(tmscuffnew_dag,tmscuffnew) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2new = 0.5*tmscuffnew.__add__(tmscuffnew_dag) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 15,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew = sum1new.__add__(sum2new) #powermatrix for bugfixed scuff"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 16,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix for NOT bugfixed scuff\n",
|
|
||||||
"tmscuffold = tmscuff_not_fixed.as_ndarray()\n",
|
|
||||||
"tmscuffold_mat = np.asmatrix(tmscuffold)\n",
|
|
||||||
"tmscuffold_dag = tmscuffold_mat.getH()\n",
|
|
||||||
"sum1old = np.dot(tmscuffold_dag,tmscuffold) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2old = 0.5*tmscuffold.__add__(tmscuffold_dag)\n",
|
|
||||||
"\n",
|
|
||||||
"powermatrix_scuffold = sum1old.__add__(sum2old) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 17,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix for T matrix generator\n",
|
|
||||||
"tmscuffgen = tmgen_omega.as_ndarray()\n",
|
|
||||||
"tmscuffgen_mat = np.asmatrix(tmscuffgen)\n",
|
|
||||||
"tmscuffgen_dag = tmscuffgen_mat.getH()\n",
|
|
||||||
"sum1gen = np.dot(tmscuffgen_dag,tmscuffgen) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2gen = 0.5*tmscuffgen.__add__(tmscuffgen_dag)\n",
|
|
||||||
"\n",
|
|
||||||
"powermatrix_scuffgen = sum1gen.__add__(sum2gen) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix of generator is diagonal and all its eigenvalues are negative:\n",
|
|
||||||
"powermatrix_scuffgen[0,0], powermatrix_scuffgen[1,1], powermatrix_scuffgen[2,2], powermatrix_scuffgen[3,3], powermatrix_scuffgen[4,4], powermatrix_scuffgen[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 19,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((0.04373066071852283+0j),\n",
|
|
||||||
" (0.04370088172427582+0j),\n",
|
|
||||||
" (0.043730660553373296+0j),\n",
|
|
||||||
" (0.001021256123757952+0j),\n",
|
|
||||||
" (0.0010213406041430792+0j),\n",
|
|
||||||
" (0.0010212560750220145+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 19,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew[0,0], powermatrix_scuffnew[1,1], powermatrix_scuffnew[2,2], powermatrix_scuffnew[3,3], powermatrix_scuffnew[4,4], powermatrix_scuffnew[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 20,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-0.004364703222422517+0j),\n",
|
|
||||||
" (-0.004361872918812184+0j),\n",
|
|
||||||
" (-0.004364703232328262+0j),\n",
|
|
||||||
" (-2.6256479824067564e-05+0j),\n",
|
|
||||||
" (-2.6262303053141142e-05+0j),\n",
|
|
||||||
" (-2.6256487319428013e-05+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 20,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffold[0,0], powermatrix_scuffold[1,1], powermatrix_scuffold[2,2], powermatrix_scuffold[3,3], powermatrix_scuffold[4,4], powermatrix_scuffold[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-10.019160178833705-0j),\n",
|
|
||||||
" (-10.018834234211564-0j),\n",
|
|
||||||
" (-10.019160118257586-0j),\n",
|
|
||||||
" (-38.895393845668316-0j),\n",
|
|
||||||
" (-38.88998623145963-0j),\n",
|
|
||||||
" (-38.89538088616882-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#So! There is a fixed factor between the N/M elements of Scuff new and old:\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/powermatrix_scuffold[0,0], powermatrix_scuffnew[1,1]/powermatrix_scuffold[1,1], powermatrix_scuffnew[2,2]/powermatrix_scuffold[2,2], powermatrix_scuffnew[3,3]/powermatrix_scuffold[3,3], powermatrix_scuffnew[4,4]/powermatrix_scuffold[4,4], powermatrix_scuffnew[5,5]/powermatrix_scuffold[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-5.118211317583541-0j),\n",
|
|
||||||
" (-5.11472600126595-0j),\n",
|
|
||||||
" (-5.118211298254535-0j),\n",
|
|
||||||
" (-1.6075545942687262-0j),\n",
|
|
||||||
" (-1.6076875744566317-0j),\n",
|
|
||||||
" (-1.60755451755371-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#And there is a fixed factor for new / generated as well! (hence also for old / generated)\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/powermatrix_scuffgen[0,0], powermatrix_scuffnew[1,1]/powermatrix_scuffgen[1,1], powermatrix_scuffnew[2,2]/powermatrix_scuffgen[2,2], powermatrix_scuffnew[3,3]/powermatrix_scuffgen[3,3], powermatrix_scuffnew[4,4]/powermatrix_scuffgen[4,4], powermatrix_scuffnew[5,5]/powermatrix_scuffgen[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-1.60755451755371-0j), (-2.557363000632975+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew[5,5]/powermatrix_scuffgen[5,5], powermatrix_scuffnew[1,1]/powermatrix_scuffgen[1,1]/2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((1.599227713011597e-16-0j),\n",
|
|
||||||
" (8.902299490051238e-14+0j),\n",
|
|
||||||
" (1.504486797691096e-21-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Let's also calculate the determinants\n",
|
|
||||||
"detnew = powermatrix_scuffnew[0,0]*powermatrix_scuffnew[1,1]*powermatrix_scuffnew[2,2]*powermatrix_scuffnew[3,3]*powermatrix_scuffnew[4,4]*powermatrix_scuffnew[5,5]\n",
|
|
||||||
"detold = powermatrix_scuffold[0,0]*powermatrix_scuffold[1,1]*powermatrix_scuffold[2,2]*powermatrix_scuffold[3,3]*powermatrix_scuffold[4,4]*powermatrix_scuffold[5,5]\n",
|
|
||||||
"detgen = powermatrix_scuffgen[0,0]*powermatrix_scuffgen[1,1]*powermatrix_scuffgen[2,2]*powermatrix_scuffgen[3,3]*powermatrix_scuffgen[4,4]*powermatrix_scuffgen[5,5]\n",
|
|
||||||
"detgen, detnew, detold"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((1.5992277130116025e-16+0j),\n",
|
|
||||||
" (8.902299447416401e-14+2.6128569373609595e-39j),\n",
|
|
||||||
" (1.504486701753944e-21-2.892571608172536e-45j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"np.linalg.det(powermatrix_scuffgen), np.linalg.det(powermatrix_scuffnew), np.linalg.det(powermatrix_scuffold)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 24,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#We try to normalize the power matrix elements for each case with the corresponding determinants."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 25,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-53426597795433.88+0j),\n",
|
|
||||||
" (-53426597795433.88+0j),\n",
|
|
||||||
" (-53426597795433.88+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 25,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#T-matrix generator: \n",
|
|
||||||
"powermatrix_scuffgen[0,0]/detgen, powermatrix_scuffgen[1,1]/detgen, powermatrix_scuffgen[2,2]/detgen, powermatrix_scuffgen[3,3]/detgen, powermatrix_scuffgen[4,4]/detgen, powermatrix_scuffgen[5,5]/detgen "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 26,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-2.901124309712079e+18+0j),\n",
|
|
||||||
" (-2.899243067806416e+18+0j),\n",
|
|
||||||
" (-2.901124316296214e+18+0j),\n",
|
|
||||||
" (-1.7452117136795634e+16+0j),\n",
|
|
||||||
" (-1.7455987711853198e+16+0j),\n",
|
|
||||||
" (-1.7452122118800434e+16+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 26,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Not bugfixed Scuff-EM: \n",
|
|
||||||
"powermatrix_scuffold[0,0]/detold, powermatrix_scuffold[1,1]/detold, powermatrix_scuffold[2,2]/detold, powermatrix_scuffold[3,3]/detold, powermatrix_scuffold[4,4]/detold, powermatrix_scuffold[5,5]/detold "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 27,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((491228819782.9563+0j),\n",
|
|
||||||
" (490894310768.96173+0j),\n",
|
|
||||||
" (491228817927.8229+0j),\n",
|
|
||||||
" (11471823936.043226+0j),\n",
|
|
||||||
" (11472772908.667904+0j),\n",
|
|
||||||
" (11471823388.58987+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 27,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#New Scuff-EM: \n",
|
|
||||||
"powermatrix_scuffnew[0,0]/detnew, powermatrix_scuffnew[1,1]/detnew, powermatrix_scuffnew[2,2]/detnew, powermatrix_scuffnew[3,3]/detnew, powermatrix_scuffnew[4,4]/detnew, powermatrix_scuffnew[5,5]/detnew "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 28,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#It might make more sense to renormalize the electric and magnetic parts of the power matrices separately:"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((13698.226641508763-0j),\n",
|
|
||||||
" (13698.226641508763-0j),\n",
|
|
||||||
" (13698.226641508763-0j),\n",
|
|
||||||
" (2477776.413504498-0j),\n",
|
|
||||||
" (2477776.413504498-0j),\n",
|
|
||||||
" (2477776.413504498-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#T-matrix generator:\n",
|
|
||||||
"detgen_el = powermatrix_scuffgen[0,0]*powermatrix_scuffgen[1,1]*powermatrix_scuffgen[2,2]\n",
|
|
||||||
"detgen_mag = powermatrix_scuffgen[3,3]*powermatrix_scuffgen[4,4]*powermatrix_scuffgen[5,5]\n",
|
|
||||||
"powermatrix_scuffgen[0,0]/detgen_el, powermatrix_scuffgen[1,1]/detgen_el, powermatrix_scuffgen[2,2]/detgen_el, powermatrix_scuffgen[3,3]/detgen_mag, powermatrix_scuffgen[4,4]/detgen_mag, powermatrix_scuffgen[5,5]/detgen_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 30,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((52525.751093170744-0j),\n",
|
|
||||||
" (52491.69062780147-0j),\n",
|
|
||||||
" (52525.75121237855-0j),\n",
|
|
||||||
" (1450208903.6280527-0j),\n",
|
|
||||||
" (1450530534.6580672-0j),\n",
|
|
||||||
" (1450209317.614944-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 30,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#NOT bugfixed Scuff-EM:\n",
|
|
||||||
"detold_el = powermatrix_scuffold[0,0]*powermatrix_scuffold[1,1]*powermatrix_scuffold[2,2]\n",
|
|
||||||
"detold_mag = powermatrix_scuffold[3,3]*powermatrix_scuffold[4,4]*powermatrix_scuffold[5,5]\n",
|
|
||||||
"powermatrix_scuffold[0,0]/detold_el, powermatrix_scuffold[1,1]/detold_el, powermatrix_scuffold[2,2]/detold_el, powermatrix_scuffold[3,3]/detold_mag, powermatrix_scuffold[4,4]/detold_mag, powermatrix_scuffold[5,5]/detold_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((523.2675016470721+0j),\n",
|
|
||||||
" (522.9111754524715+0j),\n",
|
|
||||||
" (523.2674996709441+0j),\n",
|
|
||||||
" (958726.5381294343+0j),\n",
|
|
||||||
" (958805.8459399715+0j),\n",
|
|
||||||
" (958726.4923775065+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Bugfixed Scuff-EM:\n",
|
|
||||||
"detnew_el = powermatrix_scuffnew[0,0]*powermatrix_scuffnew[1,1]*powermatrix_scuffnew[2,2]\n",
|
|
||||||
"detnew_mag = powermatrix_scuffnew[3,3]*powermatrix_scuffnew[4,4]*powermatrix_scuffnew[5,5]\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/detnew_el, powermatrix_scuffnew[1,1]/detnew_el, powermatrix_scuffnew[2,2]/detnew_el, powermatrix_scuffnew[3,3]/detnew_mag, powermatrix_scuffnew[4,4]/detnew_mag, powermatrix_scuffnew[5,5]/detnew_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.6.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
|
@ -1,362 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, make_dict_action, sslice, annotate_pdf_metadata
|
|
||||||
figscale=3
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega'])
|
|
||||||
ap.add_argument("-k", '--wavevector', nargs=2, type=float, required=True, help='"Bloch" vector, modulating phase of the driving', metavar=('KX', 'KY'), default=(0., 0.))
|
|
||||||
# ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
ap.add_argument("-S", "--symmetry-adapted", default=None, help="Use a symmetry-adapted basis of a given point group instead of individual spherical harmonics")
|
|
||||||
ap.add_argument("-d", "--ccd-distance", type=float, default=math.nan, help='Far-field "CCD" distance from the sample')
|
|
||||||
ap.add_argument("-D", "--ccd-size", type=float, default=math.nan, help='Far-field "CCD" width and heighth')
|
|
||||||
ap.add_argument("-R", "--ccd-resolution", type=int, default=101, help='Far-field "CCD" resolution')
|
|
||||||
ap.add_argument("--xslice", default={None:None}, nargs=2,
|
|
||||||
action=make_dict_action(argtype=sslice, postaction='append', first_is_key=True),
|
|
||||||
)
|
|
||||||
ap.add_argument("--yslice", default={None:None}, nargs=2,
|
|
||||||
action=make_dict_action(argtype=sslice, postaction='append', first_is_key=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#ap.add_argument("--irrep", type=str, default="none", help="Irrep subspace (irrep index from 0 to 7, irrep label, or 'none' for no irrep decomposition")
|
|
||||||
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
Nx, Ny = a.size
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "cd_%s_p%gnmx%gnm_%dx%d_m%s_n%s_k_%g_%g_f%geV_L%d_micro-%s" % (
|
|
||||||
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), str(a.background), a.wavevector[0], a.wavevector[1], a.eV, a.lMax, "SO3" if a.symmetry_adapted is None else a.symmetry_adapted)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, qpms_library_version
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# Check slice ranges and generate all corresponding combinations
|
|
||||||
slicepairs = []
|
|
||||||
slicelabels = set(a.xslice.keys()) | set(a.yslice.keys())
|
|
||||||
for label in slicelabels:
|
|
||||||
rowslices = a.xslice.get(label, None)
|
|
||||||
colslices = a.yslice.get(label, None)
|
|
||||||
# TODO check validity of the slices.
|
|
||||||
if rowslices is None:
|
|
||||||
rowslices = [slice(None, None, None)]
|
|
||||||
if colslices is None:
|
|
||||||
colslices = [slice(None, None, None)]
|
|
||||||
for rs in rowslices:
|
|
||||||
for cs in colslices:
|
|
||||||
slicepairs.append((rs, cs))
|
|
||||||
|
|
||||||
def realdipfieldlabels(yp):
|
|
||||||
if yp == 0: return 'x'
|
|
||||||
if yp == 1: return 'y'
|
|
||||||
if yp == 2: return 'z'
|
|
||||||
raise ValueError
|
|
||||||
def realdipfields(vecgrid, yp):
|
|
||||||
if yp == 1:
|
|
||||||
return vecgrid[...,0] + vecgrid[...,2]
|
|
||||||
if yp == 0:
|
|
||||||
return -1j*(vecgrid[...,0] - vecgrid[...,2])
|
|
||||||
if yp == 2:
|
|
||||||
return vecgrid[...,1]
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
def float_nicestr(x, tol=1e-5):
|
|
||||||
x = float(x)
|
|
||||||
if .5**2 - abs(x) < tol:
|
|
||||||
return(("-" if x < 0 else '+') + "2^{-2}")
|
|
||||||
else:
|
|
||||||
return "%+.3g" % x
|
|
||||||
|
|
||||||
def cplx_nicestr(x, tol=1e-5):
|
|
||||||
x = complex(x)
|
|
||||||
if x == 0:
|
|
||||||
return '0'
|
|
||||||
ret = ""
|
|
||||||
if x.real:
|
|
||||||
ret = ret + float_nicestr(x.real, tol)
|
|
||||||
if x.imag:
|
|
||||||
ret = ret + float_nicestr(x.imag, tol) + 'i'
|
|
||||||
if x.real and x.imag:
|
|
||||||
return '(' + ret + ')'
|
|
||||||
else:
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def cleanarray(a, atol=1e-10, copy=True):
|
|
||||||
a = np.array(a, copy=copy)
|
|
||||||
sieve = abs(a.real) < atol
|
|
||||||
a[sieve] = 1j * a[sieve].imag
|
|
||||||
sieve = abs(a.imag) < atol
|
|
||||||
a[sieve] = a[sieve].real
|
|
||||||
return a
|
|
||||||
|
|
||||||
def nicerot(a, atol=1e-10, copy=True): #gives array a "nice" phase
|
|
||||||
a = np.array(a, copy=copy)
|
|
||||||
i = np.argmax(abs(a))
|
|
||||||
a = a / a[i] * abs(a[i])
|
|
||||||
return a
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
|
||||||
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
|
||||||
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
|
||||||
|
|
||||||
|
|
||||||
omega = ap.omega
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
medium = EpsMuGenerator(ap.background_epsmu)
|
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info['D2h'])
|
|
||||||
ss, ssw = ScatteringSystem.create(particles=particles, medium=medium, omega=omega, sym=sym)
|
|
||||||
|
|
||||||
wavenumber = ap.background_epsmu.k(omega) # Currently, ScatteringSystem does not "remember" frequency nor wavenumber
|
|
||||||
|
|
||||||
# Mapping between ss particles and grid positions
|
|
||||||
positions = ss.positions
|
|
||||||
xpositions = np.unique(positions[:,0])
|
|
||||||
assert(len(xpositions) == Nx)
|
|
||||||
ypositions = np.unique(positions[:,1])
|
|
||||||
assert(len(ypositions == Ny))
|
|
||||||
# particle positions as integer indices
|
|
||||||
posmap = np.empty((positions.shape[0],2), dtype=int)
|
|
||||||
invposmap = np.empty((Nx, Ny), dtype=int)
|
|
||||||
for i, pos in enumerate(positions):
|
|
||||||
posmap[i,0] = np.searchsorted(xpositions, positions[i,0])
|
|
||||||
posmap[i,1] = np.searchsorted(ypositions, positions[i,1])
|
|
||||||
invposmap[posmap[i,0], posmap[i, 1]] = i
|
|
||||||
|
|
||||||
def fullvec2grid(fullvec, swapxy=False):
|
|
||||||
arr = np.empty((Nx,Ny,nelem), dtype=complex)
|
|
||||||
for pi, offset in enumerate(ss.fullvec_poffsets):
|
|
||||||
ix, iy = posmap[pi]
|
|
||||||
arr[ix, iy] = fullvec[offset:offset+nelem]
|
|
||||||
return np.swapaxes(arr, 0, 1) if swapxy else arr
|
|
||||||
|
|
||||||
|
|
||||||
outfile_tmp = defaultprefix + ".tmp" if a.output is None else a.output + ".tmp"
|
|
||||||
|
|
||||||
nelem = len(bspec)
|
|
||||||
phases = np.exp(1j*np.dot(ss.positions[:,:2], np.array(a.wavevector)))
|
|
||||||
driving_full = np.zeros((nelem, ss.fecv_size),dtype=complex)
|
|
||||||
if a.symmetry_adapted is not None:
|
|
||||||
ss1, ssw1 = ScatteringSystem.create(particles=[Particle((0,0,0), ap.tmgen, bspec)], medium=medium, omega=omega,
|
|
||||||
sym=FinitePointGroup(point_group_info[a.symmetry_adapted]))
|
|
||||||
fvcs1 = np.empty((nelem, nelem), dtype=complex)
|
|
||||||
y = 0
|
|
||||||
iris1 = []
|
|
||||||
for iri1 in range(ss1.nirreps):
|
|
||||||
for j in range(ss1.saecv_sizes[iri1]):
|
|
||||||
pvc1 = np.zeros((ss1.saecv_sizes[iri1],), dtype=complex)
|
|
||||||
pvc1[j] = 1
|
|
||||||
fvcs1[y] = ss1.unpack_vector(pvc1, iri1)
|
|
||||||
fvcs1[y] = cleanarray(nicerot(fvcs1[y], copy=False), copy=False)
|
|
||||||
driving_full[y] = (phases[:, None] * fvcs1[y][None,:]).flatten()
|
|
||||||
y += 1
|
|
||||||
iris1.append(iri1)
|
|
||||||
iris1 = np.array(iris1)
|
|
||||||
else:
|
|
||||||
for y in range(nelem):
|
|
||||||
driving_full[y,y::nelem] = phases
|
|
||||||
|
|
||||||
|
|
||||||
# Apply the driving on the specified slices only
|
|
||||||
nsp = len(slicepairs)
|
|
||||||
driving_full_sliced = np.zeros((nsp,) + driving_full.shape, dtype=complex)
|
|
||||||
p1range = np.arange(nelem)
|
|
||||||
for spi in range(nsp):
|
|
||||||
xs, ys = slicepairs[spi]
|
|
||||||
driven_pi = invposmap[xs, ys].flatten()
|
|
||||||
driven_y = ((driven_pi * nelem)[:,None] + p1range[None,:]).flatten()
|
|
||||||
driving_full_sliced[spi][:, driven_y] = driving_full[:, driven_y]
|
|
||||||
|
|
||||||
scattered_full = np.zeros((nsp, nelem, ss.fecv_size),dtype=complex)
|
|
||||||
scattered_ir = [None for iri in range(ss.nirreps)]
|
|
||||||
|
|
||||||
ir_contained = np.ones((nsp, nelem, ss.nirreps), dtype=bool)
|
|
||||||
|
|
||||||
for iri in range(ss.nirreps):
|
|
||||||
logging.info("processing irrep %d/%d" % (iri, ss.nirreps))
|
|
||||||
LU = None # to trigger garbage collection before the next call
|
|
||||||
translation_matrix = None
|
|
||||||
LU = ssw.scatter_solver(iri)
|
|
||||||
logging.info("LU solver created")
|
|
||||||
#translation_matrix = ss.translation_matrix_packed(wavenumber, iri, BesselType.REGULAR) + np.eye(ss.saecv_sizes[iri])
|
|
||||||
#logging.info("auxillary translation matrix created")
|
|
||||||
|
|
||||||
scattered_ir[iri] = np.zeros((nsp, nelem, ss.saecv_sizes[iri]), dtype=complex)
|
|
||||||
scattered_ir_unpacked = np.zeros((nsp, nelem, ss.fecv_size), dtype=complex)
|
|
||||||
|
|
||||||
for spi in range(nsp):
|
|
||||||
for y in range(nelem):
|
|
||||||
ã = driving_full_sliced[spi,y]
|
|
||||||
ãi = cleanarray(ss.pack_vector(ã, iri), copy=False)
|
|
||||||
if np.all(ãi == 0):
|
|
||||||
ir_contained[spi, y, iri] = False
|
|
||||||
continue
|
|
||||||
Tã = ssw.apply_Tmatrices_full(ã)
|
|
||||||
Tãi = ss.pack_vector(Tã, iri)
|
|
||||||
fi = LU(Tãi)
|
|
||||||
scattered_ir[iri][spi, y] = fi
|
|
||||||
scattered_ir_unpacked[spi, y] = ss.unpack_vector(fi, iri)
|
|
||||||
scattered_full[spi, y] += scattered_ir_unpacked[spi, y]
|
|
||||||
if a.save_gradually:
|
|
||||||
iriout = outfile_tmp + ".%d" % iri
|
|
||||||
np.savez(iriout, iri=iri, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
|
||||||
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
|
|
||||||
positions = ss.positions[:,:2],
|
|
||||||
scattered_ir_packed = scattered_ir[iri],
|
|
||||||
scattered_ir_full = scattered_ir_unpacked,
|
|
||||||
)
|
|
||||||
logging.info("partial results saved to %s"%iriout)
|
|
||||||
|
|
||||||
t, l, m = bspec.tlm()
|
|
||||||
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
logging.info("Computing the far fields")
|
|
||||||
if math.isnan(a.ccd_size):
|
|
||||||
a.ccd_size = (50 * a.ccd_distance / (max(Nx*px, Ny*py) *ssw.wavenumber.real))
|
|
||||||
ccd_size = a.ccd_size
|
|
||||||
ccd_x = np.linspace(-ccd_size/2, ccd_size/2, a.ccd_resolution)
|
|
||||||
ccd_y = np.linspace(-ccd_size/2, ccd_size/2, a.ccd_resolution)
|
|
||||||
ccd_grid = np.meshgrid(ccd_x, ccd_y, (a.ccd_distance,), indexing='ij')
|
|
||||||
ccd_points = np.swapaxes(np.stack(ccd_grid, axis=-1).squeeze(axis=-2), 0,1) # First axis is y, second is x, because of imshow...
|
|
||||||
ccd_fields = np.empty((nsp, nelem,) + ccd_points.shape, dtype=complex)
|
|
||||||
for spi in range(nsp):
|
|
||||||
for y in range(nelem):
|
|
||||||
ccd_fields[spi, y] = ssw.scattered_E(scattered_full[spi, y], ccd_points, btyp=BesselType.HANKEL_PLUS)
|
|
||||||
logging.info("Far fields done")
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
|
||||||
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
|
|
||||||
positions = ss.positions[:,:2],
|
|
||||||
scattered_ir_packed = np.array(scattered_ir, dtype=np.object),
|
|
||||||
scattered_full = scattered_full,
|
|
||||||
ir_contained = ir_contained,
|
|
||||||
t=t, l=l, m=m,
|
|
||||||
iris1 = iris1 if (a.symmetry_adapted is not None) else None,
|
|
||||||
irnames1 = ss1.irrep_names if (a.symmetry_adapted is not None) else None,
|
|
||||||
fvcs1 = fvcs1 if (a.symmetry_adapted is not None) else None,
|
|
||||||
#ccd_size = ccd_size if not math.isnan(a.ccd_distance) else None,
|
|
||||||
ccd_points = ccd_points if not math.isnan(a.ccd_distance) else None,
|
|
||||||
ccd_fields = ccd_fields if not math.isnan(a.ccd_distance) else None,
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
|
|
||||||
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt, cm
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
t, l, m = bspec.tlm()
|
|
||||||
phasecm = cm.twilight
|
|
||||||
pmcm = cm.bwr
|
|
||||||
abscm = cm.plasma
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
pp = PdfPages(plotfile)
|
|
||||||
|
|
||||||
for spi in range(nsp):
|
|
||||||
fig, axes = plt.subplots(nelem, 12 if math.isnan(a.ccd_distance) else 16, figsize=(figscale*(12 if math.isnan(a.ccd_distance) else 16), figscale*nelem))
|
|
||||||
for yp in range(0,3): # TODO xy-dipoles instead?
|
|
||||||
axes[0,4*yp+0].set_title("abs / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+1].set_title("arg / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+2].set_title("Fabs / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+3].set_title("Farg / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
#axes[0,12].set_title("$E_{xy}$ @ $z = %g; \phi$" % a.ccd_distance)
|
|
||||||
#axes[0,13].set_title("$E_{xy}$ @ $z = %g; \phi + \pi/2$" % a.ccd_distance)
|
|
||||||
axes[0,12].set_title("$|E_{x}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,13].set_title("$|E_{y}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,14].set_title("$|E_x + E_y|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,15].set_title("$|E_{z}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
for gg in range(12,16):
|
|
||||||
axes[-1,gg].set_xlabel("$x/\mathrm{m}$")
|
|
||||||
|
|
||||||
|
|
||||||
for y in range(nelem):
|
|
||||||
fulvec = scattered_full[spi,y]
|
|
||||||
if a.symmetry_adapted is not None:
|
|
||||||
driving_nonzero_y = [j for j in range(nelem) if abs(fvcs1[y,j]) > 1e-5]
|
|
||||||
driving_descr = ss1.irrep_names[iris1[y]]+'\n'+', '.join(('$'+cplx_nicestr(fvcs1[y,j])+'$' +
|
|
||||||
"(%s,%d,%+d)" % (("E" if t[j] == 2 else "M"), l[j], m[j]) for j in
|
|
||||||
driving_nonzero_y)) # TODO shorten the complex number precision
|
|
||||||
else:
|
|
||||||
driving_descr = "%s,%d,%+d"%('E' if t[y]==2 else 'M', l[y], m[y],)
|
|
||||||
axes[y,0].set_ylabel(driving_descr)
|
|
||||||
axes[y,-1].yaxis.set_label_position("right")
|
|
||||||
axes[y,-1].set_ylabel("$y/\mathrm{m}$\n"+driving_descr)
|
|
||||||
vecgrid = fullvec2grid(fulvec, swapxy=True)
|
|
||||||
vecgrid_ff = np.fft.fftshift(np.fft.fft2(vecgrid, axes=(0,1)),axes=(0,1))
|
|
||||||
lemax = np.amax(abs(vecgrid))
|
|
||||||
for yp in range(0,3):
|
|
||||||
if(np.amax(abs(realdipfields(vecgrid,yp))) > lemax*1e-5):
|
|
||||||
axes[y,yp*4].imshow(abs(realdipfields(vecgrid,yp)), vmin=0, interpolation='none')
|
|
||||||
axes[y,yp*4].text(0.5, 0.5, '%g' % np.amax(abs(realdipfields(vecgrid,yp))), horizontalalignment='center', verticalalignment='center', transform=axes[y,yp*4].transAxes)
|
|
||||||
axes[y,yp*4+1].imshow(np.angle(realdipfields(vecgrid,yp)), vmin=-np.pi, vmax=np.pi, cmap=phasecm, interpolation='none')
|
|
||||||
axes[y,yp*4+2].imshow(abs(realdipfields(vecgrid_ff,yp)), vmin=0, interpolation='none')
|
|
||||||
axes[y,yp*4+3].imshow(np.angle(realdipfields(vecgrid_ff,yp)), vmin=-np.pi, vmax=np.pi, cmap=phasecm, interpolation='none')
|
|
||||||
else:
|
|
||||||
for c in range(0,4):
|
|
||||||
axes[y,yp*4+c].tick_params(bottom=False, left=False, labelbottom=False, labelleft=False)
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
fxye=(-ccd_size/2, ccd_size/2, -ccd_size/2, ccd_size/2)
|
|
||||||
e2vmax = np.amax(np.linalg.norm(ccd_fields[spi,y], axis=-1)**2)
|
|
||||||
xint = abs(ccd_fields[spi,y,...,0])**2
|
|
||||||
yint = abs(ccd_fields[spi,y,...,1])**2
|
|
||||||
xyint = abs(ccd_fields[spi,y,...,0] + ccd_fields[spi,y,...,1])**2
|
|
||||||
zint = abs(ccd_fields[spi,y,...,2])**2
|
|
||||||
xintmax = np.amax(xint)
|
|
||||||
yintmax = np.amax(yint)
|
|
||||||
zintmax = np.amax(zint)
|
|
||||||
xyintmax = np.amax(xyint)
|
|
||||||
axes[y, 12].imshow(xint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 13].imshow(yint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 14].imshow(xyint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 15].imshow(zint, origin='lower', extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 12].text(0.5, 0.5, '%g\n%g' % (xintmax,xintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,12].transAxes)
|
|
||||||
axes[y, 13].text(0.5, 0.5, '%g\n%g' % (yintmax,yintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,13].transAxes)
|
|
||||||
axes[y, 14].text(0.5, 0.5, '%g\n%g' % (xyintmax,xyintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,14].transAxes)
|
|
||||||
axes[y, 15].text(0.5, 0.5, '%g\n%g' % (zintmax,zintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,15].transAxes)
|
|
||||||
for gg in range(12,16):
|
|
||||||
axes[y,gg].yaxis.tick_right()
|
|
||||||
for gg in range(12,15):
|
|
||||||
axes[y,gg].yaxis.set_major_formatter(plt.NullFormatter())
|
|
||||||
fig.text(0, 0, str(slicepairs[spi]), horizontalalignment='left', verticalalignment='bottom')
|
|
||||||
pp.savefig()
|
|
||||||
annotate_pdf_metadata(pp, scriptname="finiterectlat-constant-driving.py")
|
|
||||||
pp.close()
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'background_analytical', 'single_particle', 'single_lMax', ])
|
|
||||||
|
|
||||||
ap.add_argument("-t", "--rank-tolerance", type=float, default=1e11)
|
|
||||||
ap.add_argument("-c", "--min-candidates", type=int, default=1, help='always try at least this many eigenvalue candidates, even if their SVs in the rank tests are lower than rank_tolerance')
|
|
||||||
ap.add_argument("-T", "--residual-tolerance", type=float, default=0.)
|
|
||||||
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
#ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
#ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
#ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
|
|
||||||
ap.add_argument("-f", "--centre", type=complex, required=True, help='Contour centre in eV')
|
|
||||||
ap.add_argument("--ai", type=float, default=0.05, help="Contour imaginary half-axis in eV")
|
|
||||||
ap.add_argument("--ar", type=float, default=0.05, help="Contour real half-axis in eV")
|
|
||||||
ap.add_argument("-N", type=int, default="150", help="Integration contour discretisation size")
|
|
||||||
ap.add_argument("--D2", action='store_true', help="Use D2h symmetry even if the array has square symmetry")
|
|
||||||
|
|
||||||
ap.add_argument("--irrep", type=str, default="none", help="Irrep subspace (irrep index from 0 to 7 (9 for D4h), irrep label, or 'none' for no irrep decomposition")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
Nx, Ny = a.size
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
thegroup = 'D4h' if px == py and Nx == Ny and not a.D2 else 'D2h'
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_%dx%d_m%s_B%s_L%d_c(%s±%g±%gj)eV_cn%d_%s" % (
|
|
||||||
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), str(a.background), a.lMax,
|
|
||||||
str(a.centre), a.ar, a.ai, a.N,
|
|
||||||
thegroup,
|
|
||||||
)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
def inside_ellipse(point_xy, centre_xy, halfaxes_xy):
|
|
||||||
x = point_xy[0] - centre_xy[0]
|
|
||||||
y = point_xy[1] - centre_xy[1]
|
|
||||||
ax = halfaxes_xy[0]
|
|
||||||
ay = halfaxes_xy[1]
|
|
||||||
return ((x/ax)**2 + (y/ay)**2) <= 1
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
|
||||||
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
|
||||||
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
|
||||||
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
medium = EpsMuGenerator(ap.background_epsmu)
|
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info[thegroup])
|
|
||||||
logging.info("Creating scattering system object")
|
|
||||||
ss, ssw = ScatteringSystem.create(particles, medium, a.centre * eh, sym=sym)
|
|
||||||
|
|
||||||
if a.irrep == 'none':
|
|
||||||
iri = None # no irrep decomposition
|
|
||||||
irname = 'full'
|
|
||||||
logging.info("Not performing irrep decomposition and working with the full space of dimension %d." % ss.fecv_size)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
iri = int(a.irrep)
|
|
||||||
except ValueError:
|
|
||||||
iri = ss.irrep_names.index(a.irrep)
|
|
||||||
irname = ss.irrep_names[iri]
|
|
||||||
logging.info("Using irrep subspace %s (iri = %d) of dimension %d." % (irname, iri, ss.saecv_sizes[iri]))
|
|
||||||
|
|
||||||
outfile_tmp = defaultprefix + ".tmp" if a.output is None else a.output + ".tmp"
|
|
||||||
|
|
||||||
logging.info("Starting Beyn's algorithm")
|
|
||||||
results = ss.find_modes(iri=iri, omega_centre = a.centre*eh, omega_rr=a.ar*eh, omega_ri=a.ai*eh, contour_points=a.N,
|
|
||||||
rank_tol=a.rank_tolerance, rank_min_sel=a.min_candidates, res_tol=a.residual_tolerance)
|
|
||||||
results['inside_contour'] = inside_ellipse((results['eigval'].real, results['eigval'].imag),
|
|
||||||
(a.centre.real*eh, a.centre.imag*eh), (a.ar*eh, a.ai*eh))
|
|
||||||
results['refractive_index_internal'] = [medium(om).n for om in results['eigval']]
|
|
||||||
|
|
||||||
outfile = defaultprefix + (('_ir%s_%s.npz' % (str(iri), irname)) if iri is not None else '.npz') if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, **results)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
# TODO plots.
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
ax.plot(sinalpha_list, σ_ext*1e12,label='$\sigma_\mathrm{ext}$')
|
|
||||||
ax.plot(sinalpha_list, σ_scat*1e12, label='$\sigma_\mathrm{scat}$')
|
|
||||||
ax.plot(sinalpha_list, σ_abs*1e12, label='$\sigma_\mathrm{abs}$')
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel('$\sin\\alpha$')
|
|
||||||
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='finiterectlat-modes.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,239 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
import math
|
|
||||||
pi = math.pi
|
|
||||||
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.qpms_p import cart2sph, sph2cart, sph_loccart2cart, sph_loccart_basis
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
Nx, Ny = a.size
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_%dx%d_m%s_bg%s_φ%gπ_θ(%g_%g)π_ψ%gπ_χ%gπ_f%s_L%d" % (
|
|
||||||
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), str(a.background), a.phi/pi, np.amin(a.theta)/pi, np.amax(a.theta)/pi, a.psi/pi, a.chi/pi, ap.omega_descr, a.lMax, )
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
|
||||||
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
|
||||||
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec=bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info['D2h'])
|
|
||||||
ss, ssw = ScatteringSystem.create(particles, ap.background_emg, ap.allomegas[0], sym=sym)
|
|
||||||
|
|
||||||
|
|
||||||
## Plane wave data
|
|
||||||
a.theta = np.atleast_1d(np.array(a.theta))
|
|
||||||
dir_sph_list = np.stack((np.broadcast_to(1, a.theta.shape), a.theta, np.broadcast_to(a.phi, a.theta.shape)), axis=-1)
|
|
||||||
sψ, cψ = math.sin(a.psi), math.cos(a.psi)
|
|
||||||
sχ, cχ = math.sin(a.chi), math.cos(a.chi)
|
|
||||||
E_sph = (0., cψ*cχ + 1j*sψ*sχ, sψ*cχ + 1j*cψ*sχ)
|
|
||||||
|
|
||||||
dir_cart_list = sph2cart(dir_sph_list)
|
|
||||||
E_cart_list = sph_loccart2cart(E_sph, dir_sph_list)
|
|
||||||
|
|
||||||
nfreq = len(ap.allomegas)
|
|
||||||
ndir = a.theta.shape[0]
|
|
||||||
|
|
||||||
k_cart_arr = np.empty((nfreq, ndir, 3), dtype=float)
|
|
||||||
wavenumbers = np.empty((nfreq,), dtype=float)
|
|
||||||
|
|
||||||
σ_ext_arr_ir = np.empty((nfreq, ndir, ss.nirreps), dtype=float)
|
|
||||||
σ_scat_arr_ir = np.empty((nfreq, ndir, ss.nirreps), dtype=float)
|
|
||||||
|
|
||||||
outfile_tmp = defaultprefix + ".tmp" if a.output is None else a.output + ".tmp"
|
|
||||||
|
|
||||||
for i, omega in enumerate(ap.allomegas):
|
|
||||||
logging.info("Processing frequency %g eV" % (omega / eV,))
|
|
||||||
if i != 0:
|
|
||||||
ssw = ss(omega)
|
|
||||||
if ssw.wavenumber.imag != 0:
|
|
||||||
warnings.warn("The background medium wavenumber has non-zero imaginary part. Don't expect emaningful results for cross sections.")
|
|
||||||
wavenumber = ssw.wavenumber.real
|
|
||||||
wavenumbers[i] = wavenumber
|
|
||||||
|
|
||||||
k_sph_list = np.array(dir_sph_list, copy=True)
|
|
||||||
k_sph_list[:,0] = wavenumber
|
|
||||||
|
|
||||||
k_cart_arr[i] = sph2cart(k_sph_list)
|
|
||||||
|
|
||||||
for iri in range(ss.nirreps):
|
|
||||||
logging.info("processing irrep %d/%d" % (iri, ss.nirreps))
|
|
||||||
LU = None # to trigger garbage collection before the next call
|
|
||||||
translation_matrix = None
|
|
||||||
LU = ssw.scatter_solver(iri)
|
|
||||||
logging.info("LU solver created")
|
|
||||||
translation_matrix = ssw.translation_matrix_packed(iri, BesselType.REGULAR) + np.eye(ss.saecv_sizes[iri])
|
|
||||||
logging.info("auxillary translation matrix created")
|
|
||||||
|
|
||||||
for j in range(ndir):
|
|
||||||
k_cart = k_cart_arr[i,j]
|
|
||||||
# the following two could be calculated only once, but probably not a big deal
|
|
||||||
ã = ss.planewave_full(k_cart=k_cart_arr[i,j], E_cart=E_cart_list[j])
|
|
||||||
Tã = ssw.apply_Tmatrices_full(ã)
|
|
||||||
|
|
||||||
Tãi = ss.pack_vector(Tã, iri)
|
|
||||||
ãi = ss.pack_vector(ã, iri)
|
|
||||||
fi = LU(Tãi)
|
|
||||||
σ_ext_arr_ir[i, j, iri] = -np.vdot(ãi, fi).real/wavenumber**2
|
|
||||||
σ_scat_arr_ir[i, j, iri] = np.vdot(fi,np.dot(translation_matrix, fi)).real/wavenumber**2
|
|
||||||
if a.save_gradually:
|
|
||||||
iriout = outfile_tmp + ".%d.%d" % (i, iri)
|
|
||||||
np.savez(iriout, omegai=i, iri=iri, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omega=omega, k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph),
|
|
||||||
wavenumber=wavenumber, σ_ext_list_ir=σ_ext_arr_ir[i,:,iri], σ_scat_list_ir=σ_scat_list_ir[i,:,iri])
|
|
||||||
logging.info("partial results saved to %s"%iriout)
|
|
||||||
|
|
||||||
σ_abs_arr_ir = σ_ext_arr_ir - σ_scat_arr_ir
|
|
||||||
σ_abs_arr = np.sum(σ_abs_arr_ir, axis=-1)
|
|
||||||
σ_scat_arr = np.sum(σ_scat_arr_ir, axis=-1)
|
|
||||||
σ_ext_arr = np.sum(σ_ext_arr_ir, axis=-1)
|
|
||||||
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
|
||||||
k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph),
|
|
||||||
σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr,
|
|
||||||
σ_ext_ir=σ_ext_arr_ir,σ_abs_ir=σ_abs_arr_ir,σ_scat_ir=σ_scat_arr_ir, omega=ap.allomegas, wavenumbers=wavenumbers
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from scipy.interpolate import griddata
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
ipm = 'nearest'
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
if False: #len(ap.omega_ranges) != 0:
|
|
||||||
# angle plot ---------------------------------
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = max(np.amax(σ_ext_arr), np.amax(σ_scat_arr), np.amax(σ_abs_arr))
|
|
||||||
vmin = min(np.amin(σ_ext_arr), np.amin(σ_scat_arr), np.amin(σ_abs_arr))
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_ext_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_scat_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
im = ax.pcolormesh(a.theta, ap.allomegas/eh, σ_abs_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
if len(ap.omega_ranges) != 0:
|
|
||||||
# "k-space" plot -----------------------------
|
|
||||||
domega = np.amin(np.diff(ap.allomegas))
|
|
||||||
dsintheta = np.amin(abs(np.diff(sintheta)))
|
|
||||||
dk = dsintheta * wavenumbers[0]
|
|
||||||
|
|
||||||
# target image grid
|
|
||||||
grid_y, grid_x = np.mgrid[ap.allomegas[0] : ap.allomegas[-1] : domega, np.amin(sintheta) * wavenumbers[-1] : np.amax(sintheta) * wavenumbers[-1] : dk]
|
|
||||||
imextent = (np.amin(sintheta) * wavenumbers[-1] / 1e6, np.amax(sintheta) * wavenumbers[-1] / 1e6, ap.allomegas[0] / eh, ap.allomegas[-1] / eh)
|
|
||||||
|
|
||||||
# source coordinates for griddata
|
|
||||||
ktheta = sintheta[None, :] * wavenumbers[:, None]
|
|
||||||
omegapoints = np.broadcast_to(ap.allomegas[:, None], ktheta.shape)
|
|
||||||
points = np.stack( (ktheta.flatten(), omegapoints.flatten()), axis = -1)
|
|
||||||
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = np.amax(σ_ext_arr)
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
grid_z = griddata(points, σ_ext_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
grid_z = griddata(points, σ_scat_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
grid_z = griddata(points, σ_abs_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
im = ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
for omega in ap.omega_singles:
|
|
||||||
i = np.searchsorted(ap.allomegas, omega)
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
fig.suptitle("%g eV" % (omega / eh))
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
ax.plot(sintheta, σ_ext_arr[i]*1e12,label='$\sigma_\mathrm{ext}$')
|
|
||||||
ax.plot(sintheta, σ_scat_arr[i]*1e12, label='$\sigma_\mathrm{scat}$')
|
|
||||||
ax.plot(sintheta, σ_abs_arr[i]*1e12, label='$\sigma_\mathrm{abs}$')
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel('$\sin\\theta$')
|
|
||||||
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname="finiterectlat-scatter.py")
|
|
||||||
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -0,0 +1,376 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse, re, random, string, sys
|
||||||
|
import subprocess
|
||||||
|
import warnings
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
unitcell_size = 1 # rectangular lattice
|
||||||
|
unitcell_indices = tuple(range(unitcell_size))
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', '-p', '-o', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
parser.add_argument('--nosuffix', action='store_true', help='Do not add dimension metadata to the output filenames')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
#parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--dx', action='store', type=float, required=True, help='x-direction lattice constant')
|
||||||
|
parser.add_argument('--dy', action='store', type=float, required=True, help='y-direction lattice constant')
|
||||||
|
|
||||||
|
parser.add_argument('--Nx', '--nx', action='store', type=int, required=True, help='Lattice points in the x-direction')
|
||||||
|
parser.add_argument('--Ny', '--ny', action='store', type=int, required=True, help='Lattice points in the y-direction')
|
||||||
|
|
||||||
|
# In these default settings, the area is 2x2 times larger than first BZ
|
||||||
|
parser.add_argument('--kxmin', action='store', type=float, default=-1., help='TODO')
|
||||||
|
parser.add_argument('--kxmax', action='store', type=float, default=1., help='TODO')
|
||||||
|
parser.add_argument('--kymin', action='store', type=float, default=-1., help='TODO')
|
||||||
|
parser.add_argument('--kymax', action='store', type=float, default=1., help='TODO')
|
||||||
|
|
||||||
|
#parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--kxdensity', action='store', type=int, default=51, help='k-space resolution in the x-direction')
|
||||||
|
parser.add_argument('--kydensity', action='store', type=int, default=51, help='k-space resolution in the y-direction')
|
||||||
|
|
||||||
|
partgrp = parser.add_mutually_exclusive_group()
|
||||||
|
partgrp.add_argument('--only_TE', action='store_true', help='Calculate only the projection on the E⟂z modes')
|
||||||
|
partgrp.add_argument('--only_TM', action='store_true', help='Calculate only the projection on the E∥z modes')
|
||||||
|
partgrp.add_argument('--serial', action='store_true', help='Calculate the TE and TM parts separately to save memory')
|
||||||
|
|
||||||
|
parser.add_argument('--nocentre', action='store_true', help='Place the coordinate origin to the left bottom corner rather that to the centre of the array')
|
||||||
|
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=3000, help='Number of k-points per output file (default 3000)')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
#parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--tr%d'%i, dest='ops', action=make_action_sharedlist('tr%d'%i, 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--sym%d'%i, dest='ops', action=make_action_sharedlist('sym%d'%i, 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--multl%d'%i, dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl%d'%i, 'ops'))
|
||||||
|
#popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
if pargs.verbose:
|
||||||
|
print(pargs, file = sys.stderr)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
dy = pargs.dy
|
||||||
|
dx = pargs.dx
|
||||||
|
Ny = pargs.Ny
|
||||||
|
Nx = pargs.Nx
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
#gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kxdensity = pargs.kxdensity
|
||||||
|
kydensity = pargs.kydensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else unitcell_indices, opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
if(verbose):
|
||||||
|
print(ops, file = sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
refind = math.sqrt(epsilon_b)
|
||||||
|
cdn = c / refind
|
||||||
|
k_0 = freq * refind / c # = freq / cdn
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),unitcell_size,2,nelem,2,nelem)) )
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
#targets = (0,1)
|
||||||
|
targets = unitcell_indices
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
xpositions = np.arange(Nx) * dx
|
||||||
|
ypositions = np.arange(Ny) * dy
|
||||||
|
if not pargs.nocentre:
|
||||||
|
xpositions -= Nx * dx / 2
|
||||||
|
ypositions -= Ny * dy / 2
|
||||||
|
xpositions, ypositions = np.meshgrid(xpositions, ypositions, indexing='ij', copy=False)
|
||||||
|
positions=np.stack((xpositions.ravel(),ypositions.ravel()), axis=-1)
|
||||||
|
positions=positions[np.random.permutation(len(positions))]
|
||||||
|
N = positions.shape[0]
|
||||||
|
|
||||||
|
kx = np.linspace(pargs.kxmin, pargs.kxmax, num=pargs.kxdensity, endpoint=True) * 2*np.pi / dx
|
||||||
|
ky = np.linspace(pargs.kymin, pargs.kymax, num=pargs.kydensity, endpoint=True) * 2*np.pi / dy
|
||||||
|
kx, ky = np.meshgrid(kx, ky, indexing='ij', copy=False)
|
||||||
|
kz = np.sqrt(k_0**2 - (kx ** 2 + ky ** 2))
|
||||||
|
|
||||||
|
klist_full = np.stack((kx,ky,kz), axis=-1).reshape((-1,3))
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.size / 3 / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points' % klist_full.size + ('in %d chunks'%chunkn) if chunkn>1 else '' , file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = qpms.__version__
|
||||||
|
except NameError:
|
||||||
|
version = None
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'script': os.path.basename(__file__),
|
||||||
|
'version': version,
|
||||||
|
'type' : 'Plane wave scattering on a finite rectangular lattice',
|
||||||
|
'lMax' : lMax,
|
||||||
|
'dx' : dx,
|
||||||
|
'dy' : dy,
|
||||||
|
'Nx' : Nx,
|
||||||
|
'Ny' : Ny,
|
||||||
|
#'maxlayer' : maxlayer,
|
||||||
|
#'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
#'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'chunki' : 0,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
'centred' : not pargs.nocentre
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
scat = qpms.Scattering_2D_zsym(positions, TMatrices_om, k_0, verbose=verbose)
|
||||||
|
|
||||||
|
if pargs.only_TE:
|
||||||
|
actions = (0,)
|
||||||
|
elif pargs.only_TM:
|
||||||
|
actions = (1,)
|
||||||
|
elif pargs.serial:
|
||||||
|
actions = (0,1)
|
||||||
|
else:
|
||||||
|
actions = (None,)
|
||||||
|
|
||||||
|
xu = np.array((1,0,0))
|
||||||
|
yu = np.array((0,1,0))
|
||||||
|
zu = np.array((0,0,1))
|
||||||
|
TEč, TMč = qpms.symz_indexarrays(lMax)
|
||||||
|
|
||||||
|
klist_full_2D = klist_full[...,:2]
|
||||||
|
klist_full_dir = klist_full/np.linalg.norm(klist_full, axis=-1, keepdims=True)
|
||||||
|
for action in actions:
|
||||||
|
if action is None:
|
||||||
|
scat.prepare(verbose=verbose)
|
||||||
|
actionstring = ''
|
||||||
|
else:
|
||||||
|
scat.prepare_partial(action, verbose=verbose)
|
||||||
|
actionstring = '.TM' if action else '.TE'
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
sbtime = _time_b(verbose, step='Solving the scattering problem, chunk %d'%chunki+actionstring)
|
||||||
|
if pargs.nosuffix:
|
||||||
|
outfile = pargs.output_prefix + actionstring + (
|
||||||
|
('.%03d' % chunki) if chunkn > 1 else '')
|
||||||
|
else:
|
||||||
|
outfile = '%s_%dx%d_%.0fnmx%.0fnm_%.4f%s%s.npz' % (
|
||||||
|
pargs.output_prefix, Nx, Ny, dx/1e-9, dy/1e-9,
|
||||||
|
eVfreq, actionstring,
|
||||||
|
(".%03d" % chunki) if chunkn > 1 else '')
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
klist2d = klist_full_2D[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
klistdir = klist_full_dir[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
'''
|
||||||
|
The following loop is a fuckup that has its roots in the fact that
|
||||||
|
the function qpms.get_π̃τ̃_y1 in qpms_p.py is not vectorized
|
||||||
|
(and consequently, neither is plane_pq_y.)
|
||||||
|
|
||||||
|
And Scattering_2D_zsym.scatter_partial is not vectorized, either.
|
||||||
|
'''
|
||||||
|
if action == 0 or action is None:
|
||||||
|
xresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
yresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
if action == 1 or action is None:
|
||||||
|
zresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
for i in range(klist.shape[0]):
|
||||||
|
if math.isnan(klist[i,2]):
|
||||||
|
if(verbose):
|
||||||
|
print("%d. momentum %s invalid (k_0=%f), skipping" % (i, str(klist[i]),k_0))
|
||||||
|
continue
|
||||||
|
kdir = klistdir[i]
|
||||||
|
phases = np.exp(-1j*np.sum(klist2d[i] * positions, axis=-1))
|
||||||
|
if action == 0 or action is None:
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, xu)).ravel()[TEč] * phases[:, nx]
|
||||||
|
xresult[i] = scat.scatter_partial(0, pq)
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, yu)).ravel()[TEč] * phases[:, nx]
|
||||||
|
yresult[i] = scat.scatter_partial(0, pq)
|
||||||
|
if action == 1 or action is None:
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, zu)).ravel()[TMč] * phases[:, nx]
|
||||||
|
zresult[i] = scat.scatter_partial(1, pq)
|
||||||
|
_time_e(sbtime, verbose, step='Solving the scattering problem, chunk %d'%chunki+actionstring)
|
||||||
|
|
||||||
|
metadata[()]['chunki'] = chunki
|
||||||
|
if action is None:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_x=xresult,
|
||||||
|
ab_y=yresult,
|
||||||
|
ab_z=zresult
|
||||||
|
)
|
||||||
|
elif action == 0:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_x=xresult,
|
||||||
|
ab_y=yresult,
|
||||||
|
)
|
||||||
|
elif action == 1:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_z=zresult
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if outfile:
|
||||||
|
subprocess.run(['scp', outfile, scp_dest])
|
||||||
|
scat.forget_matrices() # free memory in case --serial was used
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
|
@ -0,0 +1,340 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
'''
|
||||||
|
Bulk SVD mode computation for compact scatterer 2D lattices
|
||||||
|
'''
|
||||||
|
|
||||||
|
__TODOs__ = '''
|
||||||
|
BIG TODO: Use more efficient way to calculate the interaction sums: perhaps some customized Ewald-type summation?
|
||||||
|
|
||||||
|
Small TODOs:
|
||||||
|
- Implement a more user-friendly way to define the lattice base vectors and positions of the particles.
|
||||||
|
cf. https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string/2371789
|
||||||
|
- low priority: allow to perform some more custom operations on T-Matrix, using some kind of parsing from the previous point
|
||||||
|
- Autodetect symmetries
|
||||||
|
|
||||||
|
'''
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
#TODO create some user-friendlier way to define lattice vectors, cf. https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string/2371789
|
||||||
|
parser.add_argument('--lattice_base', nargs=4, action='store', type=float, required=True, help='Lattice basis vectors x1, y1, x2, y2')
|
||||||
|
parser.add_argument('--particle', '-p', nargs='+', action=make_action_sharedlist('particle', 'particlespec'), help='Particle label, coordinates x,y, and (optionally) path to the T-Matrix.')
|
||||||
|
parser.add_argument('--TMatrix', '-t', nargs='+', action=make_action_sharedlist('TMatrix_path', 'particlespec'), help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
#DEL parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', '--k_density', action='store', type=int, default=33, help='Number of k-points per x-axis segment FIXME DESCRIPTION')
|
||||||
|
parser.add_argument('--bz_coverage', action='store', type=float, default=1., help='Brillouin zone coverage in relative length (default 1 for whole 1. BZ)')
|
||||||
|
parser.add_argument('--bz_edge_width', action='store', type=float, default=0., help='Width of the more densely covered belt along the 1. BZ edge in relative lengths')
|
||||||
|
parser.add_argument('--bz_edge_factor', action='store', type=float, default=8., help='Relative density of the belt along the 1. BZ edge w.r.t. k_density (default==8)')
|
||||||
|
parser.add_argument('--bz_edge_twoside', action='store_true', help='Compute also the parts of the densely covered edge belt outside the 1. BZ')
|
||||||
|
parser.add_argument('--bz_corner_width', action='store', type=float, default=0., help='Size of the more densely covered subcell along the 1. BZ corners in relative lengths')
|
||||||
|
parser.add_argument('--bz_corner_factor', action='store', type=float, default=16., help='Relative density of the subcell along the 1. BZ corner w.r.t. k_density (default==16)')
|
||||||
|
parser.add_argument('--bz_corner_twoside', action='store_true', help='Compute also the parts of the densely covered subcell outside the 1. BZ')
|
||||||
|
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=1000, help='Number of k-points per output file (default 1000)')
|
||||||
|
parser.add_argument('--lMax', action=make_action_sharedlist('lMax', 'particlespec'), nargs=+, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', nargs='+', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--sym', dest='ops', nargs='+', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
exit(0) ###
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
#DEL hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
|
||||||
|
#DEL TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
#### Nanoparticle position and T-matrix path parsing ####
|
||||||
|
TMatrix_paths = dict()
|
||||||
|
lMax_overrides = dict()
|
||||||
|
default_TMatrix_path = None
|
||||||
|
default_lMax_override = None
|
||||||
|
if not any((arg_type == 'particle') in (arg_type, arg_content) for in pargs.particlespec):
|
||||||
|
# no particles positions given: suppose only one per unit cell, in the cell origin
|
||||||
|
positions = {None: (0.0)}
|
||||||
|
else:
|
||||||
|
positions = dict()
|
||||||
|
for arg_type, arg_content in pargs.particlespec:
|
||||||
|
if arg_type == 'particle' # --particle option
|
||||||
|
if 3 <= len(arg_content) <= 4:
|
||||||
|
try:
|
||||||
|
positions[arg_content[0]] = (float(arg_content[1]), float(arg_content[2]))
|
||||||
|
except ValueError as e:
|
||||||
|
e.args += ("second and third argument of --particle must be valid floats, given: ", arg_content)
|
||||||
|
raise
|
||||||
|
if len(arg_content == 4):
|
||||||
|
if arg_content[0] in TMatrix_paths:
|
||||||
|
warnings.warn('T-matrix path for particle \'%s\' already specified.'
|
||||||
|
'Overriding with the last value.' % arg_content[0], SyntaxWarning)
|
||||||
|
TMatrix_paths[arg_content[0]] = arg_content[3]
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError("--particle expects 3 or 4 arguments, %d given: " % len(arg_content), arg_content)
|
||||||
|
elif arg_type == 'TMatrix_path': # --TMatrix option
|
||||||
|
if len(arg_content) == 1: # --TMatrix default_path
|
||||||
|
if default_TMatrix_path is not None:
|
||||||
|
warnings.warn('Default T-matrix path already specified. Overriding with the last value.', SyntaxWarning)
|
||||||
|
default_TMatrix_path = arg_content[0]
|
||||||
|
elif len(arg_content) > 1: # --TMatrix label [label2 [...]] path
|
||||||
|
for label in arg_content[:-1]:
|
||||||
|
if label in TMatrix_paths.keys():
|
||||||
|
warnings.warn('T-matrix path for particle \'%s\' already specified.'
|
||||||
|
'Overriding with the last value.' % label, SyntaxWarning)
|
||||||
|
TMatrix_paths[label] = arg_content[-1]
|
||||||
|
elif arg_type == 'lMax': # --lMax option
|
||||||
|
if len(arg_content) == 1: # --lMax default_lmax_override
|
||||||
|
if default_lMax_override is not None:
|
||||||
|
warnings.warn('Default lMax override value already specified. Overriding the last value.', SyntaxWarning)
|
||||||
|
default_lMax_override = int(arg_content[-1])
|
||||||
|
else:
|
||||||
|
for label in arg_content[:-1]:
|
||||||
|
if label in lMax_overrides.keys:
|
||||||
|
warnings.warn('lMax override for particle \'%s\' already specified.'
|
||||||
|
'overriding with the last value.' % label, SyntaxWarning)
|
||||||
|
lMax_overrides[label] = int(arg_content[-1])
|
||||||
|
else: assert False, 'unknown option type'
|
||||||
|
# Check the info from positions and TMatrix_paths and lMax_overrides
|
||||||
|
if not set(TMatrix_paths.keys()) <= set(positions.keys()):
|
||||||
|
raise ValueError("T-Matrix path(s) for particle(s) labeled %s was given, but not their positions"
|
||||||
|
% str(set(TMatrix_paths.keys()) - set(positions.keys())))
|
||||||
|
if not set(lMax_overrides.keys()) <= set(positions.keys()):
|
||||||
|
raise ValueError("lMax override(s) for particle(s) labeled %s was given, but not their positions"
|
||||||
|
%str(set(lMax_overrides.keys()) - set(positions.keys())))
|
||||||
|
if (set(TMatrix_paths.keys()) != set(positions.keys())) and default_TMatrix_path is None:
|
||||||
|
raise ValueError("Position(s) of particles(s) labeled %s was given without their T-matrix"
|
||||||
|
" and no default T-matrix was specified"
|
||||||
|
% str(set(positions.keys()) - set(TMatrix_paths_keys())))
|
||||||
|
for path in TMatrix_paths.values():
|
||||||
|
if not os.path.exists(path):
|
||||||
|
raise ValueError("Cannot access T-matrix file %s. Does it exist?" % path)
|
||||||
|
|
||||||
|
# Assign (pre-parse) the T-matrix operations to individual particles
|
||||||
|
ops = dict()
|
||||||
|
for label in positions.keys(): ops[label] = list()
|
||||||
|
for optype, arg_content in pargs.ops:
|
||||||
|
# if, no label given, apply to all, otherwise on the specifield particles
|
||||||
|
for label in (positions.keys() if len(arg_content) == 1 else arg_content[:-1]):
|
||||||
|
try:
|
||||||
|
ops[label].append((optype, arg_content[-1]))
|
||||||
|
except KeyError as e:
|
||||||
|
e.args += 'Specified operation on undefined particle labeled \'%s\'' % label
|
||||||
|
raise
|
||||||
|
|
||||||
|
print(sys.stderr, "ops: ", ops) #DEBUG
|
||||||
|
|
||||||
|
#### Collect all the info about the particles / their T-matrices into one list ####
|
||||||
|
# Enumerate and assign all the _different_ T-matrices (without any intelligent group-theory checking, though)
|
||||||
|
TMatrix_specs = dict((spec, number)
|
||||||
|
for (number, spec) in enumerate(set(
|
||||||
|
(lMax_overrides[label] if label in lMax_overrides.keys() else None,
|
||||||
|
TMatrix_paths[label],
|
||||||
|
tuple(ops[label]))
|
||||||
|
for label in positions.keys()
|
||||||
|
)))
|
||||||
|
# particles_specs contains (label, (xpos, ypos), tmspec_index per element)
|
||||||
|
particles_specs = [(label, positions(label),
|
||||||
|
TMatrix_specs[(lMax_overrides[label] if label in lMax_overrides.keys() else None,
|
||||||
|
TMatrix_paths[label],
|
||||||
|
tuple(ops[label]))]
|
||||||
|
) for label in positions.keys()]
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise ValueError('\'%d\' is not an implemented symmetry operation' % op[2])
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise ValueError('\'%d\' is not an implemented T-matrix transformation operation' % op[2])
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
klist_full = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.shape[0] / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points in %d chunks' % (klist_full.shape[0], chunkn), file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'lMax' : lMax,
|
||||||
|
'maxlayer' : maxlayer,
|
||||||
|
'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
})
|
||||||
|
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
svdout = '%s_%dnm_%.4f_c%03d.npz' % (pargs.output_prefix, hexside/1e-9, eVfreq, chunki)
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=False, verbose=verbose)
|
||||||
|
|
||||||
|
#((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
|
||||||
|
np.savez(svdout, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
uTE = svdres[0][0],
|
||||||
|
vTE = svdres[0][2],
|
||||||
|
sTE = svdres[0][1],
|
||||||
|
uTM = svdres[1][0],
|
||||||
|
vTM = svdres[1][2],
|
||||||
|
sTM = svdres[1][1],
|
||||||
|
|
||||||
|
)
|
||||||
|
svdres=None
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
||||||
|
#print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,35 @@
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
from numpy import newaxis as nx
|
||||||
|
import math
|
||||||
|
import cmath
|
||||||
|
import os
|
||||||
|
from scipy.constants import c, e as eV, hbar
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("omega")
|
||||||
|
#parser.add_argument("maxlayer")
|
||||||
|
args = parser.parse_args()
|
||||||
|
omega_eV = float(args.omega)
|
||||||
|
|
||||||
|
print(omega_eV)
|
||||||
|
|
||||||
|
epsilon_b = 2.3104
|
||||||
|
hexside = 375e-9
|
||||||
|
lMax = 3
|
||||||
|
maxlayer = 222
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
|
||||||
|
omega = omega_eV * eV / hbar
|
||||||
|
|
||||||
|
k_0 = omega * math.sqrt(epsilon_b) / c
|
||||||
|
|
||||||
|
output_prefix = '/tmp/diracpoints-newdata2/%d/' % maxlayer
|
||||||
|
|
||||||
|
os.makedirs(output_prefix, exist_ok=True)
|
||||||
|
qpms.hexlattice_precalc_AB_save(file=output_prefix+str(omega_eV), lMax=lMax, k_hexside=k_0*hexside,
|
||||||
|
maxlayer=maxlayer, savepointinfo=True)
|
|
@ -1,128 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq'])
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-s", "--singular_values", type=int, default=10, help="Number of singular values to plot")
|
|
||||||
ap.add_argument("--D2", action='store_true', help="Use D2h symmetry even if the x and y periods are equal")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
#Important! The particles are supposed to be of D2h/D4h symmetry
|
|
||||||
thegroup = 'D4h' if px == py and not a.D2 else 'D2h'
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_m%s_bg%s_f(%g..%g..%g)eV_L%d_SVGamma" % (
|
|
||||||
particlestr, px*1e9, py*1e9, str(a.material), str(a.background), *(a.eV_seq), a.lMax)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# not used; TODO:
|
|
||||||
irrep_labels = {"B2''":"$B_2''$",
|
|
||||||
"B2'":"$B_2'$",
|
|
||||||
"A1''":"$A_1''$",
|
|
||||||
"A1'":"$A_1'$",
|
|
||||||
"A2''":"$A_2''$",
|
|
||||||
"B1''":"$B_1''$",
|
|
||||||
"A2'":"$A_2'$",
|
|
||||||
"B1'":"$B_1'$",
|
|
||||||
"E'":"$E'$",
|
|
||||||
"E''":"$E''$",}
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = [0]
|
|
||||||
orig_y = [0]
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)
|
|
||||||
|
|
||||||
omegas = ap.omegas
|
|
||||||
|
|
||||||
logging.info("%d frequencies from %g to %g eV" % (len(omegas), omegas[0]/eh, omegas[-1]/eh))
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
nelem = len(bspec)
|
|
||||||
# The parameters here should probably be changed (needs a better qpms_c.Particle implementation)
|
|
||||||
pp = Particle(orig_xy[0][0], ap.tmgen, bspec=bspec)
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create([pp], ap.background_emg, omegas[0], latticebasis=ap.direct_basis)
|
|
||||||
k = np.array([0.,0.,0])
|
|
||||||
# Auxillary finite scattering system for irrep decomposition, quite a hack
|
|
||||||
ss1, ssw1 = ScatteringSystem.create([pp], ap.background_emg, omegas[0],sym=FinitePointGroup(point_group_info[thegroup]))
|
|
||||||
|
|
||||||
wavenumbers = np.empty(omegas.shape)
|
|
||||||
SVs = [None] * ss1.nirreps
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
SVs[iri] = np.empty(omegas.shape+(ss1.saecv_sizes[iri],))
|
|
||||||
for i, omega in enumerate(omegas):
|
|
||||||
ssw = ss(omega)
|
|
||||||
wavenumbers[i] = ssw.wavenumber.real
|
|
||||||
if ssw.wavenumber.imag:
|
|
||||||
warnings.warn("Non-zero imaginary wavenumber encountered")
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow; maybe not needed
|
|
||||||
ImTW = ssw.modeproblem_matrix_full(k)
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
if ss1.saecv_sizes[iri] == 0:
|
|
||||||
continue
|
|
||||||
ImTW_packed = ss1.pack_matrix(ImTW, iri)
|
|
||||||
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
cc = plt.rcParams['axes.prop_cycle']()
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
cargs = next(cc)
|
|
||||||
nlines = min(a.singular_values, ss1.saecv_sizes[iri])
|
|
||||||
for i in range(nlines):
|
|
||||||
ax.plot(omegas/eh, SVs[iri][:,-1-i],
|
|
||||||
label= None if i else irrep_labels[ss1.irrep_names[iri]],
|
|
||||||
**cargs)
|
|
||||||
ax.set_ylim([0,1.1])
|
|
||||||
ax.set_xlabel('$\hbar \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('Singular values')
|
|
||||||
ax.legend()
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='infiniterectlat-k0realfreqsvd.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
pi = math.pi
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
#ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.qpms_p import cart2sph, sph2cart, sph_loccart2cart, sph_loccart_basis
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_m%s_bg%s_φ%g_θ(%g_%g)π_ψ%gπ_χ%gπ_f%s_L%d" % (
|
|
||||||
particlestr, px*1e9, py*1e9, str(a.material), str(a.background), a.phi/pi, np.amin(a.theta)/pi, np.amax(a.theta)/pi, a.psi/pi, a.chi/pi, ap.omega_descr, a.lMax)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = [0]
|
|
||||||
orig_y = [0]
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
# The parameters here should probably be changed (needs a better qpms_c.Particle implementation)
|
|
||||||
pp = Particle(orig_xy[0][0], ap.tmgen, bspec=bspec)
|
|
||||||
par = [pp]
|
|
||||||
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(par, ap.background_emg, ap.allomegas[0], latticebasis = ap.direct_basis)
|
|
||||||
|
|
||||||
|
|
||||||
## Plane wave data
|
|
||||||
a.theta = np.array(a.theta)
|
|
||||||
dir_sph_list = np.stack((np.broadcast_to(1, a.theta.shape), a.theta, np.broadcast_to(a.phi, a.theta.shape)), axis=-1)
|
|
||||||
sψ, cψ = math.sin(a.psi), math.cos(a.psi)
|
|
||||||
sχ, cχ = math.sin(a.chi), math.cos(a.chi)
|
|
||||||
E_sph = (0., cψ*cχ + 1j*sψ*sχ, sψ*cχ + 1j*cψ*sχ)
|
|
||||||
|
|
||||||
dir_cart_list = sph2cart(dir_sph_list)
|
|
||||||
E_cart_list = sph_loccart2cart(E_sph, dir_sph_list)
|
|
||||||
|
|
||||||
nfreq = len(ap.allomegas)
|
|
||||||
ndir = len(dir_sph_list)
|
|
||||||
|
|
||||||
k_cart_arr = np.empty((nfreq, ndir, 3), dtype=float)
|
|
||||||
wavenumbers = np.empty((nfreq,), dtype=float)
|
|
||||||
|
|
||||||
σ_ext_arr = np.empty((nfreq,ndir), dtype=float)
|
|
||||||
σ_scat_arr = np.empty((nfreq,ndir), dtype=float)
|
|
||||||
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow
|
|
||||||
for i, omega in enumerate(ap.allomegas):
|
|
||||||
if i != 0:
|
|
||||||
ssw = ss(omega)
|
|
||||||
if ssw.wavenumber.imag != 0:
|
|
||||||
warnings.warn("The background medium wavenumber has non-zero imaginary part. Don't expect meaningful results for cross sections.")
|
|
||||||
wavenumber = ssw.wavenumber.real
|
|
||||||
wavenumbers[i] = wavenumber
|
|
||||||
|
|
||||||
k_sph_list = np.array(dir_sph_list, copy=True)
|
|
||||||
k_sph_list[:,0] = wavenumber
|
|
||||||
|
|
||||||
k_cart_arr[i] = sph2cart(k_sph_list)
|
|
||||||
|
|
||||||
|
|
||||||
for j in range(ndir):
|
|
||||||
k_cart = k_cart_arr[i,j]
|
|
||||||
blochvector = (k_cart[0], k_cart[1], 0)
|
|
||||||
# the following two could be calculated only once, but probably not a big deal
|
|
||||||
LU = ssw.scatter_solver(k=blochvector)
|
|
||||||
ã = ss.planewave_full(k_cart=k_cart, E_cart=E_cart_list[j])
|
|
||||||
Tã = ssw.apply_Tmatrices_full(ã)
|
|
||||||
f = LU(Tã)
|
|
||||||
|
|
||||||
σ_ext_arr[i,j] = -np.vdot(ã, f).real/wavenumber**2
|
|
||||||
translation_matrix = ssw.translation_matrix_full(blochvector=blochvector) + np.eye(ss.fecv_size)
|
|
||||||
σ_scat_arr[i,j] = np.vdot(f,np.dot(translation_matrix, f)).real/wavenumber**2
|
|
||||||
|
|
||||||
σ_abs_arr = σ_ext_arr - σ_scat_arr
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, dir_sph=dir_sph_list, k_cart = k_cart_arr, omega = ap.allomegas, E_cart = E_cart_list, wavenumbers= wavenumbers, σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from scipy.interpolate import griddata
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
ipm = 'nearest'
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
if False: #len(ap.omega_ranges) != 0:
|
|
||||||
# angle plot ---------------------------------
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = max(np.amax(σ_ext_arr), np.amax(σ_scat_arr), np.amax(σ_abs_arr))
|
|
||||||
vmin = min(np.amin(σ_ext_arr), np.amin(σ_scat_arr), np.amin(σ_abs_arr))
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_ext_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_scat_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
im = ax.pcolormesh(a.theta, ap.allomegas/eh, σ_abs_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
if len(ap.omega_ranges) != 0:
|
|
||||||
# "k-space" plot -----------------------------
|
|
||||||
domega = np.amin(np.diff(ap.allomegas))
|
|
||||||
dsintheta = np.amin(abs(np.diff(sintheta)))
|
|
||||||
dk = dsintheta * wavenumbers[0]
|
|
||||||
|
|
||||||
# target image grid
|
|
||||||
grid_y, grid_x = np.mgrid[ap.allomegas[0] : ap.allomegas[-1] : domega, np.amin(sintheta) * wavenumbers[-1] : np.amax(sintheta) * wavenumbers[-1] : dk]
|
|
||||||
imextent = (np.amin(sintheta) * wavenumbers[-1] / 1e6, np.amax(sintheta) * wavenumbers[-1] / 1e6, ap.allomegas[0] / eh, ap.allomegas[-1] / eh)
|
|
||||||
|
|
||||||
# source coordinates for griddata
|
|
||||||
ktheta = sintheta[None, :] * wavenumbers[:, None]
|
|
||||||
omegapoints = np.broadcast_to(ap.allomegas[:, None], ktheta.shape)
|
|
||||||
points = np.stack( (ktheta.flatten(), omegapoints.flatten()), axis = -1)
|
|
||||||
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = np.amax(σ_ext_arr)
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
grid_z = griddata(points, σ_ext_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
grid_z = griddata(points, σ_scat_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
grid_z = griddata(points, σ_abs_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
im = ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
for omega in ap.omega_singles:
|
|
||||||
i = np.searchsorted(ap.allomegas, omega)
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
fig.suptitle("%g eV" % (omega / eh))
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
ax.plot(sintheta, σ_ext_arr[i]*1e12,label='$\sigma_\mathrm{ext}$')
|
|
||||||
ax.plot(sintheta, σ_scat_arr[i]*1e12, label='$\sigma_\mathrm{scat}$')
|
|
||||||
ax.plot(sintheta, σ_abs_arr[i]*1e12, label='$\sigma_\mathrm{abs}$')
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel('$\sin\\theta$')
|
|
||||||
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
annotate_pdf_metadata(pdf)
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['const_real_background', 'lattice2d', 'multi_particle']) # TODO general analytical background
|
|
||||||
|
|
||||||
ap.add_argument("-k", nargs=2, type=sfloat, required=True, help='k vector', metavar=('K_X', 'K_Y'))
|
|
||||||
ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
ap.add_argument("--rank-tol", type=float, required=False)
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-t", "--rank-tolerance", type=float, default=1e11)
|
|
||||||
ap.add_argument("-c", "--min-candidates", type=int, default=1, help='always try at least this many eigenvalue candidates, even if their SVs in the rank tests are lower than rank_tolerance')
|
|
||||||
ap.add_argument("-T", "--residual-tolerance", type=float, default=2.)
|
|
||||||
ap.add_argument("-N", type=int, default="150", help="Integration contour discretisation size")
|
|
||||||
|
|
||||||
|
|
||||||
#TODO alternative specification of the contour by center and half-axes
|
|
||||||
dospec = ap.add_argument_group("Eigenvalue search area by diffracted order specification", "Specification of eigenvalue search area by diffracted order number (requires constant real refractive index for background): the integration contour 'touches' the empty lattice band specified by -b, and its axis lying on the real axis reaches '-f'-way to the next diffractive order")
|
|
||||||
dospec.add_argument("-d", "--band-index", type=int, help="Argument's absolute value determines the empty lattice band order (counted from 1), -/+ determines whether the eigenvalues are searched below/above that empty lattice band.", required=True)
|
|
||||||
dospec.add_argument("-f", "--interval-factor", type=float, default=0.1, help="Relative length of the integration ellipse axis w.r.t. the interval between two empty lattice bands; this should be be less than 1.") #TODO check
|
|
||||||
dospec.add_argument("-i", "--imaginary-aspect-ratio", type=float, default=1., help="Aspect ratio of the integration ellipse (Im/Re); this should not exceed 1/interval_factor.")
|
|
||||||
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
|
|
||||||
a = ap.parse_args()
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
particlestr = "modes" # TODO particle string specifier or some hash, do this in argproc.py
|
|
||||||
defaultprefix = "%s_basis%gnm_%gnm__%gnm_%gnm_n%g_b%+d_k(%g_%g)um-1_cn%d" % (
|
|
||||||
particlestr, a1[0]*1e9, a1[1]*1e9, a2[0]*1e9, a2[1]*1e9, a.refractive_index, a.band_index, a.k[0]*1e-6, a.k[1]*1e-6, a.N)
|
|
||||||
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix
|
|
||||||
from qpms.qpms_c import Particle, ScatteringSystem, empty_lattice_modes_xy
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.constants import eV, hbar
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
def inside_ellipse(point_xy, centre_xy, halfaxes_xy):
|
|
||||||
x = point_xy[0] - centre_xy[0]
|
|
||||||
y = point_xy[1] - centre_xy[1]
|
|
||||||
ax = halfaxes_xy[0]
|
|
||||||
ay = halfaxes_xy[1]
|
|
||||||
return ((x/ax)**2 + (y/ay)**2) <= 1
|
|
||||||
|
|
||||||
beta = np.array(a.k)
|
|
||||||
|
|
||||||
if True: # TODO alternative specification of the contour by center and half-axes
|
|
||||||
empty_freqs = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, np.array([0,0]), 1)
|
|
||||||
empty_freqs = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, beta, (1+abs(a.band_index)) * empty_freqs[1])
|
|
||||||
|
|
||||||
# make the frequencies in the list unique
|
|
||||||
empty_freqs = list(empty_freqs)
|
|
||||||
i = 0
|
|
||||||
while i < len(empty_freqs) - 1:
|
|
||||||
if math.isclose(empty_freqs[i], empty_freqs[i+1], rel_tol=1e-13):
|
|
||||||
del empty_freqs[i+1]
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
logging.info("Empty freqs: %s", str(empty_freqs))
|
|
||||||
logging.info("Empty freqs (eV): %s", str([ff / eh for ff in empty_freqs]))
|
|
||||||
if a.band_index > 0:
|
|
||||||
top = empty_freqs[a.band_index]
|
|
||||||
bottom = empty_freqs[a.band_index - 1]
|
|
||||||
lebeta_om = bottom
|
|
||||||
else: # a.band_index < 0
|
|
||||||
top = empty_freqs[abs(a.band_index) - 1]
|
|
||||||
bottom = empty_freqs[abs(a.band_index) - 2] if abs(a.band_index) > 1 else 0.
|
|
||||||
lebeta_om = top
|
|
||||||
#print(top,bottom,lebeta_om)
|
|
||||||
freqradius = .5 * (top - bottom) * a.interval_factor
|
|
||||||
|
|
||||||
centfreq = bottom + freqradius if a.band_index > 0 else top - freqradius
|
|
||||||
if freqradius == 0:
|
|
||||||
raise ValueError("Integration contour radius is set to zero. Are you trying to look below the lowest empty lattice band at the gamma point?")
|
|
||||||
|
|
||||||
freqradius *= (1-1e-13) # to not totally touch the singularities
|
|
||||||
|
|
||||||
logging.info("Direct lattice basis: %s" % str(ap.direct_basis))
|
|
||||||
logging.info("Reciprocal lattice basis: %s" % str(ap.reciprocal_basis2pi))
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(ap.get_particles(), ap.background_emg, centfreq, latticebasis=ap.direct_basis)
|
|
||||||
|
|
||||||
logging.info("Finding eigenvalues around %s (= %s eV)" % (str(centfreq), str(centfreq/eh)))
|
|
||||||
logging.info("Real half-axis %s (= %s eV)" % (str(freqradius), str(freqradius/eh)))
|
|
||||||
logging.info("Imaginary half-axis %s (= %s eV)" % (str(freqradius*a.imaginary_aspect_ratio), str(freqradius*a.imaginary_aspect_ratio/eh)))
|
|
||||||
|
|
||||||
with qpms.pgsl_ignore_error(15):
|
|
||||||
res = ss.find_modes(centfreq, freqradius, freqradius * a.imaginary_aspect_ratio,
|
|
||||||
blochvector = a.k, contour_points = a.N, rank_tol = a.rank_tolerance,
|
|
||||||
res_tol = a.residual_tolerance, rank_min_sel = a.min_candidates)
|
|
||||||
|
|
||||||
logging.info("Eigenfrequencies found: %s" % str(res['eigval']))
|
|
||||||
logging.info("Eigenfrequencies found (eV): %s" % str(res['eigval'] / eh))
|
|
||||||
|
|
||||||
res['inside_contour'] = inside_ellipse((res['eigval'].real, res['eigval'].imag),
|
|
||||||
(centfreq.real, centfreq.imag), (freqradius, freqradius * a.imaginary_aspect_ratio))
|
|
||||||
|
|
||||||
#res['refractive_index_internal'] = [emg(om).n for om in res['eigval']]
|
|
||||||
|
|
||||||
#del res['omega'] If contour points are not needed...
|
|
||||||
#del res['ImTW'] # not if dbg=false anyway
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, empty_freqs=np.array(empty_freqs),
|
|
||||||
ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets,
|
|
||||||
ss_fullvec_psizes=ss.fullvec_psizes,
|
|
||||||
ss_bspecs_flat = np.concatenate(ss.bspecs),
|
|
||||||
ss_lattice_basis=ss.lattice_basis, ss_reciprocal_basis = ss.reciprocal_basis,
|
|
||||||
**res)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
if len(res['eigval']) == 0:
|
|
||||||
logging.info("No eigenvalues found; nothing to plot")
|
|
||||||
exit(1)
|
|
||||||
imcut = np.linspace(0, -freqradius)
|
|
||||||
recut1 = np.sqrt(lebeta_om**2+imcut**2) # incomplete Gamma-related cut
|
|
||||||
recut2 = np.sqrt((lebeta_om/2)**2-imcut**2) + lebeta_om/2 # odd-power-lilgamma-related cut
|
|
||||||
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111,)
|
|
||||||
#ax.plot(res['omega'].real/eh, res['omega'].imag/eh*1e3, ':') #res['omega'] not implemented in ScatteringSystem
|
|
||||||
ax.add_artist(matplotlib.patches.Ellipse((centfreq.real/eh, centfreq.imag/eh*1e3),
|
|
||||||
2*freqradius/eh, 2*freqradius*a.imaginary_aspect_ratio/eh*1e3, fill=False,
|
|
||||||
ls=':'))
|
|
||||||
ax.scatter(x=res['eigval'].real/eh, y=res['eigval'].imag/eh*1e3 , c = res['inside_contour']
|
|
||||||
)
|
|
||||||
ax.plot(recut1/eh, imcut/eh*1e3)
|
|
||||||
ax.plot(recut2/eh, imcut/eh*1e3)
|
|
||||||
for i,om in enumerate(res['eigval']):
|
|
||||||
ax.annotate(str(i), (om.real/eh, om.imag/eh*1e3))
|
|
||||||
xmin = np.amin(res['eigval'].real)/eh
|
|
||||||
xmax = np.amax(res['eigval'].real)/eh
|
|
||||||
xspan = xmax-xmin
|
|
||||||
ymin = np.amin(res['eigval'].imag)/eh*1e3
|
|
||||||
ymax = np.amax(res['eigval'].imag)/eh*1e3
|
|
||||||
yspan = ymax-ymin
|
|
||||||
ax.set_xlim([xmin-.1*xspan, xmax+.1*xspan])
|
|
||||||
ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan])
|
|
||||||
ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$')
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='lat2d_modes.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['background', 'lattice2d', 'multi_particle', 'omega_seq'])
|
|
||||||
|
|
||||||
ap.add_argument("-k", nargs=2, type=sfloat, required=True, help='k vector', metavar=('K_X', 'K_Y'))
|
|
||||||
ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
|
|
||||||
ap.add_argument("-g", "--little-group", type=str, default="trivial_g", help="Little group for subspace irrep classification", action="store")
|
|
||||||
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-s", "--singular_values", type=int, default=10, help="Number of singular values to plot")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
#Important! The particles are supposed to be of D2h/D4h symmetry
|
|
||||||
# thegroup = 'D4h' if px == py and not a.D2 else 'D2h'
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
particlestr = "svdinterval" # TODO particle string specifier or some hash, do this in argproc.py
|
|
||||||
defaultprefix = "%s_basis%gnm_%gnm__%gnm_%gnm_f(%g..%g..%g)eV_k%g_%g" % (
|
|
||||||
particlestr, a1[0]*1e9, a1[1]*1e9, a2[0]*1e9, a2[1]*1e9, *(a.eV_seq), ap.k[0], ap.k[1])
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error, empty_lattice_modes_xy
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# not used; TODO:
|
|
||||||
irrep_labels = {"B2''":"$B_2''$",
|
|
||||||
"B2'":"$B_2'$",
|
|
||||||
"A1''":"$A_1''$",
|
|
||||||
"A1'":"$A_1'$",
|
|
||||||
"A2''":"$A_2''$",
|
|
||||||
"B1''":"$B_1''$",
|
|
||||||
"A2'":"$A_2'$",
|
|
||||||
"B1'":"$B_1'$",
|
|
||||||
"E'":"$E'$",
|
|
||||||
"E''":"$E''$",}
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
omegas = ap.omegas
|
|
||||||
|
|
||||||
logging.info("%d frequencies from %g to %g eV" % (len(omegas), omegas[0]/eh, omegas[-1]/eh))
|
|
||||||
|
|
||||||
particles = ap.get_particles()
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(particles, ap.background_emg, omegas[0], latticebasis=ap.direct_basis)
|
|
||||||
k = np.array([ap.k[0], ap.k[1], 0])
|
|
||||||
# Auxillary finite scattering system for irrep decomposition, quite a hack
|
|
||||||
ss1, ssw1 = ScatteringSystem.create(particles, ap.background_emg, omegas[0],sym=FinitePointGroup(point_group_info[ap.little_group]))
|
|
||||||
|
|
||||||
wavenumbers = np.empty(omegas.shape)
|
|
||||||
SVs = [None] * ss1.nirreps
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
SVs[iri] = np.empty(omegas.shape+(ss1.saecv_sizes[iri],))
|
|
||||||
for i, omega in enumerate(omegas):
|
|
||||||
ssw = ss(omega)
|
|
||||||
wavenumbers[i] = ssw.wavenumber.real
|
|
||||||
if ssw.wavenumber.imag:
|
|
||||||
warnings.warn("Non-zero imaginary wavenumber encountered")
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow; maybe not needed
|
|
||||||
ImTW = ssw.modeproblem_matrix_full(k)
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
ImTW_packed = ss1.pack_matrix(ImTW, iri)
|
|
||||||
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
cc = plt.rcParams['axes.prop_cycle']()
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
cargs = next(cc)
|
|
||||||
nlines = min(a.singular_values, ss1.saecv_sizes[iri])
|
|
||||||
for i in range(nlines):
|
|
||||||
ax.plot(omegas/eh, SVs[iri][:,-1-i],
|
|
||||||
label= None if i else irrep_labels.get(ss1.irrep_names[iri], ss1.irrep_names[iri]),
|
|
||||||
**cargs)
|
|
||||||
ax.set_ylim([0,1.1])
|
|
||||||
if hasattr(ap, "background_epsmu"):
|
|
||||||
xlim = ax.get_xlim()
|
|
||||||
omegas_empty = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, k, omegas[-1])
|
|
||||||
for om in omegas_empty:
|
|
||||||
if om/eh > xlim[0] and om/eh < xlim[1]:
|
|
||||||
ax.axvline(om/eh, ls=':')
|
|
||||||
ax.set_xlabel('$\hbar \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('Singular values')
|
|
||||||
ax.legend()
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='lat2d_realfreqsvd.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue