Compare commits
256 Commits
precise_po
...
master
Author | SHA1 | Date |
---|---|---|
Marek Nečada | 33d144cf68 | |
Marek Nečada | 53764f3dd1 | |
Marek Nečada | f9620e1d11 | |
Marek Nečada | 5e4f9130fb | |
Marek Nečada | 03e5be17f9 | |
Marek Nečada | 74ce35605b | |
Marek Nečada | 2a85b16347 | |
Marek Nečada | ac0d322246 | |
Marek Nečada | a1472f3db6 | |
Marek Nečada | 260b053102 | |
Marek Nečada | 78992188fd | |
Marek Nečada | e7f7cd38d2 | |
Marek Nečada | b525c66043 | |
Marek Nečada | e69b927ec3 | |
Marek Nečada | 2731a87ef7 | |
Marek Nečada | 3a34effe34 | |
Marek Nečada | 1aac5de903 | |
Marek Nečada | 87c2fd24fe | |
Marek Nečada | aea0afee15 | |
Kristian Arjas | 77a3566aba | |
Kristian Arjas | 24a6ea01d7 | |
Kristian Arjas | 50a5aa11a6 | |
Marek Nečada | 572e15edbb | |
Marek Nečada | b12fc991e5 | |
Marek Nečada | a5b137847a | |
Marek Nečada | 314cde1b99 | |
Marek Nečada | 80ee8b0d53 | |
Marek Nečada | 087cd1cab3 | |
Marek Nečada | 9d556e7b23 | |
Marek Nečada | f19c590d6e | |
Marek Nečada | 2be3521333 | |
Marek Nečada | 64f77557a7 | |
Marek Nečada | 7e0d7639e8 | |
Marek Nečada | 36c5d5236a | |
Marek Nečada | cf2aca7f03 | |
Marek Nečada | 3479721455 | |
Marek Nečada | 6189918348 | |
Marek Nečada | 031397aacd | |
Marek Nečada | 1a4b279eff | |
Marek Nečada | 5285210489 | |
Marek Nečada | ae62cf903d | |
Marek Nečada | 5246229b2d | |
Marek Nečada | 868e603f1c | |
Marek Nečada | bf297c11c3 | |
Marek Nečada | 9e42520371 | |
Marek Nečada | a68e1d8f8c | |
Kristian Arjas | a669e661e3 | |
Kristian Arjas | d19a7813f7 | |
Marek Nečada | 07c2f678b2 | |
Marek Nečada | 38fca209ef | |
Marek Nečada | 24b5371e18 | |
Marek Nečada | 840744ec97 | |
Marek Nečada | 38a4dbfcd7 | |
Marek Nečada | 17824b062e | |
Marek Nečada | 1328077490 | |
Marek Nečada | f7883a713b | |
Marek Nečada | 93118cfc07 | |
Marek Nečada | fc27320988 | |
Marek Nečada | 676240cf0d | |
Marek Nečada | 7d92f4990b | |
Marek Nečada | e0861a7d40 | |
Marek Nečada | 87c2b08701 | |
Marek Nečada | 6c79a9116b | |
Marek Nečada | 884baca199 | |
Marek Nečada | e0e572db3c | |
Marek Nečada | 42497939c1 | |
Marek Nečada | cc8d2644bf | |
Marek Nečada | 14e415dfc5 | |
Marek Nečada | 7f2e36e956 | |
Marek Nečada | eba5784042 | |
Marek Nečada | b09dfc8784 | |
Marek Nečada | 62ba67ebcf | |
Marek Nečada | a0b0d72686 | |
Marek Nečada | 299bb6fc03 | |
Marek Nečada | cae5cee97d | |
Marek Nečada | 827499c3ff | |
Marek Nečada | 0c442ba745 | |
Marek Nečada | a34f3b37d9 | |
Marek Nečada | fec399d16b | |
Marek Nečada | e2584e3163 | |
Marek Nečada | 582f33bb00 | |
Marek Nečada | ecf599bb15 | |
Marek Nečada | d3cd9b9350 | |
Marek Nečada | 90458af3be | |
Marek Nečada | 6009de6fa2 | |
Marek Nečada | 3046f03734 | |
Marek Nečada | 61a2baecb0 | |
Marek Nečada | 97977dbb46 | |
Marek Nečada | 975d23b557 | |
Marek Nečada | c50f40a747 | |
Marek Nečada | c056099d5a | |
Marek Nečada | 93cde82a9a | |
Marek Nečada | 626ffd77cd | |
Marek Nečada | 85dbf79caa | |
Marek Nečada | 932f30e9f9 | |
Marek Nečada | 43c2de4f35 | |
Steven G. Johnson | 206f8b65a1 | |
Marek Nečada | a7c95d0ee0 | |
Marek Nečada | 4bf3bb1bb1 | |
Marek Nečada | 1221012c7b | |
Marek Nečada | 80efed00fd | |
Marek Nečada | 2f14de7dde | |
Marek Nečada | 14a5c32202 | |
Marek Nečada | 999dc7f72e | |
Marek Nečada | 8ed4bdb683 | |
Marek Nečada | 83e76b1f95 | |
Marek Nečada | 69fd19c019 | |
Marek Nečada | 2460f3b644 | |
Marek Nečada | fe55f4b391 | |
Marek Nečada | 74f6c489ba | |
Marek Nečada | 3da6e5cfb2 | |
Marek Nečada | c5c148ca40 | |
Marek Nečada | 63aa338891 | |
Marek Nečada | 2ccf9e2c5d | |
Marek Nečada | dd2391abf7 | |
Marek Nečada | 231a76529d | |
Marek Nečada | ba06abe13f | |
Marek Nečada | 3458acca16 | |
Marek Nečada | 3f266f5501 | |
Marek Nečada | 9b9338be05 | |
Marek Nečada | e774b30d0c | |
Marek Nečada | 70d03f75aa | |
Marek Nečada | dc503158bf | |
Marek Nečada | a88694e7ef | |
Marek Nečada | 8b7e2c6332 | |
Marek Nečada | 858e7d0697 | |
Marek Nečada | a14d0e5bc4 | |
Marek Nečada | ac6e94065a | |
Marek Nečada | 5f729d28a7 | |
Marek Nečada | 1b4b397093 | |
Marek Nečada | 20a13cdb2c | |
Marek Nečada | 3ebc1af946 | |
Marek Nečada | 2798fcce49 | |
Marek Nečada | c031d65905 | |
Marek Nečada | 3c7377e5fe | |
Marek Nečada | b3d15a1bb7 | |
Marek Nečada | aa82b3a01a | |
Marek Nečada | 35ffc61faf | |
Marek Nečada | b00a6db4cf | |
Marek Nečada | 301a0e0633 | |
Marek Nečada | 433be52bbc | |
Marek Nečada | 4b2e48f459 | |
Marek Nečada | 9bf2f6a57a | |
Marek Nečada | 15328a3dc9 | |
Marek Nečada | 79b805a6aa | |
Marek Nečada | 57483ac9c8 | |
Marek Nečada | 5270430bfd | |
Marek Nečada | 3791db2060 | |
Marek Nečada | 213853e407 | |
Marek Nečada | dd391747bf | |
Marek Nečada | 78c793fb68 | |
Marek Nečada | 1fb4e5760a | |
Marek Nečada | 2b628736f0 | |
Marek Nečada | f994514aeb | |
Marek Nečada | 1e765e3cf6 | |
Marek Nečada | bf49531666 | |
Marek Nečada | 379dc3117e | |
Marek Nečada | 2499c739c8 | |
Marek Nečada | 3fed9396a1 | |
Marek Nečada | 54315c61c8 | |
Marek Nečada | cea33ae97c | |
Marek Nečada | b4bd1eedac | |
Marek Nečada | 68812c9555 | |
Marek Nečada | d557a99a49 | |
Marek Nečada | 5176bd5451 | |
Marek Nečada | daf95e799a | |
Marek Nečada | c11fe19af3 | |
Marek Nečada | c7c27c4731 | |
Marek Nečada | 609b6e6265 | |
Marek Nečada | 0a7bd72004 | |
Marek Nečada | 76171179e7 | |
Marek Nečada | bc5a024e86 | |
Marek Nečada | a2a51d0de6 | |
Marek Nečada | 71852aa017 | |
Marek Nečada | 937757cf47 | |
Marek Nečada | 3da4ec6b07 | |
Marek Nečada | 80a9f8703a | |
Marek Nečada | 4674fa5844 | |
Marek Nečada | 3b6fb71f2e | |
Marek Nečada | 8b8d002d42 | |
Marek Nečada | a16cea4dca | |
Marek Nečada | c445b83593 | |
Marek Nečada | 355bc52325 | |
Marek Nečada | 6d83e26aa7 | |
Marek Nečada | b578f305ac | |
Marek Nečada | c86ff69827 | |
Marek Nečada | 8f90842b24 | |
Marek Nečada | b708b74292 | |
Marek Nečada | be8f55eb1f | |
Marek Nečada | 6cf1f667de | |
Marek Nečada | c86b881088 | |
Marek Nečada | 5a98b91b3d | |
Marek Nečada | 541af5a984 | |
Marek Nečada | 5dd93235f0 | |
Marek Nečada | 7e57c3cc81 | |
Marek Nečada | 3bf263c4f3 | |
Marek Nečada | e1a6389232 | |
Marek Nečada | d31d8737b8 | |
Marek Nečada | c2b4787cd5 | |
Marek Nečada | dff8293e6d | |
Marek Nečada | d17a5e5eea | |
Marek Nečada | d53f2964f0 | |
Marek Nečada | b6e6554323 | |
Marek Nečada | dc5d2cde0b | |
Marek Nečada | ef1c699861 | |
Marek Nečada | fb3e5467d6 | |
Marek Nečada | 2f9e5670da | |
Marek Nečada | 4c7dd1ee61 | |
Marek Nečada | f1f2c821df | |
Marek Nečada | 1dcebe4fee | |
Marek Nečada | a712789386 | |
Marek Nečada | d1068419f4 | |
Marek Nečada | c9a5661519 | |
Marek Nečada | 1821a0d8f5 | |
Marek Nečada | e4f368f47a | |
Marek Nečada | cfda120a20 | |
Marek Nečada | 28f4e7f3d2 | |
Marek Nečada | cc9dbb6cc5 | |
Marek Nečada | 493ba079e2 | |
Marek Nečada | d79a35110c | |
Marek Nečada | 84acb1ada2 | |
Marek Nečada | 79e6c47f94 | |
Marek Nečada | dad170b8fe | |
Marek Nečada | f940e62e52 | |
Marek Nečada | d6084f3264 | |
Marek Nečada | 2e7b925be2 | |
Marek Nečada | b3c3eeb2a2 | |
Marek Nečada | 2fcc6282fa | |
Marek Nečada | 6445c3523e | |
Marek Nečada | 42931eb0a0 | |
Marek Nečada | bd0b8a83e9 | |
Marek Nečada | 9d0f910bba | |
Marek Nečada | 2762ada49c | |
Marek Nečada | 11aa48d2da | |
Marek Nečada | 3bc59096bc | |
Marek Nečada | cbf039710f | |
Marek Nečada | 1585c48071 | |
Marek Nečada | 5dc2a44cdd | |
Marek Nečada | cabe764640 | |
Marek Nečada | bc703cbcca | |
Marek Nečada | 537c4b2d37 | |
Marek Nečada | 4c21fde628 | |
Marek Nečada | 1aa9890155 | |
Marek Nečada | 5471367aad | |
Marek Nečada | 00e3a9ce09 | |
Marek Nečada | c0c44c11b6 | |
Marek Nečada | 51fa6f1dd6 | |
Marek Nečada | 93d34c9830 | |
Marek Nečada | 8666657fcc | |
Marek Nečada | e898fd5ad8 | |
Marek Nečada | 26e7d9acee | |
Marek Nečada | 142d97d484 | |
Marek Nečada | cf9892279d | |
Marek Nečada | 6e875d65ae | |
Marek Nečada | b52942a5e5 | |
Kristian Arjas | 3fb9f23af5 |
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
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,4 +5,29 @@
|
|||
*.pdf
|
||||
*.o
|
||||
docs/*
|
||||
|
||||
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/*
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[submodule "camos"]
|
||||
path = camos
|
||||
url = https://codeberg.org/QPMS/zbessel.git
|
||||
branch = purec
|
|
@ -0,0 +1,43 @@
|
|||
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,11 +1,16 @@
|
|||
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)
|
||||
endif (QPMS_USE_FORTRAN_AMOS)
|
||||
include(version.cmake)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
project (QPMS)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
macro(use_c99)
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||
|
@ -24,10 +29,23 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|||
|
||||
set (QPMS_VERSION_MAJOR 0)
|
||||
#set (QPMS_VERSION_MINOR 3)
|
||||
cmake_add_fortran_subdirectory (amos
|
||||
PROJECT amos
|
||||
LIBRARIES amos
|
||||
NO_EXTERNAL_INSTALL)
|
||||
|
||||
if (QPMS_USE_FORTRAN_AMOS)
|
||||
cmake_add_fortran_subdirectory (amos
|
||||
PROJECT amos
|
||||
LIBRARIES amos
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,675 @@
|
|||
### 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>.
|
8
Doxyfile
8
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
|
||||
# to the output directory.
|
||||
|
||||
PROJECT_LOGO =
|
||||
PROJECT_LOGO = farfield.png
|
||||
|
||||
# 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
|
||||
|
@ -753,7 +753,7 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = qpms notes finite_systems.md README.md README.Triton.md finite_systems.md lattices.md TODO.md
|
||||
INPUT = qpms notes misc finite_systems.md MIRRORS.md CLIUTILS.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
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
@ -773,7 +773,7 @@ INPUT_ENCODING = UTF-8
|
|||
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
|
||||
# *.qsf, *.as and *.js.
|
||||
|
||||
FILE_PATTERNS =
|
||||
FILE_PATTERNS =
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
|
@ -1462,7 +1462,7 @@ MATHJAX_FORMAT = HTML-CSS
|
|||
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
MATHJAX_RELPATH = https://uslugi.necada.org/js/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
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
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,10 +1,14 @@
|
|||
[![Build Status](https://drone.perkele.eu/api/badges/QPMS/qpms/status.svg)](https://drone.perkele.eu/QPMS/qpms)
|
||||
|
||||
QPMS README
|
||||
===========
|
||||
|
||||
QPMS is a toolkit for frequency-domain simulations of photonic systems
|
||||
[QPMS][homepage] (standing for QPMS Photonic Multiple Scattering)
|
||||
is a toolkit for frequency-domain simulations of photonic systems
|
||||
consisting of compact objects (particles) inside a homogeneous medium. Scattering
|
||||
properties of the individual particles are described by their T-matrices
|
||||
(which can be obtained e.g. with the `scuff-tmatrix` tool from
|
||||
(which can be obtained using one of the built-in generators or
|
||||
e.g. with the `scuff-tmatrix` tool from
|
||||
the [SCUFF-EM] suite).
|
||||
|
||||
QPMS handles the multiple scattering of electromagnetic radiation between
|
||||
|
@ -12,26 +16,39 @@ the particles. The system can consist either of a finite number of particles
|
|||
or an infinite number of periodically arranged lattices (with finite number
|
||||
of particles in a single unit cell).
|
||||
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
|
||||
Finite systems
|
||||
--------------
|
||||
* Computing multipole excitations *and fields (TODO)* scattered from nanoparticle
|
||||
* Computing multipole excitations and fields scattered from nanoparticle
|
||||
clusters illuminated by plane, spherical or *cylindrical (TODO)* waves.
|
||||
* Finding eigenmodes.
|
||||
* *Calculating cross sections (TODO).*
|
||||
* Finding eigenmodes (optical resonances).
|
||||
* Calculating cross sections.
|
||||
* Reducing numerical complexity of the computations by exploiting
|
||||
symmetries of the cluster (decomposition to irreducible representations).
|
||||
|
||||
|
||||
Infinite systems (lattices)
|
||||
---------------------------
|
||||
* 2D-periodic systems supported. (TODO 1D and 3D.)
|
||||
* *Calculation of transmission and reflection properties (TODO).*
|
||||
* 2D-periodic systems with arbitrary unit cell geometry supported. (TODO 1D and 3D.)
|
||||
* Computing multipole excitations and fields scattered from nanoparticle
|
||||
* Finding eigenmodes and calculating dispersion relations.
|
||||
* *Calculation of far-field radiation patterns of an excited array (TODO).*
|
||||
* Reducing numerical complexity of the computations by exploiting
|
||||
symmetries of the lattice (decomposition to irreducible representations).
|
||||
* Calculation of the scattered fields.
|
||||
* *Calculation of total transmission and reflection properties (TODO).*
|
||||
* *Reducing numerical complexity of the computations by exploiting
|
||||
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
|
||||
|
@ -47,7 +64,16 @@ you can [get the source and compile it yourself][GSL].
|
|||
|
||||
You also need a fresh enough version of [cmake][].
|
||||
|
||||
After GSL is installed, you can install qpms to your local python library using
|
||||
QPMS uses a C version of the Amos library for calculating Bessel function
|
||||
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}
|
||||
cmake -DCMAKE_INSTALL_PREFIX=${YOUR_PREFIX} .
|
||||
|
@ -66,13 +92,21 @@ Special care might need to be taken when installing QPMS in cluster environments
|
|||
Specific installation instructions for Aalto University's Triton cluster
|
||||
can be found in a [separate document][TRITON-README].
|
||||
|
||||
Instructions for installation on Android-based devices are
|
||||
in [another document][INSTALL-ANDROID].
|
||||
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Documentation of QPMS is a work in progress. Most of the newer code
|
||||
is documented using [doxygen][] comments. To build the documentation, just run
|
||||
[QPMS documentation][homepage] is a work in progress. Most of the newer code
|
||||
is documented using [doxygen][] comments. Documentation generated for the
|
||||
upstream version is hosted on the QPMS homepage <https://qpms.necada.org>.
|
||||
|
||||
To build the documentation yourself,
|
||||
just run
|
||||
`doxygen`
|
||||
in the root directory; the documentation will then be found in
|
||||
in the QPMS source root directory; the documentation will then be found in
|
||||
`docs/html/index.html`.
|
||||
|
||||
Of course, the prerequisite of this is having doxygen installed.
|
||||
|
@ -84,14 +118,77 @@ under root.
|
|||
Tutorials
|
||||
---------
|
||||
|
||||
* [Infinite system (lattice) tutorial][tutorial-infinite]
|
||||
* [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/
|
||||
[OpenBLAS]: https://www.openblas.net/
|
||||
[GSL]: https://www.gnu.org/software/gsl/
|
||||
[cmake]: https://cmake.org
|
||||
[TRITON-README]: README.Triton.md
|
||||
[INSTALL-ANDROID]: notes/INSTALL_ANDROID.md
|
||||
[tutorial-finite]: finite_systems.md
|
||||
[tutorial-infinite]: lattices.md
|
||||
[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
|
||||
|
|
29
TODO.md
29
TODO.md
|
@ -1,11 +1,12 @@
|
|||
TODO list before public release
|
||||
===============================
|
||||
TODO list before 1.0 release
|
||||
============================
|
||||
|
||||
- Tests!
|
||||
- Docs!
|
||||
- Cross section calculations.
|
||||
- Field calculations.
|
||||
- Complex frequencies, n's, k's.
|
||||
- Cross section calculations. (Done in some Python scripts.)
|
||||
- Field calculations. (Partly done, needs more testing.)
|
||||
* Also test periodic vs. nonperiodic consistence (big finite lattice + absorbing medium vs. infinite lattice + absorbing medium).
|
||||
- Complex frequencies, n's, k's. (Mostly done.)
|
||||
- Transforming point (meta)generators.
|
||||
- Check whether moble's quaternions and my
|
||||
quaternions give the same results in tmatrices.py
|
||||
|
@ -24,11 +25,12 @@ TODO list before public release
|
|||
* As a description of a T-matrix / particle metadata.
|
||||
- Nice CLI for all general enough utilities.
|
||||
- Remove legacy code.
|
||||
- Split qpms_c.pyx.
|
||||
- Split `qpms_c.pyx`.
|
||||
- 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.
|
||||
in the `qpms_tmatrix_isclose()` call.
|
||||
- Prefix all identifiers. Maybe think about a different prefix than qpms?
|
||||
- Consistent indentation and style overall.
|
||||
- Rewrite the parallelized translation matrix, mode problem matrix generators
|
||||
|
@ -39,3 +41,16 @@ Nice but less important features
|
|||
|
||||
- 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.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#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_
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 19e7ae82e7e0b436bd273557a87d288f8f338221
|
|
@ -0,0 +1,7 @@
|
|||
#!/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
|
|
@ -0,0 +1,5 @@
|
|||
#!/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 .
|
|
@ -0,0 +1,5 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
FROM commondeps AS numlibs
|
||||
# openblas-dev adds gfortran :(
|
||||
RUN apk add openblas-dev gsl-dev
|
|
@ -0,0 +1,16 @@
|
|||
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
|
|
@ -0,0 +1,4 @@
|
|||
FROM commondeps AS numlibs
|
||||
RUN apt-get -y install --no-install-recommends libopenblas-dev libgsl-dev liblapacke-dev \
|
||||
&& apt-get clean
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
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
|
||||
|
|
@ -0,0 +1 @@
|
|||
../.drone.yml
|
|
@ -0,0 +1,284 @@
|
|||
# - 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()
|
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# 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()
|
|
@ -0,0 +1,23 @@
|
|||
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.
|
|
@ -0,0 +1,36 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#!/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
|
|
@ -0,0 +1,18 @@
|
|||
#!/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
|
|
@ -0,0 +1,16 @@
|
|||
#!/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
|
|
@ -0,0 +1,22 @@
|
|||
#!/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
|
|
@ -0,0 +1,24 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1 @@
|
|||
scale=20;pi=3.14159265358979323846;
|
|
@ -0,0 +1,37 @@
|
|||
#!/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})
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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
|
|
@ -0,0 +1,17 @@
|
|||
#!/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
|
|
@ -0,0 +1,15 @@
|
|||
#!/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
|
|
@ -0,0 +1,22 @@
|
|||
#!/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
|
|
@ -0,0 +1,24 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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
|
@ -0,0 +1 @@
|
|||
../modes/00_params.sh
|
|
@ -0,0 +1,19 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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
|
@ -0,0 +1,54 @@
|
|||
# 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
2.0
|
||||
2.1
|
||||
2.2
|
||||
2.3
|
||||
2.4
|
|
@ -0,0 +1,10 @@
|
|||
1.32
|
||||
1.34
|
||||
1.35
|
||||
1.38
|
||||
1.4
|
||||
1.5
|
||||
1.6
|
||||
1.65
|
||||
1.7
|
||||
3.5
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
freqlist_scuff: freqlist_eV
|
||||
../../../../misc/omega_eV2scuff.py -o freqlist_scuff freqlist_eV
|
|
@ -0,0 +1,3 @@
|
|||
1.0
|
||||
1.5
|
||||
2.0
|
|
@ -0,0 +1,62 @@
|
|||
// 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};
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// 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};
|
|
@ -0,0 +1,65 @@
|
|||
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
|
|
@ -0,0 +1,7 @@
|
|||
REGION Exterior MATERIAL CONST_EPS_2.3104
|
||||
|
||||
OBJECT TheParticle
|
||||
MESHFILE __THEMESHFILE__
|
||||
MATERIAL __THEMATERIAL__
|
||||
ENDOBJECT
|
||||
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r100_h50.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r100_h50_fine.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r100_h50_rough.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r100_h50_veryrough.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r30_h30.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r30_h30_fine.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r30_h30_rough.msh
|
|
@ -0,0 +1 @@
|
|||
../shapes/cylinder_r30_h30_veryrough.msh
|
|
@ -0,0 +1 @@
|
|||
../materials/matprop.dat
|
|
@ -0,0 +1 @@
|
|||
../omegalist1_eV
|
|
@ -0,0 +1 @@
|
|||
../omegalist2_eV
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,19 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/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
|
|
@ -0,0 +1,11 @@
|
|||
#!/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
|
|
@ -0,0 +1,300 @@
|
|||
{
|
||||
"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
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
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})
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/* 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"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
/* 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
|
|
@ -0,0 +1,62 @@
|
|||
/* 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
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -1,6 +1,8 @@
|
|||
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
|
||||
most relevant parts are wrapped into python modules. The central data structure
|
||||
defining the system of scatterers is [qpms_scatsys_t][],
|
||||
|
|
118
lattices.md
118
lattices.md
|
@ -1,118 +0,0 @@
|
|||
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.
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
#!/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!
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#!/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!
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#!/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!
|
||||
|
|
@ -1,547 +0,0 @@
|
|||
#!/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)))
|
|
@ -1,403 +0,0 @@
|
|||
#!/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)))
|
|
@ -1,239 +0,0 @@
|
|||
#!/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)))
|
|
@ -0,0 +1,719 @@
|
|||
{
|
||||
"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
|
||||
}
|
|
@ -0,0 +1,362 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
#!/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)
|
||||
|
|
@ -1,376 +0,0 @@
|
|||
#!/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)
|
|
@ -1,340 +0,0 @@
|
|||
#!/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)))
|
|
@ -1,35 +0,0 @@
|
|||
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)
|
|
@ -0,0 +1,128 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
#!/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)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
#!/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