Compare commits
26 Commits
master
...
finite_lat
Author | SHA1 | Date |
---|---|---|
Marek Nečada | acc08f8863 | |
Marek Nečada | b4381bd13d | |
Marek Nečada | 6233e1c210 | |
Marek Nečada | e3834fdad7 | |
Marek Nečada | acec5bed98 | |
Marek Nečada | 96c9e95ea0 | |
Marek Nečada | 8f4a8c7c7b | |
Marek Nečada | 338fc00bfe | |
Marek Nečada | 775976816e | |
Marek Nečada | 00ab187510 | |
Marek Nečada | b62f1dadc5 | |
Marek Nečada | 7d19bed4cd | |
Marek Nečada | 7a80c9e0f2 | |
Marek Nečada | 1f63d2b529 | |
Marek Nečada | 2f03fc58b4 | |
Marek Nečada | f33b102768 | |
Marek Nečada | e4d84b3b25 | |
Marek Nečada | 5cc29210d7 | |
Marek Nečada | effe59bc50 | |
Marek Nečada | 8209e9df6e | |
Marek Nečada | 8251eba955 | |
Marek Nečada | af12f2301f | |
Marek Nečada | a0acdfdc5d | |
Marek Nečada | 36c6826b5a | |
Marek Nečada | ed3322ec93 | |
Marek Nečada | f082838c5f |
83
.drone.yml
83
.drone.yml
|
@ -1,83 +0,0 @@
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: buildqpms-alpine-preinstlibs
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
path: /home/qpmsbuild/qpms
|
|
||||||
|
|
||||||
# don't run in master until the python/lapacke linking problem is resolved
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
exclude:
|
|
||||||
- master
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: chown
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
commands:
|
|
||||||
- chown -R qpmsbuild.qpmsbuild .
|
|
||||||
- name: submodules
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- git submodule init
|
|
||||||
- git submodule update
|
|
||||||
- name: build
|
|
||||||
image: qpms/buildenv/alpine/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .
|
|
||||||
- make install
|
|
||||||
- export LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- python3 setup.py install --user
|
|
||||||
- cd examples/rectangular/modes
|
|
||||||
- pip3 install --user matplotlib #needed to run the example
|
|
||||||
- export LD_LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- ./01a_realfreq_svd.sh
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: buildqpms-debian-preinstlibs
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
path: /home/qpmsbuild/qpms
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: chown
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
commands:
|
|
||||||
- chown -R qpmsbuild.qpmsbuild .
|
|
||||||
- name: submodules
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- git submodule init
|
|
||||||
- git submodule update
|
|
||||||
- name: build
|
|
||||||
image: qpms/buildenv/debian/pkgdnumlib
|
|
||||||
pull: never
|
|
||||||
user: qpmsbuild
|
|
||||||
commands:
|
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=/home/qpmsbuild/.local .
|
|
||||||
- make install
|
|
||||||
- export LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- python3 setup.py install --user
|
|
||||||
- pip3 install --user matplotlib #needed to run the examples
|
|
||||||
- export LD_LIBRARY_PATH=$HOME/.local/lib
|
|
||||||
- cd examples/rectangular/modes
|
|
||||||
- ./01a_realfreq_svd.sh
|
|
||||||
- cd -
|
|
||||||
- cd examples/hexagonal/modes
|
|
||||||
#- ./01a_realfreq_svd.sh
|
|
||||||
#- ./01_compute_modes.sh
|
|
||||||
#- ./02b_compute_disp_0M.sh
|
|
||||||
#- ./02_compute_disp.sh
|
|
||||||
#- ./02x_compute_disp.sh
|
|
||||||
|
|
|
@ -5,29 +5,4 @@
|
||||||
*.pdf
|
*.pdf
|
||||||
*.o
|
*.o
|
||||||
docs/*
|
docs/*
|
||||||
|
|
||||||
qpms/qpms_c.c
|
qpms/qpms_c.c
|
||||||
qpms/cy*.c
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles/*
|
|
||||||
faddeeva/*
|
|
||||||
qpms/CMakeFiles/*
|
|
||||||
qpms/libqpms.so
|
|
||||||
qpms/cmake_install.cmake
|
|
||||||
qpms_version.c
|
|
||||||
qpms.egg_info/*
|
|
||||||
dist/*
|
|
||||||
build/*
|
|
||||||
Makefile
|
|
||||||
CTestTestfile.cmake
|
|
||||||
|
|
||||||
amos/CMakeFiles/*
|
|
||||||
amos/Makefile
|
|
||||||
amos/amos_mangling.h
|
|
||||||
cmake_install.cmake
|
|
||||||
cython_debug/*
|
|
||||||
qpms.egg-info/*
|
|
||||||
tests/CmakeFiles/*
|
|
||||||
tests/cmake_install.cmake
|
|
||||||
tests/CMakeFiles/*
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[submodule "camos"]
|
|
||||||
path = camos
|
|
||||||
url = https://codeberg.org/QPMS/zbessel.git
|
|
||||||
branch = purec
|
|
43
CLIUTILS.md
43
CLIUTILS.md
|
@ -1,43 +0,0 @@
|
||||||
Overview of QPMS command line utilities
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
The utilities are located in the `misc` directory. Run the
|
|
||||||
utility with `-h` argument to get more info.
|
|
||||||
|
|
||||||
|
|
||||||
Rectangular and square 2D lattices
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
These scripts deal with simple 2D rectangular lattices,
|
|
||||||
finite or infinite, one scatterer per unit cell.
|
|
||||||
\f$ D_{2h} \f$ or \f$ D_{4h} \f$ symmetric adapted bases
|
|
||||||
are used where applicable.
|
|
||||||
|
|
||||||
### Finite lattices
|
|
||||||
|
|
||||||
* `finiterectlat-modes.py`: Search for resonances using Beyn's algorithm.
|
|
||||||
* `finiterectlat-scatter.py`: Plane wave scattering.
|
|
||||||
* `finiterectlat-constant-driving.py`: Rectangular array response to
|
|
||||||
a driving where a subset of particles are excited by basis VSWFs with the
|
|
||||||
same phase.
|
|
||||||
|
|
||||||
### Infinite lattices
|
|
||||||
|
|
||||||
* `rectlat_simple_modes.py`: Search for lattice modes using Beyn's algorithm.
|
|
||||||
* `infiniterectlat-k0realfreqsvd.py`:
|
|
||||||
Evaluate the lattice mode problem singular values at the Γ point for a real frequency interval.
|
|
||||||
Useful as a starting point in lattice mode search before using Beyn's algorithm.
|
|
||||||
* `infiniterectlat-scatter.py`: Plane wave scattering.
|
|
||||||
|
|
||||||
|
|
||||||
General 2D lattices
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
### Infinite lattices
|
|
||||||
|
|
||||||
These can contain several scatterers per unit cell. Symmetry adapted bases currently not implemented.
|
|
||||||
|
|
||||||
* `lat2d_modes.py`: Search for lattice modes using Beyn's algorithm.
|
|
||||||
* `lat2d_realfreqsvd.py`:
|
|
||||||
Evaluate the lattice mode problem singular values at the Γ point for a real frequency interval.
|
|
||||||
Useful as a starting point in lattice mode search before using Beyn's algorithm.
|
|
|
@ -1,17 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.0.2)
|
cmake_minimum_required(VERSION 3.0.2)
|
||||||
|
|
||||||
option(QPMS_USE_FORTRAN_AMOS "Use the original AMOS Fortran libraries instead of the C ones" OFF)
|
|
||||||
|
|
||||||
if (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
include(CMakeAddFortranSubdirectory)
|
include(CMakeAddFortranSubdirectory)
|
||||||
endif (QPMS_USE_FORTRAN_AMOS)
|
|
||||||
include(version.cmake)
|
include(version.cmake)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
project (QPMS)
|
project (QPMS)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
|
||||||
|
|
||||||
macro(use_c99)
|
macro(use_c99)
|
||||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
@ -29,23 +22,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
set (QPMS_VERSION_MAJOR 0)
|
set (QPMS_VERSION_MAJOR 0)
|
||||||
#set (QPMS_VERSION_MINOR 3)
|
#set (QPMS_VERSION_MINOR 3)
|
||||||
|
cmake_add_fortran_subdirectory (amos
|
||||||
if (QPMS_USE_FORTRAN_AMOS)
|
PROJECT amos
|
||||||
cmake_add_fortran_subdirectory (amos
|
LIBRARIES amos
|
||||||
PROJECT amos
|
NO_EXTERNAL_INSTALL)
|
||||||
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)
|
add_subdirectory (qpms)
|
||||||
|
|
||||||
|
|
||||||
|
|
675
COPYING.md
675
COPYING.md
|
@ -1,675 +0,0 @@
|
||||||
### GNU GENERAL PUBLIC LICENSE
|
|
||||||
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
|
||||||
<https://fsf.org/>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this
|
|
||||||
license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
### Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom
|
|
||||||
to share and change all versions of a program--to make sure it remains
|
|
||||||
free software for all its users. We, the Free Software Foundation, use
|
|
||||||
the GNU General Public License for most of our software; it applies
|
|
||||||
also to any other work released this way by its authors. You can apply
|
|
||||||
it to your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you
|
|
||||||
have certain responsibilities if you distribute copies of the
|
|
||||||
software, or if you modify it: responsibilities to respect the freedom
|
|
||||||
of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the
|
|
||||||
manufacturer can do so. This is fundamentally incompatible with the
|
|
||||||
aim of protecting users' freedom to change the software. The
|
|
||||||
systematic pattern of such abuse occurs in the area of products for
|
|
||||||
individuals to use, which is precisely where it is most unacceptable.
|
|
||||||
Therefore, we have designed this version of the GPL to prohibit the
|
|
||||||
practice for those products. If such problems arise substantially in
|
|
||||||
other domains, we stand ready to extend this provision to those
|
|
||||||
domains in future versions of the GPL, as needed to protect the
|
|
||||||
freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish
|
|
||||||
to avoid the special danger that patents applied to a free program
|
|
||||||
could make it effectively proprietary. To prevent this, the GPL
|
|
||||||
assures that patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
### TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
#### 0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds
|
|
||||||
of works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of
|
|
||||||
an exact copy. The resulting work is called a "modified version" of
|
|
||||||
the earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user
|
|
||||||
through a computer network, with no transfer of a copy, is not
|
|
||||||
conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices" to
|
|
||||||
the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
#### 1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. "Object code" means any non-source form of
|
|
||||||
a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users can
|
|
||||||
regenerate automatically from other parts of the Corresponding Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that same
|
|
||||||
work.
|
|
||||||
|
|
||||||
#### 2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not convey,
|
|
||||||
without conditions so long as your license otherwise remains in force.
|
|
||||||
You may convey covered works to others for the sole purpose of having
|
|
||||||
them make modifications exclusively for you, or provide you with
|
|
||||||
facilities for running those works, provided that you comply with the
|
|
||||||
terms of this License in conveying all material for which you do not
|
|
||||||
control copyright. Those thus making or running the covered works for
|
|
||||||
you must do so exclusively on your behalf, under your direction and
|
|
||||||
control, on terms that prohibit them from making any copies of your
|
|
||||||
copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under the
|
|
||||||
conditions stated below. Sublicensing is not allowed; section 10 makes
|
|
||||||
it unnecessary.
|
|
||||||
|
|
||||||
#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such
|
|
||||||
circumvention is effected by exercising rights under this License with
|
|
||||||
respect to the covered work, and you disclaim any intention to limit
|
|
||||||
operation or modification of the work as a means of enforcing, against
|
|
||||||
the work's users, your or third parties' legal rights to forbid
|
|
||||||
circumvention of technological measures.
|
|
||||||
|
|
||||||
#### 4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
#### 5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
- a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
- b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under
|
|
||||||
section 7. This requirement modifies the requirement in section 4
|
|
||||||
to "keep intact all notices".
|
|
||||||
- c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
- d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
#### 6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms of
|
|
||||||
sections 4 and 5, provided that you also convey the machine-readable
|
|
||||||
Corresponding Source under the terms of this License, in one of these
|
|
||||||
ways:
|
|
||||||
|
|
||||||
- a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
- b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the Corresponding
|
|
||||||
Source from a network server at no charge.
|
|
||||||
- c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
- d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
- e) Convey the object code using peer-to-peer transmission,
|
|
||||||
provided you inform other peers where the object code and
|
|
||||||
Corresponding Source of the work are being offered to the general
|
|
||||||
public at no charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal,
|
|
||||||
family, or household purposes, or (2) anything designed or sold for
|
|
||||||
incorporation into a dwelling. In determining whether a product is a
|
|
||||||
consumer product, doubtful cases shall be resolved in favor of
|
|
||||||
coverage. For a particular product received by a particular user,
|
|
||||||
"normally used" refers to a typical or common use of that class of
|
|
||||||
product, regardless of the status of the particular user or of the way
|
|
||||||
in which the particular user actually uses, or expects or is expected
|
|
||||||
to use, the product. A product is a consumer product regardless of
|
|
||||||
whether the product has substantial commercial, industrial or
|
|
||||||
non-consumer uses, unless such uses represent the only significant
|
|
||||||
mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to
|
|
||||||
install and execute modified versions of a covered work in that User
|
|
||||||
Product from a modified version of its Corresponding Source. The
|
|
||||||
information must suffice to ensure that the continued functioning of
|
|
||||||
the modified object code is in no case prevented or interfered with
|
|
||||||
solely because modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or
|
|
||||||
updates for a work that has been modified or installed by the
|
|
||||||
recipient, or for the User Product in which it has been modified or
|
|
||||||
installed. Access to a network may be denied when the modification
|
|
||||||
itself materially and adversely affects the operation of the network
|
|
||||||
or violates the rules and protocols for communication across the
|
|
||||||
network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
#### 7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders
|
|
||||||
of that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
- a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
- b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
- c) Prohibiting misrepresentation of the origin of that material,
|
|
||||||
or requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
- d) Limiting the use for publicity purposes of names of licensors
|
|
||||||
or authors of the material; or
|
|
||||||
- e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
- f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions
|
|
||||||
of it) with contractual assumptions of liability to the recipient,
|
|
||||||
for any liability that these contractual assumptions directly
|
|
||||||
impose on those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions; the
|
|
||||||
above requirements apply either way.
|
|
||||||
|
|
||||||
#### 8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your license
|
|
||||||
from a particular copyright holder is reinstated (a) provisionally,
|
|
||||||
unless and until the copyright holder explicitly and finally
|
|
||||||
terminates your license, and (b) permanently, if the copyright holder
|
|
||||||
fails to notify you of the violation by some reasonable means prior to
|
|
||||||
60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
#### 9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or run
|
|
||||||
a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
#### 10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
#### 11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims owned
|
|
||||||
or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within the
|
|
||||||
scope of its coverage, prohibits the exercise of, or is conditioned on
|
|
||||||
the non-exercise of one or more of the rights that are specifically
|
|
||||||
granted under this License. You may not convey a covered work if you
|
|
||||||
are a party to an arrangement with a third party that is in the
|
|
||||||
business of distributing software, under which you make payment to the
|
|
||||||
third party based on the extent of your activity of conveying the
|
|
||||||
work, and under which the third party grants, to any of the parties
|
|
||||||
who would receive the covered work from you, a discriminatory patent
|
|
||||||
license (a) in connection with copies of the covered work conveyed by
|
|
||||||
you (or copies made from those copies), or (b) primarily for and in
|
|
||||||
connection with specific products or compilations that contain the
|
|
||||||
covered work, unless you entered into that arrangement, or that patent
|
|
||||||
license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
#### 12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under
|
|
||||||
this License and any other pertinent obligations, then as a
|
|
||||||
consequence you may not convey it at all. For example, if you agree to
|
|
||||||
terms that obligate you to collect a royalty for further conveying
|
|
||||||
from those to whom you convey the Program, the only way you could
|
|
||||||
satisfy both those terms and this License would be to refrain entirely
|
|
||||||
from conveying the Program.
|
|
||||||
|
|
||||||
#### 13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
#### 14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU General Public License from time to time. Such new versions
|
|
||||||
will be similar in spirit to the present version, but may differ in
|
|
||||||
detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies that a certain numbered version of the GNU General Public
|
|
||||||
License "or any later version" applies to it, you have the option of
|
|
||||||
following the terms and conditions either of that numbered version or
|
|
||||||
of any later version published by the Free Software Foundation. If the
|
|
||||||
Program does not specify a version number of the GNU General Public
|
|
||||||
License, you may choose any version ever published by the Free
|
|
||||||
Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future versions
|
|
||||||
of the GNU General Public License can be used, that proxy's public
|
|
||||||
statement of acceptance of a version permanently authorizes you to
|
|
||||||
choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
#### 15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
|
||||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
|
||||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
|
||||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
|
||||||
CORRECTION.
|
|
||||||
|
|
||||||
#### 16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
|
|
||||||
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
|
||||||
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
|
|
||||||
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
|
||||||
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
|
|
||||||
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
|
||||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
#### 17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
### How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these
|
|
||||||
terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to
|
|
||||||
attach them to the start of each source file to most effectively state
|
|
||||||
the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper
|
|
||||||
mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands \`show w' and \`show c' should show the
|
|
||||||
appropriate parts of the General Public License. Of course, your
|
|
||||||
program's commands might be different; for a GUI interface, you would
|
|
||||||
use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. For more information on this, and how to apply and follow
|
|
||||||
the GNU GPL, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your
|
|
||||||
program into proprietary programs. If your program is a subroutine
|
|
||||||
library, you may consider it more useful to permit linking proprietary
|
|
||||||
applications with the library. If this is what you want to do, use the
|
|
||||||
GNU Lesser General Public License instead of this License. But first,
|
|
||||||
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
6
Doxyfile
6
Doxyfile
|
@ -51,7 +51,7 @@ PROJECT_BRIEF = "Electromagnetic multiple scattering library and toolki
|
||||||
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
||||||
# to the output directory.
|
# to the output directory.
|
||||||
|
|
||||||
PROJECT_LOGO = farfield.png
|
PROJECT_LOGO =
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||||
# into which the generated documentation will be written. If a relative path is
|
# into which the generated documentation will be written. If a relative path is
|
||||||
|
@ -753,7 +753,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = qpms notes misc finite_systems.md MIRRORS.md CLIUTILS.md README.md README.Triton.md finite_systems.md lattices.md TODO.md
|
INPUT = qpms notes finite_systems.md README.md README.Triton.md finite_systems.md lattices.md TODO.md
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
@ -1462,7 +1462,7 @@ MATHJAX_FORMAT = HTML-CSS
|
||||||
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = https://uslugi.necada.org/js/mathjax
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
||||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
# extension names that should be enabled during MathJax rendering. For example
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
|
|
14
MIRRORS.md
14
MIRRORS.md
|
@ -1,14 +0,0 @@
|
||||||
QPMS source code mirrors
|
|
||||||
========================
|
|
||||||
|
|
||||||
QPMS source code is available at several locations; in all of the following,
|
|
||||||
upstream `master` branch is kept up-to-date. Various development branches
|
|
||||||
are not necessarily pushed everywhere (and they should be considered
|
|
||||||
unstable in the sense that rebases and forced pushes are possible).
|
|
||||||
|
|
||||||
mirror | note | provider | backend
|
|
||||||
----------------------------------------------- | ----------------------- | ------------------------------------------------- | ------
|
|
||||||
<https://repo.or.cz/qpms.git> | primary public upstream | [repo.or.cz](https://repo.or.cz/) | girocco
|
|
||||||
<https://codeberg.org/QPMS/qpms> | | [Codeberg](https://codeberg.org) | gitea
|
|
||||||
<https://git.piraattipuolue.fi/QPMS/qpms.git> | | [Pirate Party Finland](https://piraattipuolue.fi) | gitea
|
|
||||||
<https://version.aalto.fi/gitlab/qpms/qpms.git> | | [Aalto University](https://aalto.fi) | gitlab
|
|
127
README.md
127
README.md
|
@ -1,14 +1,10 @@
|
||||||
[![Build Status](https://drone.perkele.eu/api/badges/QPMS/qpms/status.svg)](https://drone.perkele.eu/QPMS/qpms)
|
|
||||||
|
|
||||||
QPMS README
|
QPMS README
|
||||||
===========
|
===========
|
||||||
|
|
||||||
[QPMS][homepage] (standing for QPMS Photonic Multiple Scattering)
|
QPMS is a toolkit for frequency-domain simulations of photonic systems
|
||||||
is a toolkit for frequency-domain simulations of photonic systems
|
|
||||||
consisting of compact objects (particles) inside a homogeneous medium. Scattering
|
consisting of compact objects (particles) inside a homogeneous medium. Scattering
|
||||||
properties of the individual particles are described by their T-matrices
|
properties of the individual particles are described by their T-matrices
|
||||||
(which can be obtained using one of the built-in generators or
|
(which can be obtained e.g. with the `scuff-tmatrix` tool from
|
||||||
e.g. with the `scuff-tmatrix` tool from
|
|
||||||
the [SCUFF-EM] suite).
|
the [SCUFF-EM] suite).
|
||||||
|
|
||||||
QPMS handles the multiple scattering of electromagnetic radiation between
|
QPMS handles the multiple scattering of electromagnetic radiation between
|
||||||
|
@ -16,39 +12,26 @@ the particles. The system can consist either of a finite number of particles
|
||||||
or an infinite number of periodically arranged lattices (with finite number
|
or an infinite number of periodically arranged lattices (with finite number
|
||||||
of particles in a single unit cell).
|
of particles in a single unit cell).
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
||||||
Finite systems
|
Finite systems
|
||||||
--------------
|
--------------
|
||||||
* Computing multipole excitations and fields scattered from nanoparticle
|
* Computing multipole excitations *and fields (TODO)* scattered from nanoparticle
|
||||||
clusters illuminated by plane, spherical or *cylindrical (TODO)* waves.
|
clusters illuminated by plane, spherical or *cylindrical (TODO)* waves.
|
||||||
* Finding eigenmodes (optical resonances).
|
* Finding eigenmodes.
|
||||||
* Calculating cross sections.
|
* *Calculating cross sections (TODO).*
|
||||||
* Reducing numerical complexity of the computations by exploiting
|
* Reducing numerical complexity of the computations by exploiting
|
||||||
symmetries of the cluster (decomposition to irreducible representations).
|
symmetries of the cluster (decomposition to irreducible representations).
|
||||||
|
|
||||||
|
|
||||||
Infinite systems (lattices)
|
Infinite systems (lattices)
|
||||||
---------------------------
|
---------------------------
|
||||||
* 2D-periodic systems with arbitrary unit cell geometry supported. (TODO 1D and 3D.)
|
* 2D-periodic systems supported. (TODO 1D and 3D.)
|
||||||
* Computing multipole excitations and fields scattered from nanoparticle
|
* *Calculation of transmission and reflection properties (TODO).*
|
||||||
* Finding eigenmodes and calculating dispersion relations.
|
* Finding eigenmodes and calculating dispersion relations.
|
||||||
* Calculation of the scattered fields.
|
* *Calculation of far-field radiation patterns of an excited array (TODO).*
|
||||||
* *Calculation of total transmission and reflection properties (TODO).*
|
* Reducing numerical complexity of the computations by exploiting
|
||||||
* *Reducing numerical complexity of the computations by exploiting
|
symmetries of the lattice (decomposition to irreducible representations).
|
||||||
symmetries of the lattice (decomposition to irreducible representations) (in development).*
|
|
||||||
|
|
||||||
|
|
||||||
Getting the code
|
|
||||||
================
|
|
||||||
|
|
||||||
The codebase is available at the main upstream public repository
|
|
||||||
<https://repo.or.cz/qpms.git> or any of the [maintained mirrors][MIRRORS].
|
|
||||||
Just clone the repository with `git` and proceed to the installation instructions
|
|
||||||
below.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
@ -64,16 +47,7 @@ you can [get the source and compile it yourself][GSL].
|
||||||
|
|
||||||
You also need a fresh enough version of [cmake][].
|
You also need a fresh enough version of [cmake][].
|
||||||
|
|
||||||
QPMS uses a C version of the Amos library for calculating Bessel function
|
After GSL is installed, you can install qpms to your local python library using
|
||||||
from a submodule. Before proceeding with running `cmake`, the submodules
|
|
||||||
need to be downloaded first (in the QPMS source root directory):
|
|
||||||
|
|
||||||
```{.sh}
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
```
|
|
||||||
|
|
||||||
After GSL is installed and submodules updated, you can install qpms to your local python library using
|
|
||||||
|
|
||||||
```{.sh}
|
```{.sh}
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=${YOUR_PREFIX} .
|
cmake -DCMAKE_INSTALL_PREFIX=${YOUR_PREFIX} .
|
||||||
|
@ -92,21 +66,13 @@ Special care might need to be taken when installing QPMS in cluster environments
|
||||||
Specific installation instructions for Aalto University's Triton cluster
|
Specific installation instructions for Aalto University's Triton cluster
|
||||||
can be found in a [separate document][TRITON-README].
|
can be found in a [separate document][TRITON-README].
|
||||||
|
|
||||||
Instructions for installation on Android-based devices are
|
|
||||||
in [another document][INSTALL-ANDROID].
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
|
||||||
[QPMS documentation][homepage] is a work in progress. Most of the newer code
|
Documentation of QPMS is a work in progress. Most of the newer code
|
||||||
is documented using [doxygen][] comments. Documentation generated for the
|
is documented using [doxygen][] comments. To build the documentation, just run
|
||||||
upstream version is hosted on the QPMS homepage <https://qpms.necada.org>.
|
|
||||||
|
|
||||||
To build the documentation yourself,
|
|
||||||
just run
|
|
||||||
`doxygen`
|
`doxygen`
|
||||||
in the QPMS source root directory; the documentation will then be found in
|
in the root directory; the documentation will then be found in
|
||||||
`docs/html/index.html`.
|
`docs/html/index.html`.
|
||||||
|
|
||||||
Of course, the prerequisite of this is having doxygen installed.
|
Of course, the prerequisite of this is having doxygen installed.
|
||||||
|
@ -118,77 +84,14 @@ under root.
|
||||||
Tutorials
|
Tutorials
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
* [Infinite system (lattice) tutorial][tutorial-infinite]
|
||||||
* [Finite system tutorial][tutorial-finite]
|
* [Finite system tutorial][tutorial-finite]
|
||||||
|
|
||||||
See also the examples directory in the source repository.
|
|
||||||
|
|
||||||
|
|
||||||
Command line utilities
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
* [Overview of the Python command line utilities][cliutils]
|
|
||||||
|
|
||||||
|
|
||||||
Acknowledgments
|
|
||||||
================
|
|
||||||
|
|
||||||
This software has been developed in the [Quantum Dynamics research group][QD],
|
|
||||||
Aalto University, Finland. If you use the code in your work, please cite
|
|
||||||
**M. Nečada and P. Törmä, Multiple-scattering T-matrix simulations for nanophotonics: symmetries and periodic lattices, [arXiv: 2006.12968][lepaper] (2020)**
|
|
||||||
in your publications, presentations, and similar.
|
|
||||||
|
|
||||||
Please also have a look at other publications by the group
|
|
||||||
(google scholar Päivi Törmä), they may be useful for your work as well.
|
|
||||||
|
|
||||||
|
|
||||||
Bug reports
|
|
||||||
===========
|
|
||||||
|
|
||||||
If you believe that some parts of QPMS behave incorrectly, please mail
|
|
||||||
a bug report to [marek@necada.org][authormail]. To ensure that your message is not
|
|
||||||
considered spam, please start the subject line with `QPMS`.
|
|
||||||
|
|
||||||
If you were able to fix a bug yourself, please include the patch as well,
|
|
||||||
see below.
|
|
||||||
|
|
||||||
|
|
||||||
Contributions
|
|
||||||
=============
|
|
||||||
|
|
||||||
Contributions to QPMS are welcome, be it bug fixes, improvements to the
|
|
||||||
documentation, code quality, or new features.
|
|
||||||
|
|
||||||
You can send patches prepared using the
|
|
||||||
[`git format-patch`](https://git-scm.com/docs/git-format-patch) tool
|
|
||||||
to [marek@necada.org][authormail].
|
|
||||||
|
|
||||||
If you plan to contribute with major changes to the codebase, it is
|
|
||||||
recommended to discuss that first (see the contact information below).
|
|
||||||
|
|
||||||
|
|
||||||
Contact & discussion
|
|
||||||
====================
|
|
||||||
|
|
||||||
You can contact the main author e.g. via [e-mail][authormail]
|
|
||||||
or [Telegram](https://t.me/necadam).
|
|
||||||
|
|
||||||
You are also warmly welcome to the [QPMS user chat][telegramchat]
|
|
||||||
in Telegram!
|
|
||||||
|
|
||||||
|
|
||||||
[homepage]: https://qpms.necada.org
|
|
||||||
[SCUFF-EM]: https://homerreid.github.io/scuff-em-documentation/
|
[SCUFF-EM]: https://homerreid.github.io/scuff-em-documentation/
|
||||||
[OpenBLAS]: https://www.openblas.net/
|
[OpenBLAS]: https://www.openblas.net/
|
||||||
[GSL]: https://www.gnu.org/software/gsl/
|
[GSL]: https://www.gnu.org/software/gsl/
|
||||||
[cmake]: https://cmake.org
|
[cmake]: https://cmake.org
|
||||||
[TRITON-README]: README.Triton.md
|
[TRITON-README]: README.Triton.md
|
||||||
[INSTALL-ANDROID]: notes/INSTALL_ANDROID.md
|
|
||||||
[tutorial-finite]: finite_systems.md
|
[tutorial-finite]: finite_systems.md
|
||||||
[tutorial-infinite]: lattices.md
|
[tutorial-infinite]: lattices.md
|
||||||
[doxygen]: http://doxygen.nl/
|
[doxygen]: http://doxygen.nl/
|
||||||
[QD]: https://www.aalto.fi/en/department-of-applied-physics/quantum-dynamics-qd
|
|
||||||
[lepaper]: https://arxiv.org/abs/2006.12968
|
|
||||||
[telegramchat]: https://t.me/QPMScattering
|
|
||||||
[authormail]: mailto:marek@necada.org
|
|
||||||
[cliutils]: CLIUTILS.md
|
|
||||||
[MIRRORS]: MIRRORS.md
|
|
||||||
|
|
29
TODO.md
29
TODO.md
|
@ -1,12 +1,11 @@
|
||||||
TODO list before 1.0 release
|
TODO list before public release
|
||||||
============================
|
===============================
|
||||||
|
|
||||||
- Tests!
|
- Tests!
|
||||||
- Docs!
|
- Docs!
|
||||||
- Cross section calculations. (Done in some Python scripts.)
|
- Cross section calculations.
|
||||||
- Field calculations. (Partly done, needs more testing.)
|
- Field calculations.
|
||||||
* Also test periodic vs. nonperiodic consistence (big finite lattice + absorbing medium vs. infinite lattice + absorbing medium).
|
- Complex frequencies, n's, k's.
|
||||||
- Complex frequencies, n's, k's. (Mostly done.)
|
|
||||||
- Transforming point (meta)generators.
|
- Transforming point (meta)generators.
|
||||||
- Check whether moble's quaternions and my
|
- Check whether moble's quaternions and my
|
||||||
quaternions give the same results in tmatrices.py
|
quaternions give the same results in tmatrices.py
|
||||||
|
@ -25,12 +24,11 @@ TODO list before 1.0 release
|
||||||
* As a description of a T-matrix / particle metadata.
|
* As a description of a T-matrix / particle metadata.
|
||||||
- Nice CLI for all general enough utilities.
|
- Nice CLI for all general enough utilities.
|
||||||
- Remove legacy code.
|
- Remove legacy code.
|
||||||
- Split `qpms_c.pyx`.
|
- Split qpms_c.pyx.
|
||||||
- Reduce compiler warnings.
|
- Reduce compiler warnings.
|
||||||
- Serialisation (saving, loading) of `ScatteringSystem` and other structures.
|
|
||||||
- Python exceptions instead of hard crashes in the C library where possible.
|
- Python exceptions instead of hard crashes in the C library where possible.
|
||||||
- Scatsystem init sometimes fail due to rounding errors and hardcoded absolute tolerance
|
- 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?
|
- Prefix all identifiers. Maybe think about a different prefix than qpms?
|
||||||
- Consistent indentation and style overall.
|
- Consistent indentation and style overall.
|
||||||
- Rewrite the parallelized translation matrix, mode problem matrix generators
|
- Rewrite the parallelized translation matrix, mode problem matrix generators
|
||||||
|
@ -41,16 +39,3 @@ Nice but less important features
|
||||||
|
|
||||||
- Static, thread-safe caches of constant coefficients + API without the current "calculators".
|
- Static, thread-safe caches of constant coefficients + API without the current "calculators".
|
||||||
|
|
||||||
|
|
||||||
Optimisations
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- Leaving out the irrelevant elements if a "rectangular" block of the translations matrix is needed.
|
|
||||||
- Ewald sums with "non-parallel" shifts (are about 20 times slower than the purely parallel ones).
|
|
||||||
- Reusing intermediate results (profiling needed)
|
|
||||||
* Bessel, Legendre functions (see also branch `finite_lattice_speedup`)
|
|
||||||
* Lattice points (sorting and scaling)
|
|
||||||
* Γ/Δ functions (for periodic lattices)
|
|
||||||
- More parallelisation.
|
|
||||||
- Possibly pre-calculation of the (precise) coefficients in Bessel and Legendre functions (using gmp)
|
|
||||||
- Asymptotic approximations of the Bessel functions for far fields.
|
|
||||||
|
|
30
amos/camos.h
30
amos/camos.h
|
@ -1,30 +0,0 @@
|
||||||
#ifndef CAMOS_H_
|
|
||||||
#define CAMOS_H_
|
|
||||||
#include "amos.h"
|
|
||||||
|
|
||||||
// TODO what about all the INTEGER_t and DOUBLE_PRECISION_t?
|
|
||||||
|
|
||||||
static inline int camos_zbesh(double zr, double zi, double fnu, int kode, int m,
|
|
||||||
int n, double *cyr, double *cyi, int *nz) {
|
|
||||||
int ierr;
|
|
||||||
amos_zbesh(&zr, &zi, &fnu, &kode, &m, &n, cyr, cyi, nz, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int camos_zbesj(double zr, double zi, double fnu, int kode, int n, double *cyr,
|
|
||||||
double *cyi, int *nz) {
|
|
||||||
int ierr;
|
|
||||||
double cwrkr[n], cwrki[n];
|
|
||||||
amos_zbesj(&zr, &zi, &fnu, &kode, &n, cyr, cyi, nz, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int camos_zbesy(double zr, double zi, double fnu, int kode, int n, double *cyr,
|
|
||||||
double *cyi, int *nz, double *cwrkr, double *cwrki) {
|
|
||||||
int ierr;
|
|
||||||
amos_zbesy(&zr, &zi, &fnu, &kode, &n, cyr, cyi, nz, cwrkr, cwrki, &ierr);
|
|
||||||
return ierr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CAMOS_H_
|
|
1
camos
1
camos
|
@ -1 +0,0 @@
|
||||||
Subproject commit 19e7ae82e7e0b436bd273557a87d288f8f338221
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
DP=Dockerfile_parts
|
|
||||||
# "Build environment" Dockerfiles
|
|
||||||
cat >Dockerfile.benv.debian.bnl ${DP}/00_common.debian ${DP}/01_numlibs.built
|
|
||||||
cat >Dockerfile.benv.debian.pnl ${DP}/00_common.debian ${DP}/01_numlibs.debian.pkgd
|
|
||||||
cat >Dockerfile.benv.alpine.bnl ${DP}/00_common.alpine ${DP}/01_numlibs.built
|
|
||||||
cat >Dockerfile.benv.alpine.pnl ${DP}/00_common.alpine ${DP}/01_numlibs.alpine.pkgd
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
docker build -t qpms/buildenv/debian/builtnumlib -f Dockerfile.benv.debian.bnl .
|
|
||||||
docker build -t qpms/buildenv/debian/pkgdnumlib -f Dockerfile.benv.debian.pnl .
|
|
||||||
docker build -t qpms/buildenv/alpine/builtnumlib -f Dockerfile.benv.alpine.bnl .
|
|
||||||
docker build -t qpms/buildenv/alpine/pkgdnumlib -f Dockerfile.benv.alpine.pnl .
|
|
|
@ -1,5 +0,0 @@
|
||||||
FROM alpine:latest AS commondeps
|
|
||||||
RUN apk update \
|
|
||||||
&& apk add cmake python3-dev py3-pip gcc g++ wget git make libc-dev bc \
|
|
||||||
&& adduser -D qpmsbuild
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
FROM debian:stable AS commondeps
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get -y install --no-install-recommends build-essential cmake python3 python3-pip git wget python3-dev bc \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& useradd -m qpmsbuild
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
FROM commondeps AS numlibs
|
|
||||||
# openblas-dev adds gfortran :(
|
|
||||||
RUN apk add openblas-dev gsl-dev
|
|
|
@ -1,16 +0,0 @@
|
||||||
FROM commondeps AS buildopenblas
|
|
||||||
USER qpmsbuild
|
|
||||||
RUN cd && git clone --depth 1 https://github.com/xianyi/OpenBLAS.git \
|
|
||||||
&& cd OpenBLAS && make \
|
|
||||||
&& make install PREFIX=$HOME/.local/ \
|
|
||||||
&& make clean \
|
|
||||||
&& cd .. && rm -rf OpenBLAS
|
|
||||||
|
|
||||||
FROM buildopenblas AS numlibs
|
|
||||||
USER qpmsbuild
|
|
||||||
RUN cd && wget https://ftp.gnu.org/gnu/gsl/gsl-latest.tar.gz \
|
|
||||||
&& tar xf gsl-latest.tar.gz \
|
|
||||||
&& cd $( tar tf gsl-latest.tar.gz | head -n 1 ) \
|
|
||||||
&& ./configure --prefix=$HOME/.local \
|
|
||||||
&& make && make install && make clean \
|
|
||||||
&& cd .. && rm -rf $OLDPWD gsl-latest.tar.gz
|
|
|
@ -1,4 +0,0 @@
|
||||||
FROM commondeps AS numlibs
|
|
||||||
RUN apt-get -y install --no-install-recommends libopenblas-dev libgsl-dev liblapacke-dev \
|
|
||||||
&& apt-get clean
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
FROM numlibs AS buildqpms
|
|
||||||
USER qpmsbuild
|
|
||||||
ENV LD_LIBRARY_PATH /home/qpmsbuild/.local/lib
|
|
||||||
ENV LIBRARY_PATH /home/qpmsbuild/.local/lib
|
|
||||||
ENV C_INCLUDE_PATH /home/qpmsbuild/.local/include
|
|
||||||
RUN cd && git clone --depth 1 https://repo.or.cz/qpms.git \
|
|
||||||
&& cd qpms && git submodule init && git submodule update
|
|
||||||
RUN cd ~/qpms && cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local . \
|
|
||||||
&& make \
|
|
||||||
&& make install
|
|
||||||
RUN cd ~/qpms && python3 setup.py install --user
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../.drone.yml
|
|
|
@ -1,284 +0,0 @@
|
||||||
# - Returns a version string from Git
|
|
||||||
#
|
|
||||||
# These functions force a re-configure on each git commit so that you can
|
|
||||||
# trust the values of the variables in your build system.
|
|
||||||
#
|
|
||||||
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
|
|
||||||
#
|
|
||||||
# Returns the refspec and sha hash of the current head revision
|
|
||||||
#
|
|
||||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe on the source tree, and adjusting
|
|
||||||
# the output so that it tests false if an error occurs.
|
|
||||||
#
|
|
||||||
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe on the working tree (--dirty option),
|
|
||||||
# and adjusting the output so that it tests false if an error occurs.
|
|
||||||
#
|
|
||||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe --exact-match on the source tree,
|
|
||||||
# and adjusting the output so that it tests false if there was no exact
|
|
||||||
# matching tag.
|
|
||||||
#
|
|
||||||
# git_local_changes(<var>)
|
|
||||||
#
|
|
||||||
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
|
|
||||||
# Uses the return code of "git diff-index --quiet HEAD --".
|
|
||||||
# Does not regard untracked files.
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
#
|
|
||||||
# Copyright 2009-2013, Iowa State University.
|
|
||||||
# Copyright 2013-2020, Ryan Pavlik
|
|
||||||
# Copyright 2013-2020, Contributors
|
|
||||||
# SPDX-License-Identifier: BSL-1.0
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
if(__get_git_revision_description)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(__get_git_revision_description YES)
|
|
||||||
|
|
||||||
# We must run the following at "include" time, not at function call time,
|
|
||||||
# to find the path to this module rather than the path to a calling list file
|
|
||||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|
||||||
|
|
||||||
# Function _git_find_closest_git_dir finds the next closest .git directory
|
|
||||||
# that is part of any directory in the path defined by _start_dir.
|
|
||||||
# The result is returned in the parent scope variable whose name is passed
|
|
||||||
# as variable _git_dir_var. If no .git directory can be found, the
|
|
||||||
# function returns an empty string via _git_dir_var.
|
|
||||||
#
|
|
||||||
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
|
||||||
# neither foo nor bar contain a file/directory .git. This wil return
|
|
||||||
# C:/bla/.git
|
|
||||||
#
|
|
||||||
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
|
||||||
set(cur_dir "${_start_dir}")
|
|
||||||
set(git_dir "${_start_dir}/.git")
|
|
||||||
while(NOT EXISTS "${git_dir}")
|
|
||||||
# .git dir not found, search parent directories
|
|
||||||
set(git_previous_parent "${cur_dir}")
|
|
||||||
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
|
|
||||||
if(cur_dir STREQUAL git_previous_parent)
|
|
||||||
# We have reached the root directory, we are not in git
|
|
||||||
set(${_git_dir_var}
|
|
||||||
""
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(git_dir "${cur_dir}/.git")
|
|
||||||
endwhile()
|
|
||||||
set(${_git_dir_var}
|
|
||||||
"${git_dir}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(get_git_head_revision _refspecvar _hashvar)
|
|
||||||
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
|
|
||||||
|
|
||||||
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
|
|
||||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
|
|
||||||
else()
|
|
||||||
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
|
|
||||||
endif()
|
|
||||||
if(NOT "${GIT_DIR}" STREQUAL "")
|
|
||||||
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
|
|
||||||
"${GIT_DIR}")
|
|
||||||
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
|
|
||||||
# We've gone above the CMake root dir.
|
|
||||||
set(GIT_DIR "")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if("${GIT_DIR}" STREQUAL "")
|
|
||||||
set(${_refspecvar}
|
|
||||||
"GITDIR-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
set(${_hashvar}
|
|
||||||
"GITDIR-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Check if the current source dir is a git submodule or a worktree.
|
|
||||||
# In both cases .git is a file instead of a directory.
|
|
||||||
#
|
|
||||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
|
||||||
# The following git command will return a non empty string that
|
|
||||||
# points to the super project working tree if the current
|
|
||||||
# source dir is inside a git submodule.
|
|
||||||
# Otherwise the command will return an empty string.
|
|
||||||
#
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" rev-parse
|
|
||||||
--show-superproject-working-tree
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT "${out}" STREQUAL "")
|
|
||||||
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
|
|
||||||
file(READ ${GIT_DIR} submodule)
|
|
||||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
|
|
||||||
${submodule})
|
|
||||||
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
|
|
||||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
|
||||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
|
|
||||||
ABSOLUTE)
|
|
||||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
|
||||||
else()
|
|
||||||
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
|
|
||||||
file(READ ${GIT_DIR} worktree_ref)
|
|
||||||
# The .git directory contains a path to the worktree information directory
|
|
||||||
# inside the parent git repo of the worktree.
|
|
||||||
#
|
|
||||||
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
|
|
||||||
${worktree_ref})
|
|
||||||
string(STRIP ${git_worktree_dir} git_worktree_dir)
|
|
||||||
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
|
|
||||||
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
|
|
||||||
endif()
|
|
||||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
|
||||||
if(NOT EXISTS "${GIT_DATA}")
|
|
||||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
|
||||||
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
|
|
||||||
|
|
||||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
|
||||||
"${GIT_DATA}/grabRef.cmake" @ONLY)
|
|
||||||
include("${GIT_DATA}/grabRef.cmake")
|
|
||||||
|
|
||||||
set(${_refspecvar}
|
|
||||||
"${HEAD_REF}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
set(${_hashvar}
|
|
||||||
"${HEAD_HASH}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_describe _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
get_git_head_revision(refspec hash)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
if(NOT hash)
|
|
||||||
set(${_var}
|
|
||||||
"HEAD-HASH-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TODO sanitize
|
|
||||||
#if((${ARGN}" MATCHES "&&") OR
|
|
||||||
# (ARGN MATCHES "||") OR
|
|
||||||
# (ARGN MATCHES "\\;"))
|
|
||||||
# message("Please report the following error to the project!")
|
|
||||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT res EQUAL 0)
|
|
||||||
set(out "${out}-${res}-NOTFOUND")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_describe_working_tree _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT res EQUAL 0)
|
|
||||||
set(out "${out}-${res}-NOTFOUND")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_get_exact_tag _var)
|
|
||||||
git_describe(out --exact-match ${ARGN})
|
|
||||||
set(${_var}
|
|
||||||
"${out}"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_local_changes _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
get_git_head_revision(refspec hash)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var}
|
|
||||||
"GIT-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
if(NOT hash)
|
|
||||||
set(${_var}
|
|
||||||
"HEAD-HASH-NOTFOUND"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE res
|
|
||||||
OUTPUT_VARIABLE out
|
|
||||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(res EQUAL 0)
|
|
||||||
set(${_var}
|
|
||||||
"CLEAN"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${_var}
|
|
||||||
"DIRTY"
|
|
||||||
PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
|
@ -1,43 +0,0 @@
|
||||||
#
|
|
||||||
# Internal file for GetGitRevisionDescription.cmake
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
# Iowa State University HCI Graduate Program/VRAC
|
|
||||||
#
|
|
||||||
# Copyright 2009-2012, Iowa State University
|
|
||||||
# Copyright 2011-2015, Contributors
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
# SPDX-License-Identifier: BSL-1.0
|
|
||||||
|
|
||||||
set(HEAD_HASH)
|
|
||||||
|
|
||||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
|
||||||
|
|
||||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
|
||||||
if(HEAD_CONTENTS MATCHES "ref")
|
|
||||||
# named branch
|
|
||||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
|
||||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
|
||||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
else()
|
|
||||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
|
||||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
|
||||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
|
||||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# detached HEAD
|
|
||||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT HEAD_HASH)
|
|
||||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
|
||||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
|
||||||
endif()
|
|
|
@ -1,23 +0,0 @@
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
from qpms import TMatrixGenerator, BaseSpec, eV, hbar
|
|
||||||
import numpy as np
|
|
||||||
import sys
|
|
||||||
|
|
||||||
errors = 0
|
|
||||||
|
|
||||||
def tmg_diagonal_fun(tmatrix, omega):
|
|
||||||
'''
|
|
||||||
Example of a python function used as a custom T-matrix generator
|
|
||||||
|
|
||||||
It receives a CTMatrix argument with pre-filled BaseSpec
|
|
||||||
(in tmatrix.spec) and angular frequency.
|
|
||||||
|
|
||||||
It has to fill in the T-matrix elements tmatrix[...]
|
|
||||||
(a numpy array of shape (len(tmatrix.spec),len(tmatrix.spec)))
|
|
||||||
and return zero (on success) or other integral value on error.
|
|
||||||
|
|
||||||
Note that this in justa an example of using the API,
|
|
||||||
not supposed to be anything physical.
|
|
||||||
'''
|
|
||||||
l = tmatrix.spec.l()
|
|
||||||
tmatrix[...] = np.diag(1./l**2)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# Wrap the function as an actual TMatrixGenerator
|
|
||||||
tmg_diagonal = TMatrixGenerator(tmg_diagonal_fun)
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax=2)
|
|
||||||
|
|
||||||
tmatrix = tmg_diagonal(bspec, (2.0+.01j) * eV/hbar)
|
|
||||||
|
|
||||||
errors += np.sum(tmatrix[...] != np.diag(1./bspec.l()**2))
|
|
||||||
|
|
||||||
sys.exit(errors)
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
echo 'scale=20;pi=3.14159265358979323846;' > bc_env
|
|
||||||
export BC_ENV_ARGS="bc_env"
|
|
||||||
|
|
||||||
# We put those into bc, which does not understant exponential notation
|
|
||||||
SEPARATION_nm=576
|
|
||||||
|
|
||||||
# Particle positions within unit cell
|
|
||||||
export P1X_nm=0
|
|
||||||
export P1Y_nm=$(bc <<< ${SEPARATION_nm}/2)
|
|
||||||
export P2X_nm=0
|
|
||||||
export P2Y_nm=-$P1Y_nm
|
|
||||||
|
|
||||||
# Lattice vectors
|
|
||||||
export A1X_nm=$(bc <<< ${SEPARATION_nm}'*sqrt(3)')
|
|
||||||
export A1Y_nm=0
|
|
||||||
export A2X_nm=$(bc <<< ${SEPARATION_nm}'*sqrt(3)/2')
|
|
||||||
export A2Y_nm=$(bc <<< ${SEPARATION_nm}'*3/2')
|
|
||||||
|
|
||||||
# Reciprocal lattice vectors
|
|
||||||
export B1X_nmi=$(bc <<< '2*pi/sqrt(3)/'${SEPARATION_nm})
|
|
||||||
export B1Y_nmi=$(bc <<< '-2*pi/3/'${SEPARATION_nm})
|
|
||||||
export B2X_nmi=0
|
|
||||||
export B2Y_nmi=$(bc <<< '4*pi/3/'${SEPARATION_nm})
|
|
||||||
|
|
||||||
# a K-point coordinates
|
|
||||||
export KPOINTX_nmi=$(bc <<< '4*pi/3/sqrt(3)'/${SEPARATION_nm})
|
|
||||||
export KPOINTY_nmi=0.0 #$(bc <<< '4*pi/3/sqrt(3)'/${SEPARATION_nm})
|
|
||||||
|
|
||||||
# a M-point coordinates
|
|
||||||
export MPOINTX_nmi=0.0
|
|
||||||
export MPOINTY_nmi=$(bc <<< '2*pi/3'/${SEPARATION_nm})
|
|
||||||
|
|
||||||
|
|
||||||
export RADIUS_nm=50
|
|
||||||
export HEIGHT_nm=50
|
|
||||||
export METAL=Au
|
|
||||||
export BG_REFINDEX=1.52
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-d -3 \
|
|
||||||
-t 0.01 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-F 1.3 0.001 1.5 \
|
|
||||||
-P
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 1.50 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e13 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.00 0.01 1.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${MPOINTX_nmi}*${coeff})e9 s$(bc <<< ${MPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.3 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 2 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 2.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d -$bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
scale=20;pi=3.14159265358979323846;
|
|
|
@ -1,37 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Common parameters for a rectangular array
|
|
||||||
# N.B. We put those into bc, which does not understant exponential notation
|
|
||||||
|
|
||||||
export PX_nm=375
|
|
||||||
export PY_nm=375
|
|
||||||
export RADIUS_nm=30
|
|
||||||
export HEIGHT_nm=30
|
|
||||||
export METAL=Ag
|
|
||||||
export BG_REFINDEX=1.52
|
|
||||||
|
|
||||||
|
|
||||||
# Setup bc
|
|
||||||
|
|
||||||
echo 'scale=20;pi=3.14159265358979323846;' > bc_env
|
|
||||||
export BC_ENV_ARGS="bc_env"
|
|
||||||
|
|
||||||
|
|
||||||
# We have only one particle per unit cell here
|
|
||||||
export P1X_nm=0
|
|
||||||
export P1Y_nm=0
|
|
||||||
|
|
||||||
|
|
||||||
# Lattice vectors (for the general scripts)
|
|
||||||
export A1X_nm=${PX_nm}
|
|
||||||
export A1Y_nm=0
|
|
||||||
export A2X_nm=0
|
|
||||||
export A2Y_nm=${PY_nm}
|
|
||||||
|
|
||||||
# Reciprocal lattice vectors
|
|
||||||
export B1X_nmi=$(bc <<< '1/'${PX_nm})
|
|
||||||
export B1Y_nmi=0
|
|
||||||
export B2X_nmi=0
|
|
||||||
export B2Y_nmi=$(bc <<< '1/'${PY_nm})
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s${KPOINTX_nmi}e9 s${KPOINTY_nmi}e9 \
|
|
||||||
-d -3 \
|
|
||||||
-t 0.01 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
# try several lMaxes
|
|
||||||
|
|
||||||
${MISCDIR}/lat2d_realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k 0 0 \
|
|
||||||
-F 2.001 0.001 2.250 \
|
|
||||||
-P
|
|
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
|
|
||||||
for LMAX in 1 2 3 ; do # try several cutoffs
|
|
||||||
${MISCDIR}/infiniterectlat-k0realfreqsvd.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L $LMAX -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-F 2.001 0.001 2.250 \
|
|
||||||
-P
|
|
||||||
done
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.80 0.01 1.50 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${KPOINTX_nmi}*${coeff})e9 s$(bc <<< ${KPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e13 \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 -3 -4 ; do
|
|
||||||
for coeff in $(seq 0.00 0.01 1.00 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-p s${P2X_nm}e-9 s${P2Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${MPOINTX_nmi}*${coeff})e9 s$(bc <<< ${MPOINTY_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-t 1e12 \
|
|
||||||
-T 0.3 \
|
|
||||||
-c 250 \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for bbb in 1 -2 2 -3 ; do
|
|
||||||
for coeff in $(seq -0.200 0.010 0.200 | sed -e s/,/./g) ; do
|
|
||||||
${MISCDIR}/lat2d_modes.py \
|
|
||||||
-n $BG_REFINDEX \
|
|
||||||
-b s${A1X_nm}e-9 s${A1Y_nm}e-9 \
|
|
||||||
-b s${A2X_nm}e-9 s${A2Y_nm}e-9 \
|
|
||||||
-p s${P1X_nm}e-9 s${P1Y_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
-k s$(bc <<< ${B1X_nmi}*${coeff})e9 s$(bc <<< ${B1Y_nmi}*${coeff})e9 \
|
|
||||||
-d $bbb \
|
|
||||||
-T 0.2 \
|
|
||||||
-c 250
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
../modes/00_params.sh
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/infiniterectlat-scatter.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.015:0.015|201" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-f "s2.110:2.230|100" \
|
|
||||||
-P
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 5 5\
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/infiniterectlat-scatter.py \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=50000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 140 100 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 140x100.npz -O 140x100.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=30000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 100 100 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 100x100.npz -O 100x100.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
##SBATCH --mem=50000
|
|
||||||
##SBATCH -c 12
|
|
||||||
##SBATCH -t 14:00:00
|
|
||||||
##SBATCH -p batch
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 0 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 140 140 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 2 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.05:0.05|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-o 140x140.npz -O 140x140.pdf \
|
|
||||||
-P \
|
|
||||||
-f 2.15
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
MISCDIR=../../../misc
|
|
||||||
|
|
||||||
source ${SCRIPTDIR}/00_params.sh
|
|
||||||
|
|
||||||
for PSI in 1; do
|
|
||||||
${MISCDIR}/finiterectlat-scatter.py \
|
|
||||||
--size 20 20 \
|
|
||||||
-B $BG_REFINDEX \
|
|
||||||
-p ${PX_nm}e-9 ${PY_nm}e-9 \
|
|
||||||
-L 3 -m $METAL -r ${RADIUS_nm}e-9 -H ${HEIGHT_nm}e-9 \
|
|
||||||
--theta "s-0.005:0.005|101" \
|
|
||||||
--phi 0 \
|
|
||||||
--psi $PSI \
|
|
||||||
--chi 0 \
|
|
||||||
-P \
|
|
||||||
-f "s2.150:2.180|100" \
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#SBATCH --mem=200
|
|
||||||
#SBATCH -t 30:00
|
|
||||||
#SBATCH -c 4
|
|
||||||
#SBATCH -p short-ivb
|
|
||||||
#SBATCH --array=0-250
|
|
||||||
|
|
||||||
cat $0
|
|
||||||
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
#radii_nm=(`seq 80 1 150`)
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for lMax in $(seq 1 5); do
|
|
||||||
srun rectlat_simple_modes.py -p 580e-9 -m '4+0.7j' -r ${radius_nm}e-9 -k 0 0 --kpi -n 1.52 -L lMax -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points}
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kx=0.0
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for lMax in $(seq 1 5) ; do
|
|
||||||
for radius_nm in $(seq 50 1 300) ; do
|
|
||||||
rectlat_simple_modes.py -p 580e-9 -m 'Au' -r ${radius_nm}e-9 -k $kx 0 --kpi -n 1.52 -L $lMax -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points} --lMax-extend 10
|
|
||||||
done
|
|
||||||
done
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kx=0.0
|
|
||||||
contour_points=410
|
|
||||||
|
|
||||||
radii_nm=(`seq 50 1 300`)
|
|
||||||
radius_nm=${radii_nm[$SLURM_ARRAY_TASK_ID]}
|
|
||||||
|
|
||||||
for radius_nm in $(seq 50 1 300) ; do
|
|
||||||
rectlat_simple_modes.py -p 580e-9 -m 'Au' -r ${radius_nm}e-9 -k $kx 0 --kpi -n 1.52 -L 1 -t 1e11 -b -2 -f 0.1 -i 1. -T .3 -N ${contour_points}
|
|
||||||
done
|
|
|
@ -1,300 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"%matplotlib inline\n",
|
|
||||||
"import re\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import matplotlib\n",
|
|
||||||
"from matplotlib import pyplot as plt\n",
|
|
||||||
"from scipy.constants import hbar, e as eV, c\n",
|
|
||||||
"eh = eV/hbar\n",
|
|
||||||
"import glob\n",
|
|
||||||
"def ri(z): return (z.real, z.imag)\n",
|
|
||||||
"#m = re.compile(r\"([^_]+)_r([0-9.]+)nm_\")\n",
|
|
||||||
"#removek = re.compile(r\"(k\\([^)]+\\)um-1_)\")\n",
|
|
||||||
"remover = re.compile(r\"r[0-9.]+nm_\")\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"markerdict = {\n",
|
|
||||||
" 4: \"3\",\n",
|
|
||||||
" -4: \"4\",\n",
|
|
||||||
" 3: \"^\",\n",
|
|
||||||
" -3: \"v\",\n",
|
|
||||||
" -2: 'x',\n",
|
|
||||||
" 2: '+',\n",
|
|
||||||
" 1: 's',\n",
|
|
||||||
" -1: 'd',\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"prop_cycle = plt.rcParams['axes.prop_cycle']\n",
|
|
||||||
"colors = prop_cycle.by_key()['color']\n",
|
|
||||||
"colordict = {i: colors[(i+1)] for i in range(-4,8)}\n",
|
|
||||||
"\n",
|
|
||||||
"def markerfun(b):\n",
|
|
||||||
" if b in markerdict.keys():\n",
|
|
||||||
" return markerdict[b]\n",
|
|
||||||
" else: return 'X'\n",
|
|
||||||
"\n",
|
|
||||||
"def colorfun(b):\n",
|
|
||||||
" if (b+1) in colordict.keys():\n",
|
|
||||||
" return colordict[b+1]\n",
|
|
||||||
" else: return colordict[0]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"allfiles=glob.glob('*sph*k(0_0)*.npz')\n",
|
|
||||||
"allgraphs=dict()\n",
|
|
||||||
"for f in allfiles:\n",
|
|
||||||
" base = remover.sub('', f)\n",
|
|
||||||
" if base in allgraphs.keys():\n",
|
|
||||||
" allgraphs[base] += 1\n",
|
|
||||||
" else:\n",
|
|
||||||
" allgraphs[base] = 1\n",
|
|
||||||
"for k in sorted(allgraphs.keys()):\n",
|
|
||||||
" print(k, allgraphs[k])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"ename": "FileNotFoundError",
|
|
||||||
"evalue": "[Errno 2] No such file or directory: 'projectors_D4h_lMax1.npz'",
|
|
||||||
"output_type": "error",
|
|
||||||
"traceback": [
|
|
||||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
||||||
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
|
|
||||||
"\u001b[0;32m<ipython-input-3-0c266089be08>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mlMaxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mlMax\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mlMax\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mlMax\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mlMaxes\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mproj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'projectors_D4h_lMax%d.npz'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mlMax\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mirlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mproj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mproj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mirlabels\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
||||||
"\u001b[0;32m~/.local/lib/python3.7/site-packages/numpy-1.17.3-py3.7-linux-x86_64.egg/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)\u001b[0m\n\u001b[1;32m 426\u001b[0m \u001b[0mown_fid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 427\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 428\u001b[0;31m \u001b[0mfid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mos_fspath\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"rb\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 429\u001b[0m \u001b[0mown_fid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 430\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
||||||
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'projectors_D4h_lMax1.npz'"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"projectors = dict()\n",
|
|
||||||
"projectors_list = dict()\n",
|
|
||||||
"lMaxes = [lMax for lMax in range(1,6)]\n",
|
|
||||||
"for lMax in lMaxes:\n",
|
|
||||||
" proj = np.load('projectors_D4h_lMax%d.npz' % lMax)\n",
|
|
||||||
" irlabels = sorted(proj.keys())\n",
|
|
||||||
" proj = {f: proj[f] for f in irlabels}\n",
|
|
||||||
" proj_list = [proj[irlabels[i]] for i in range(len(proj))]\n",
|
|
||||||
" projectors[lMax] = proj\n",
|
|
||||||
" projectors_list[lMax] = proj_list\n",
|
|
||||||
"globpattern = '*sph_r*_p580nmx580nm_mAu_n1.52_b?2_k(0_0)um-1_L?_cn???.npz'\n",
|
|
||||||
"filenames=glob.glob(globpattern)\n",
|
|
||||||
"plotfilename = 'collected_' + globpattern.replace('*', 'XXX').replace('?', 'X').replace('npz','pdf')\n",
|
|
||||||
"print(filenames[:4], plotfilename)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 41,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#projectors\n",
|
|
||||||
"#glob.glob('cyl_r100nm*L3*3100.npz')\n",
|
|
||||||
"#glob.glob('sph_r100*m5*.npz')\n",
|
|
||||||
"#dat['meta'][()],list(dat.keys())"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 42,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"inpure result detected [1. 0.99999999 1. 0.97991334 0.99999996 0.9999989\n",
|
|
||||||
" 0.99999983 0.99999966 0.99999322 0.99999721 0.99999653] [3.28735741e-04 2.66532534e-05 2.47011478e-05 1.45012420e-01\n",
|
|
||||||
" 2.44785416e-04 7.05405359e-04 1.60203586e-03 1.71245137e-03\n",
|
|
||||||
" 1.03244480e-02 9.18732728e-03 1.18651583e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.99999998 0.99999999 0.99999996 0.96608887\n",
|
|
||||||
" 0.99999852 0.99999397 0.99998951 0.99999912 0.99982435] [2.66223026e-04 2.12357147e-05 3.54211968e-05 1.06651057e-04\n",
|
|
||||||
" 2.79595790e-04 2.41939163e-01 2.17645058e-03 3.41541473e-03\n",
|
|
||||||
" 1.14507609e-02 1.49639498e-02 2.33483138e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.92521572 1. 0.99999627 0.99990293\n",
|
|
||||||
" 0.99946049] [1.59712906e-05 3.60193407e-05 2.48341492e-01 1.21848930e-03\n",
|
|
||||||
" 3.81805601e-03 2.42649228e-02 2.99534246e-02]\n",
|
|
||||||
"inpure result detected [1. 1. 0.99999998 0.99999961 0.93267685 0.99999964\n",
|
|
||||||
" 0.99999822 0.99921774 0.99995547 0.99997301] [5.22490396e-04 3.01556792e-05 4.88795563e-05 6.29703960e-04\n",
|
|
||||||
" 2.34414238e-01 3.72766210e-03 4.72444059e-03 7.62106094e-02\n",
|
|
||||||
" 6.32796684e-02 5.63231562e-02]\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"plotdata = {}\n",
|
|
||||||
"for file in filenames:\n",
|
|
||||||
" dat = np.load(file, allow_pickle=True)\n",
|
|
||||||
" kx = dat['meta'][()]['k'][0]\n",
|
|
||||||
" radius = dat['meta'][()]['radius']\n",
|
|
||||||
" b = dat['meta'][()]['band_index']\n",
|
|
||||||
" eigvals = dat['eigval']\n",
|
|
||||||
" lMax = dat['meta'][()]['lMax']\n",
|
|
||||||
" residuals = dat['residuals']\n",
|
|
||||||
" ef =dat['empty_freqs']\n",
|
|
||||||
" eigvecs = dat['eigvec']\n",
|
|
||||||
" irweights = []\n",
|
|
||||||
" #for proj in projectors_list[lMax]:\n",
|
|
||||||
" # try:\n",
|
|
||||||
" # irweights.append(np.linalg.norm(np.tensordot(proj, eigvecs, axes=(-1, -1)), axis=0,ord=2) if len(proj) != 0 else np.zeros((len(eigvecs),)))\n",
|
|
||||||
" # except ValueError as err:\n",
|
|
||||||
" # print(proj, len(proj))\n",
|
|
||||||
" # raise err\n",
|
|
||||||
" irweights = np.array(irweights)\n",
|
|
||||||
" #print(irweights)\n",
|
|
||||||
" irweights = np.array([np.linalg.norm(np.tensordot(proj, eigvecs, axes=(-1, -1)), axis=0,ord=2) if len(proj) != 0 else np.zeros((len(eigvecs),)) for proj in projectors_list[lMax]]).T\n",
|
|
||||||
" irclass = np.argmax(irweights, axis=-1)\n",
|
|
||||||
" purities = np.amax(irweights, axis=-1)\n",
|
|
||||||
" if (np.any(purities < 0.98)):\n",
|
|
||||||
" print(\"inpure result detected\", purities, residuals)\n",
|
|
||||||
" #print(purities)\n",
|
|
||||||
" \n",
|
|
||||||
" #for i in range(len(residuals)): \n",
|
|
||||||
" # if residuals[i] < 0.01:\n",
|
|
||||||
" # vec = eigvecs[i]\n",
|
|
||||||
" # for irlabel, proj in projectors.items():\n",
|
|
||||||
" # print(irlabel, np.linalg.norm(np.dot(proj, vec))) #maybe some conj() here?\n",
|
|
||||||
" # print('--->', irlabels[irclass[i]])\n",
|
|
||||||
"\n",
|
|
||||||
" \n",
|
|
||||||
" plotdata[(lMax,radius)] = (eigvals, residuals, b, ef, irclass,)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"fig = plt.figure(figsize=(15,6))\n",
|
|
||||||
"axesR = {}\n",
|
|
||||||
"axesI = {}\n",
|
|
||||||
"for i, lMax in enumerate(lMaxes):\n",
|
|
||||||
" axesR[lMax] = fig.add_subplot(2,len(lMaxes),i+1)\n",
|
|
||||||
" axesR[lMax].set_xlim([50,300])\n",
|
|
||||||
" axesR[lMax].set_ylim([1.25, ef[1]/eh])\n",
|
|
||||||
" axesI[lMax] = fig.add_subplot(2,len(lMaxes),len(lMaxes)+i+1)\n",
|
|
||||||
" axesI[lMax].set_xlim([50,300])\n",
|
|
||||||
" axesI[lMax].set_ylim([-60, 30])\n",
|
|
||||||
" axesR[lMax].set_title('$l_\\max = %d $' % lMax) \n",
|
|
||||||
" axesR[lMax].tick_params(labelbottom=False) \n",
|
|
||||||
" if i == len(lMaxes)//2:\n",
|
|
||||||
" axesI[lMax].set_xlabel(\"Particle base radius / nm\")\n",
|
|
||||||
" if i == 0:\n",
|
|
||||||
" axesR[lMax].set_ylabel('$\\hbar \\Re \\omega / \\mathrm{eV}$')\n",
|
|
||||||
" axesI[lMax].set_ylabel('$\\hbar \\Im \\omega / \\mathrm{meV}$')\n",
|
|
||||||
" else:\n",
|
|
||||||
" axesR[lMax].tick_params(labelleft=False) \n",
|
|
||||||
" axesI[lMax].tick_params(labelleft=False) \n",
|
|
||||||
"\n",
|
|
||||||
"res_thr = 0.005\n",
|
|
||||||
"\n",
|
|
||||||
"ir_labeled=set()\n",
|
|
||||||
"if True:\n",
|
|
||||||
" for (lMax, radius), (eigvals, residuals, b, ef, irclass) in plotdata.items():\n",
|
|
||||||
" for i, (e, res, iri) in enumerate(zip(eigvals, residuals, irclass)):\n",
|
|
||||||
" #if i == 0:\n",
|
|
||||||
" if res < res_thr:# and e.real < 2.14e15:\n",
|
|
||||||
" if iri in ir_labeled: \n",
|
|
||||||
" label=None\n",
|
|
||||||
" else:\n",
|
|
||||||
" ir_labeled.add(iri)\n",
|
|
||||||
" label=irlabels[iri]\n",
|
|
||||||
" axesR[lMax].plot(radius*1e9, e.real/eh, \n",
|
|
||||||
" marker='.',\n",
|
|
||||||
" #marker=markerfun(b),\n",
|
|
||||||
" ms=4, #c=colorfun(b)\n",
|
|
||||||
" c=matplotlib.cm.hsv(iri/9),\n",
|
|
||||||
" #c = colorfun(iri),\n",
|
|
||||||
" label=label,\n",
|
|
||||||
" )\n",
|
|
||||||
" axesI[lMax].plot(radius*1e9, e.imag/eh*1000, \n",
|
|
||||||
" #marker='x', \n",
|
|
||||||
" #c=colorfun(b), \n",
|
|
||||||
" c=matplotlib.cm.hsv(iri/9),#colorfun(iri),\n",
|
|
||||||
" marker='.', #markerfun(b),\n",
|
|
||||||
" ms=4,\n",
|
|
||||||
" #label=label\n",
|
|
||||||
" )\n",
|
|
||||||
"fig.legend(title=\"Irrep\", loc=\"center right\")\n",
|
|
||||||
"#fig.suptitle('$l_\\mathrm{max}=%d$, residual threshold = %g' % (lMax, res_thr) )\n",
|
|
||||||
"fig.savefig(plotfilename)\n",
|
|
||||||
"fig.savefig(plotfilename.replace('pdf', 'png'))\n",
|
|
||||||
"print(plotfilename)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([0. , 1.40635433, 1.98888536, 2.81270865, 3.14470387,\n",
|
|
||||||
" 3.97777072, 4.21906298, 4.44728287])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"ef / eh"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.7.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 4
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
project(Faddeeva VERSION 1.0 LANGUAGES C)
|
|
||||||
|
|
||||||
option(FADDEEVA_BUILD_STATIC "Build Faddeeva as static library" OFF)
|
|
||||||
|
|
||||||
if (FADDEEVA_BUILD_STATIC)
|
|
||||||
add_library(Faddeeva STATIC Faddeeva.h Faddeeva.c Faddeeva.cc)
|
|
||||||
else (FADDEEVA_BUILD_STATIC)
|
|
||||||
add_library(Faddeeva SHARED Faddeeva.c)
|
|
||||||
set_target_properties(Faddeeva PROPERTIES PUBLIC_HEADER "Faddeeva.h")
|
|
||||||
install(TARGETS Faddeeva
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
endif (FADDEEVA_BUILD_STATIC)
|
|
||||||
target_include_directories(Faddeeva PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
/* The Faddeeva.cc file contains macros to let it compile as C code
|
|
||||||
(assuming C99 complex-number support), so just #include it. */
|
|
||||||
#include "Faddeeva.cc"
|
|
2517
faddeeva/Faddeeva.cc
2517
faddeeva/Faddeeva.cc
File diff suppressed because it is too large
Load Diff
|
@ -1,68 +0,0 @@
|
||||||
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Available at: http://ab-initio.mit.edu/Faddeeva
|
|
||||||
|
|
||||||
Header file for Faddeeva.c; see Faddeeva.cc for more information. */
|
|
||||||
|
|
||||||
#ifndef FADDEEVA_H
|
|
||||||
#define FADDEEVA_H 1
|
|
||||||
|
|
||||||
// Require C99 complex-number support
|
|
||||||
#include <complex.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
// compute w(z) = exp(-z^2) erfc(-iz) [ Faddeeva / scaled complex error func ]
|
|
||||||
extern double complex Faddeeva_w(double complex z,double relerr);
|
|
||||||
extern double Faddeeva_w_im(double x); // special-case code for Im[w(x)] of real x
|
|
||||||
|
|
||||||
// Various functions that we can compute with the help of w(z)
|
|
||||||
|
|
||||||
// compute erfcx(z) = exp(z^2) erfc(z)
|
|
||||||
extern double complex Faddeeva_erfcx(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfcx_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erf(z), the error function of complex arguments
|
|
||||||
extern double complex Faddeeva_erf(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erf_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfi(z) = -i erf(iz), the imaginary error function
|
|
||||||
extern double complex Faddeeva_erfi(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfi_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfc(z) = 1 - erf(z), the complementary error function
|
|
||||||
extern double complex Faddeeva_erfc(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_erfc_re(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute Dawson(z) = sqrt(pi)/2 * exp(-z^2) * erfi(z)
|
|
||||||
extern double complex Faddeeva_Dawson(double complex z, double relerr);
|
|
||||||
extern double Faddeeva_Dawson_re(double x); // special case for real x
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif // FADDEEVA_H
|
|
|
@ -1,62 +0,0 @@
|
||||||
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Available at: http://ab-initio.mit.edu/Faddeeva
|
|
||||||
|
|
||||||
Header file for Faddeeva.cc; see that file for more information. */
|
|
||||||
|
|
||||||
#ifndef FADDEEVA_HH
|
|
||||||
#define FADDEEVA_HH 1
|
|
||||||
|
|
||||||
#include <complex>
|
|
||||||
|
|
||||||
namespace Faddeeva {
|
|
||||||
|
|
||||||
// compute w(z) = exp(-z^2) erfc(-iz) [ Faddeeva / scaled complex error func ]
|
|
||||||
extern std::complex<double> w(std::complex<double> z,double relerr=0);
|
|
||||||
extern double w_im(double x); // special-case code for Im[w(x)] of real x
|
|
||||||
|
|
||||||
// Various functions that we can compute with the help of w(z)
|
|
||||||
|
|
||||||
// compute erfcx(z) = exp(z^2) erfc(z)
|
|
||||||
extern std::complex<double> erfcx(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfcx(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erf(z), the error function of complex arguments
|
|
||||||
extern std::complex<double> erf(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erf(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfi(z) = -i erf(iz), the imaginary error function
|
|
||||||
extern std::complex<double> erfi(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfi(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute erfc(z) = 1 - erf(z), the complementary error function
|
|
||||||
extern std::complex<double> erfc(std::complex<double> z, double relerr=0);
|
|
||||||
extern double erfc(double x); // special case for real x
|
|
||||||
|
|
||||||
// compute Dawson(z) = sqrt(pi)/2 * exp(-z^2) * erfi(z)
|
|
||||||
extern std::complex<double> Dawson(std::complex<double> z, double relerr=0);
|
|
||||||
extern double Dawson(double x); // special case for real x
|
|
||||||
|
|
||||||
} // namespace Faddeeva
|
|
||||||
|
|
||||||
#endif // FADDEEVA_HH
|
|
BIN
farfield.png
BIN
farfield.png
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
|
@ -1,8 +1,6 @@
|
||||||
Using QPMS library for simulating finite systems
|
Using QPMS library for simulating finite systems
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
*** This tutorial is partly obsolete, the interpolators are no longer the first choice of getting the T-matrices. ***
|
|
||||||
|
|
||||||
The main C API for finite systems is defined in [scatsystem.h][], and the
|
The main C API for finite systems is defined in [scatsystem.h][], and the
|
||||||
most relevant parts are wrapped into python modules. The central data structure
|
most relevant parts are wrapped into python modules. The central data structure
|
||||||
defining the system of scatterers is [qpms_scatsys_t][],
|
defining the system of scatterers is [qpms_scatsys_t][],
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
Using QPMS library for finding modes of 2D-periodic systems
|
||||||
|
===========================================================
|
||||||
|
|
||||||
|
Calculating modes of infinite 2D arrays is now done
|
||||||
|
in several steps (assuming the T-matrices have already
|
||||||
|
been obtained using `scuff-tmatrix` or can be obtained
|
||||||
|
from Lorenz-Mie solution (spherical particles)):
|
||||||
|
|
||||||
|
1. Sampling the *k*, *ω* space.
|
||||||
|
2. Pre-calculating the
|
||||||
|
Ewald-summed translation operators.
|
||||||
|
3. For each *k*, *ω* pair, build the LHS operator
|
||||||
|
for the scattering problem (TODO reference), optionally decomposed
|
||||||
|
into suitable irreducible representation subspaces.
|
||||||
|
4. Evaluating the singular values and finding their minima.
|
||||||
|
|
||||||
|
The steps above may (and will) change as more user-friendly interface
|
||||||
|
will be developed.
|
||||||
|
|
||||||
|
|
||||||
|
Preparation: compile the `ew_gen_kin` utility
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
This will change, but at this point, the lattice-summed
|
||||||
|
translation operators are computed using the `ew_gen_kin`
|
||||||
|
utility located in the `qpms/apps` directory. It has to be built
|
||||||
|
manually like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd qpms/apps
|
||||||
|
c99 -o ew_gen_kin -Wall -I ../.. -I ../../amos/ -O2 -ggdb -DQPMS_VECTORS_NICE_TRANSFORMATIONS -DLATTICESUMS32 2dlattice_ewald.c ../translations.c ../ewald.c ../ewaldsf.c ../gaunt.c ../lattices2d.c ../latticegens.c ../bessel.c -lgsl -lm -lblas ../../amos/libamos.a -lgfortran ../error.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 1: Sampling the *k*, *ω* space
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
`ew_gen_kin` expects a list of (*k_x*, *k_y*)
|
||||||
|
pairs on standard input (separated by whitespaces),
|
||||||
|
the rest is specified via command line arguments.
|
||||||
|
|
||||||
|
So if we want to examine the line between the Г point and the point
|
||||||
|
\f$ k = (0, 10^5\,\mathrm{m}^{-1}) \f$, we can generate an input
|
||||||
|
running
|
||||||
|
```bash
|
||||||
|
for ky in $(seq 0 1e3 1e5); do
|
||||||
|
echo 0 $ky >> klist
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
It also make sense to pre-generate the list of *ω* values,
|
||||||
|
e.g.
|
||||||
|
```bash
|
||||||
|
seq 6.900 0.002 7.3 | sed -e 's/,/./g' > omegalist
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Step 2: Pre-calculating the translation operators
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
`ew_gen_kin` currently uses command-line arguments in
|
||||||
|
an atrocious way with a hard-coded order:
|
||||||
|
```
|
||||||
|
ew_gen_kin outfile b1.x b1.y b2.x b2.y lMax scuffomega refindex npart part0.x part0.y [part1.x part1.y [...]]
|
||||||
|
```
|
||||||
|
where `outfile` specifies the path to the output, `b1` and `b2` are the
|
||||||
|
direct lattice vectors, `lMax` is the multipole degree cutoff,
|
||||||
|
`scuffomega` is the frequency in the units used by `scuff-tmatrix`
|
||||||
|
(TODO specify), `refindex` is the refractive index of the background
|
||||||
|
medium, `npart` number of particles in the unit cell, and `partN` are
|
||||||
|
the positions of these particles inside the unit cell.
|
||||||
|
|
||||||
|
Assuming we have the `ew_gen_kin` binary in our `${PATH}`, we can
|
||||||
|
now run e.g.
|
||||||
|
```bash
|
||||||
|
for omega in $(cat omegalist); do
|
||||||
|
ew_gen_kin $omega 621e-9 0 0 571e-9 3 w_$omega 1.52 1 0 0 < klist
|
||||||
|
done
|
||||||
|
```
|
||||||
|
This pre-calculates the translation operators for a simple (one particle per unit cell)
|
||||||
|
621 nm × 571 nm rectangular lattice inside a medium with refractive index 1.52,
|
||||||
|
up to the octupole (`lMax` = 3) order, yielding one file per frequency.
|
||||||
|
This can take some time and
|
||||||
|
it makes sense to run a parallelised `for`-loop instead; this is a stupid but working
|
||||||
|
way to do it in bash:
|
||||||
|
```bash
|
||||||
|
N=4 # number of parallel processes
|
||||||
|
for omega in $(cat omegalist); do
|
||||||
|
((i=i%N)); ((i++==0)) && wait
|
||||||
|
ew_gen_kin $omega 621e-9 0 0 571e-9 3 w_$omega 1.52 1 0 0 < klist
|
||||||
|
echo $omega # optional, to follow progress
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
When this is done, we convert all the text output files into
|
||||||
|
numpy's binary format in order to speed up loading in the following steps.
|
||||||
|
This is done using the processWfiles_sortnames.py script located in the
|
||||||
|
`misc` directory. Its usage pattern is
|
||||||
|
```
|
||||||
|
processWfiles_sortnames.py npart dest src1 [src2 ...]
|
||||||
|
```
|
||||||
|
where `npart` is the number of particles in the unit cell, `dest`
|
||||||
|
is the destination path for the converted data (this will be
|
||||||
|
a directory), and the remaining arguments are paths to the
|
||||||
|
files generated by `ew_gen_kin`. In the case above, one could use
|
||||||
|
```
|
||||||
|
processWfiles_sortnames.py 1 all w_*
|
||||||
|
```
|
||||||
|
which would create a directory named `all` containing several
|
||||||
|
.npy files.
|
||||||
|
|
||||||
|
|
||||||
|
Steps 3, 4
|
||||||
|
----------
|
||||||
|
|
||||||
|
TODO. For the time being, see e.g. the `SaraRect/dispersions.ipynb` jupyter notebook
|
||||||
|
from the `qpms_ipynotebooks` repository
|
||||||
|
for the remaining steps.
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_longer.TMatrix'
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_new'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
tmatrix = interp(omega)
|
||||||
|
#print(tmatrix.m)
|
||||||
|
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.npz'%(Nx, Ny, omega/eV*hbar, iri,))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.done'%(Nx, Ny, omega/eV*hbar, iri,))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
#print(mm_iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
from pathlib import Path
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
cyr_part_height = 50*nm
|
||||||
|
cyr_part_radius = 50*nm
|
||||||
|
cyr_part_volume = cyr_part_height * np.pi * cyr_part_radius**2
|
||||||
|
eqv_sph_radius = (3/4/np.pi*cyr_part_volume)**(1/3)
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
#tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_cleaned.TMatrix'
|
||||||
|
materialfile = '/home/necadam1/wrkdir/repo/refractiveindex.info-database/database/data/main/Au/Johnson.yml'
|
||||||
|
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
#outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_sph'
|
||||||
|
outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_sph'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
mi = MaterialInterpolator(materialfile)
|
||||||
|
#interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
#tmatrix = interp(omega)
|
||||||
|
tmatrix = CTMatrix.spherical_perm(bspec, eqv_sph_radius, omega, mi(omega), n**2)
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.npz'%(Nx, Ny, omega/eV*hbar, iri))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d.done'%(Nx, Ny, omega/eV*hbar, iri))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# coding: utf-8
|
||||||
|
from qpms import Particle, CTMatrix, BaseSpec, FinitePointGroup, ScatteringSystem, TMatrixInterpolator, eV, hbar, c, MaterialInterpolator, scatsystem_set_nthreads
|
||||||
|
from qpms.symmetries import point_group_info
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
if 'SLURM_CPUS_PER_TASK' in os.environ:
|
||||||
|
scatsystem_set_nthreads(int(os.environ['SLURM_CPUS_PER_TASK']))
|
||||||
|
|
||||||
|
nm = 1e-9
|
||||||
|
|
||||||
|
rewrite_output = '--rewrite-output' in sys.argv
|
||||||
|
|
||||||
|
radiusfactor = float(sys.argv[5])
|
||||||
|
|
||||||
|
cyr_part_height = 50*nm
|
||||||
|
cyr_part_radius = 50*nm
|
||||||
|
cyr_part_volume = cyr_part_height * np.pi * cyr_part_radius**2
|
||||||
|
eqv_sph_radius = (3/4/np.pi*cyr_part_volume)**(1/3) * radiusfactor
|
||||||
|
|
||||||
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
|
bspec = BaseSpec(lMax = 2)
|
||||||
|
#tmfile = '/m/phys/project/qd/Marek/tmatrix-experiments/Cylinder/AaroBEC/cylinder_50nm_lMax4_cleaned.TMatrix'
|
||||||
|
materialfile = '/home/necadam1/wrkdir/repo/refractiveindex.info-database/database/data/main/Au/Johnson.yml'
|
||||||
|
|
||||||
|
#outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_new'
|
||||||
|
#outputdatadir = '/u/46/necadam1/unix/project/AaroBECfinite_sph'
|
||||||
|
outputdatadir = '/home/necadam1/wrkdir/AaroBECfinite_fatsph'
|
||||||
|
os.makedirs(outputdatadir, exist_ok = True)
|
||||||
|
mi = MaterialInterpolator(materialfile)
|
||||||
|
#interp = TMatrixInterpolator(tmfile, bspec, symmetrise = sym, atol = 1e-8)
|
||||||
|
# There is only one t-matrix in the system for each frequency. We initialize the matrix with the lowest frequency data.
|
||||||
|
# Later, we can replace it using the tmatrix[...] = interp(freq) and s.update_tmatrices NOT YET; TODO
|
||||||
|
|
||||||
|
omega = float(sys.argv[3]) * eV/hbar
|
||||||
|
sv_threshold = float(sys.argv[4])
|
||||||
|
|
||||||
|
|
||||||
|
# Now place the particles and set background index.
|
||||||
|
px = 571*nm; py = 621*nm
|
||||||
|
n = 1.52
|
||||||
|
Nx = int(sys.argv[1])
|
||||||
|
Ny = int(sys.argv[2])
|
||||||
|
|
||||||
|
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
||||||
|
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
#tmatrix = interp(omega)
|
||||||
|
tmatrix = CTMatrix.spherical_perm(bspec, eqv_sph_radius, omega, mi(omega), n**2)
|
||||||
|
particles = [Particle(orig_xy[i], tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
|
|
||||||
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
|
||||||
|
k = n * omega / c
|
||||||
|
|
||||||
|
|
||||||
|
for iri in range(ss.nirreps):
|
||||||
|
destpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d_r%gnm.npz'%(Nx, Ny, omega/eV*hbar, iri, eqv_sph_radius/nm))
|
||||||
|
touchpath = os.path.join(outputdatadir, 'Nx%d_Ny%d_%geV_ir%d_r%gnm.done'%(Nx, Ny, omega/eV*hbar, iri, eqv_sph_radius/nm))
|
||||||
|
if (os.path.isfile(destpath) or os.path.isfile(touchpath)) and not rewrite_output:
|
||||||
|
print(destpath, 'already exists, skipping')
|
||||||
|
continue
|
||||||
|
mm_iri = ss.modeproblem_matrix_packed(k, iri)
|
||||||
|
U, S, Vh = np.linalg.svd(mm_iri)
|
||||||
|
del U
|
||||||
|
print(iri, ss.irrep_names[iri], S[-1])
|
||||||
|
starti = max(0,len(S) - np.searchsorted(S[::-1], sv_threshold, side='left')-1)
|
||||||
|
np.savez(destpath,
|
||||||
|
S=S[starti:], omega=omega, Vh = Vh[starti:], iri=iri, Nx = Nx, Ny= Ny )
|
||||||
|
del S
|
||||||
|
del Vh
|
||||||
|
Path(touchpath).touch()
|
||||||
|
# Don't forget to conjugate Vh before transforming it to the full vector!
|
||||||
|
|
|
@ -0,0 +1,547 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--output', action='store', help='Path to output PDF')
|
||||||
|
parser.add_argument('--store_SVD', action='store_true', help='If specified without --SVD_output, it will save the data in a file named as the PDF output, but with .npz extension instead')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--nSV', action='store', metavar='N', type=int, default=1, help='Store and draw N minimun singular values')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--sparse', action='store', type=int, help='Skip frequencies for preview')
|
||||||
|
parser.add_argument('--eVmax', action='store', type=float, help='Skip frequencies above this value')
|
||||||
|
parser.add_argument('--eVmin', action='store', type=float, help='Skip frequencies below this value')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=66, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
|
||||||
|
translations_dir = pargs.griddir
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
pdfout = pargs.output if pargs.output else (''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) + '.pdf')
|
||||||
|
print(pdfout)
|
||||||
|
if(pargs.store_SVD):
|
||||||
|
if re.search('.pdf$', pdfout):
|
||||||
|
svdout = re.sub('.pdf$', r'.npz', pdfout)
|
||||||
|
else:
|
||||||
|
svdout = pdfout + '.npz'
|
||||||
|
else:
|
||||||
|
svdout = None
|
||||||
|
|
||||||
|
|
||||||
|
hexside = pargs.hexside #375e-9
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
minfreq = pargs.eVmin*eV/hbar if pargs.eVmin else None
|
||||||
|
maxfreq = pargs.eVmax*eV/hbar if pargs.eVmax else None
|
||||||
|
skipfreq = pargs.sparse if pargs.sparse else None
|
||||||
|
svn = pargs.nSV
|
||||||
|
|
||||||
|
# TODO multiplier operation definitions and parsing
|
||||||
|
#factor13inc = 10
|
||||||
|
#factor13scat=10
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
#ops = (
|
||||||
|
# # co, typ operace (symetrizace / transformace / kopie), specifikace (operace nebo zdroj),
|
||||||
|
# # co: 0, 1, (0,1), (0,), (1,), #NI: 'all'
|
||||||
|
# # typ operace: sym, tr, copy
|
||||||
|
# # specifikace:
|
||||||
|
# # sym, tr: 'σ_z', 'σ_y', 'C2'; sym: 'C3',
|
||||||
|
# # copy: 0, 1 (zdroj)
|
||||||
|
# ((0,1), 'sym', 'σ_z'),
|
||||||
|
# #((0,1), 'sym', 'σ_x'),
|
||||||
|
# #((0,1), 'sym', 'σ_y'),
|
||||||
|
# ((0,1), 'sym', 'C3'),
|
||||||
|
# ((1), 'tr', 'C2'),
|
||||||
|
#
|
||||||
|
#)
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
import time
|
||||||
|
begtime=time.time()
|
||||||
|
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from matplotlib.backends.backend_pdf import PdfPages
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdf = PdfPages(pdfout)
|
||||||
|
|
||||||
|
# In[3]:
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
ž = np.arange(2*nelem)
|
||||||
|
tž = ž // nelem
|
||||||
|
mž = my[ž%nelem]
|
||||||
|
nž = ny[ž%nelem]
|
||||||
|
TEž = ž[(mž+nž+tž) % 2 == 0]
|
||||||
|
TMž = ž[(mž+nž+tž) % 2 == 1]
|
||||||
|
|
||||||
|
č = np.arange(2*2*nelem)
|
||||||
|
žč = č % (2* nelem)
|
||||||
|
tč = tž[žč]
|
||||||
|
mč = mž[žč]
|
||||||
|
nč = nž[žč]
|
||||||
|
TEč = č[(mč+nč+tč) % 2 == 0]
|
||||||
|
TMč = č[(mč+nč+tč) % 2 == 1]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# In[4]:
|
||||||
|
|
||||||
|
om = np.linspace(np.min(freqs_orig), np.max(freqs_orig),100)
|
||||||
|
TMatrix0ip = np.reshape(TMatrices_interp(om)[:,0], (len(om), 2*nelem*2*nelem))
|
||||||
|
f, axa = plt.subplots(2, 2, figsize=(15,15))
|
||||||
|
|
||||||
|
#print(TMatrices.shape)
|
||||||
|
#plt.plot(om, TMatrices[:,0,0,0,0].imag,'r',om, TMatrices[:,0,0,0,0].real,'r--',om, TMatrices[:,0,2,0,2].imag,'b',om, TMatrices[:,0,2,0,2].real,'b--'))
|
||||||
|
|
||||||
|
ax = axa[0,0]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, TMatrix0ip[:,:].imag,'-',om, TMatrix0ip[:,:].real,'--',
|
||||||
|
)
|
||||||
|
ax = axa[0,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, abs(TMatrix0ip[:,:]),'-'
|
||||||
|
)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
|
||||||
|
ax = axa[1,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, np.unwrap(np.angle(TMatrix0ip[:,:]),axis=0),'-'
|
||||||
|
)
|
||||||
|
|
||||||
|
ax = axa[1,0]
|
||||||
|
ax.text(0.5,0.5,str(pargs).replace(',',',\n'),horizontalalignment='center',verticalalignment='center',transform=ax.transAxes)
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
#kdensity = 66 #defined from cl arguments
|
||||||
|
bz_0 = np.array((0,0,0.,))
|
||||||
|
bz_K1 = np.array((1.,0,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4,0))*4*np.pi/3/hexside/s3
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(klist, axis=0), axis=-1))))
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
n2id = np.identity(2*nelem)
|
||||||
|
n2id.shape = (2,nelem,2,nelem)
|
||||||
|
extlistlist = list()
|
||||||
|
leftmatrixlistlist = list()
|
||||||
|
minsvTElistlist=list()
|
||||||
|
minsvTMlistlist=list()
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistlist = list()
|
||||||
|
svVfullTElistlist = list()
|
||||||
|
svSfullTElistlist = list()
|
||||||
|
svUfullTMlistlist = list()
|
||||||
|
svVfullTMlistlist = list()
|
||||||
|
svSfullTMlistlist = list()
|
||||||
|
|
||||||
|
nan = float('nan')
|
||||||
|
omegalist = list()
|
||||||
|
filecount = 0
|
||||||
|
for trfile in os.scandir(translations_dir):
|
||||||
|
filecount += 1
|
||||||
|
if (skipfreq and filecount % skipfreq):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
npz = np.load(trfile.path, mmap_mode='r')
|
||||||
|
k_0 = npz['precalc_params'][()]['k_hexside'] / hexside
|
||||||
|
omega = k_0 * c / math.sqrt(epsilon_b)
|
||||||
|
if((minfreq and omega < minfreq) or (maxfreq and omega > maxfreq)):
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
print ("Unexpected error, trying to continue with another file:", sys.exc_info()[0])
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
tdic = qpms.hexlattice_precalc_AB_loadunwrap(trfile.path, return_points=True)
|
||||||
|
except:
|
||||||
|
print ("Unexpected error, trying to continue with another file:", sys.exc_info()[0])
|
||||||
|
continue
|
||||||
|
k_0 = tdic['k_hexside'] / hexside
|
||||||
|
omega = k_0 * c / math.sqrt(epsilon_b)
|
||||||
|
omegalist.append(omega)
|
||||||
|
print(filecount, omega/eV*hbar)
|
||||||
|
sys.stdout.flush()
|
||||||
|
a_self = tdic['a_self'][:,:nelem,:nelem]
|
||||||
|
b_self = tdic['b_self'][:,:nelem,:nelem]
|
||||||
|
a_u2d = tdic['a_u2d'][:,:nelem,:nelem]
|
||||||
|
b_u2d = tdic['b_u2d'][:,:nelem,:nelem]
|
||||||
|
a_d2u = tdic['a_d2u'][:,:nelem,:nelem]
|
||||||
|
b_d2u = tdic['b_d2u'][:,:nelem,:nelem]
|
||||||
|
unitcell_translations = tdic['self_tr']*hexside*s3
|
||||||
|
u2d_translations = tdic['u2d_tr']*hexside*s3
|
||||||
|
d2u_translations = tdic['d2u_tr']*hexside*s3
|
||||||
|
if gaussianSigma:
|
||||||
|
unitcell_envelope = np.exp(-np.sum(tdic['self_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
u2d_envelope = np.exp(-np.sum(tdic['u2d_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
d2u_envelope = np.exp(-np.sum(tdic['d2u_tr']**2,axis=-1)/(2*gaussianSigma**2))
|
||||||
|
|
||||||
|
|
||||||
|
TMatrices_om = TMatrices_interp(omega)
|
||||||
|
if svdout:
|
||||||
|
svUfullTElist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svVfullTElist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svSfullTElist = np.full((klist.shape[0], 2*nelem), np.nan, dtype=complex)
|
||||||
|
svUfullTMlist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svVfullTMlist = np.full((klist.shape[0], 2*nelem, 2*nelem), np.nan, dtype=complex)
|
||||||
|
svSfullTMlist = np.full((klist.shape[0], 2*nelem), np.nan, dtype=complex)
|
||||||
|
|
||||||
|
|
||||||
|
minsvTElist = np.full((klist.shape[0], svn),np.nan)
|
||||||
|
minsvTMlist = np.full((klist.shape[0], svn),np.nan)
|
||||||
|
leftmatrixlist = np.full((klist.shape[0],2,2,nelem,2,2,nelem),np.nan,dtype=complex)
|
||||||
|
isNaNlist = np.zeros((klist.shape[0]), dtype=bool)
|
||||||
|
|
||||||
|
# sem nějaká rozumná smyčka
|
||||||
|
for ki in range(klist.shape[0]):
|
||||||
|
k = klist[ki]
|
||||||
|
if (k_0*k_0 - k[0]*k[0] - k[1]*k[1] < 0):
|
||||||
|
isNaNlist[ki] = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
phases_self = np.exp(1j*np.tensordot(k,unitcell_translations,axes=(0,-1)))
|
||||||
|
phases_u2d = np.exp(1j*np.tensordot(k,u2d_translations,axes=(0,-1)))
|
||||||
|
phases_d2u = np.exp(1j*np.tensordot(k,d2u_translations,axes=(0,-1)))
|
||||||
|
if gaussianSigma:
|
||||||
|
phases_self *= unitcell_envelope
|
||||||
|
phases_u2d *= u2d_envelope
|
||||||
|
phases_d2u *= d2u_envelope
|
||||||
|
leftmatrix = np.zeros((2,2,nelem, 2,2,nelem), dtype=complex)
|
||||||
|
|
||||||
|
leftmatrix[0,0,:,0,0,:] = np.tensordot(a_self,phases_self, axes=(0,-1)) # u2u, E2E
|
||||||
|
leftmatrix[1,0,:,1,0,:] = leftmatrix[0,0,:,0,0,:] # d2d, E2E
|
||||||
|
leftmatrix[0,1,:,0,1,:] = leftmatrix[0,0,:,0,0,:] # u2u, M2M
|
||||||
|
leftmatrix[1,1,:,1,1,:] = leftmatrix[0,0,:,0,0,:] # d2d, M2M
|
||||||
|
leftmatrix[0,0,:,0,1,:] = np.tensordot(b_self,phases_self, axes=(0,-1)) # u2u, M2E
|
||||||
|
leftmatrix[0,1,:,0,0,:] = leftmatrix[0,0,:,0,1,:] # u2u, E2M
|
||||||
|
leftmatrix[1,1,:,1,0,:] = leftmatrix[0,0,:,0,1,:] # d2d, E2M
|
||||||
|
leftmatrix[1,0,:,1,1,:] = leftmatrix[0,0,:,0,1,:] # d2d, M2E
|
||||||
|
leftmatrix[0,0,:,1,0,:] = np.tensordot(a_d2u, phases_d2u,axes=(0,-1)) #d2u,E2E
|
||||||
|
leftmatrix[0,1,:,1,1,:] = leftmatrix[0,0,:,1,0,:] #d2u, M2M
|
||||||
|
leftmatrix[1,0,:,0,0,:] = np.tensordot(a_u2d, phases_u2d,axes=(0,-1)) #u2d,E2E
|
||||||
|
leftmatrix[1,1,:,0,1,:] = leftmatrix[1,0,:,0,0,:] #u2d, M2M
|
||||||
|
leftmatrix[0,0,:,1,1,:] = np.tensordot(b_d2u, phases_d2u,axes=(0,-1)) #d2u,M2E
|
||||||
|
leftmatrix[0,1,:,1,0,:] = leftmatrix[0,0,:,1,1,:] #d2u, E2M
|
||||||
|
leftmatrix[1,0,:,0,1,:] = np.tensordot(b_u2d, phases_u2d,axes=(0,-1)) #u2d,M2E
|
||||||
|
leftmatrix[1,1,:,0,0,:] = leftmatrix[1,0,:,0,1,:] #u2d, E2M
|
||||||
|
#leftmatrix is now the translation matrix T
|
||||||
|
for j in range(2):
|
||||||
|
leftmatrix[j] = -np.tensordot(TMatrices_om[j], leftmatrix[j], axes=([-2,-1],[0,1]))
|
||||||
|
# at this point, jth row of leftmatrix is that of -MT
|
||||||
|
leftmatrix[j,:,:,j,:,:] += n2id
|
||||||
|
#now we are done, 1-MT
|
||||||
|
|
||||||
|
leftmatrixlist[ki] = leftmatrix
|
||||||
|
|
||||||
|
|
||||||
|
nnlist = np.logical_not(isNaNlist)
|
||||||
|
leftmatrixlist_s = np.reshape(leftmatrixlist,(klist.shape[0], 2*2*nelem,2*2*nelem))[nnlist]
|
||||||
|
leftmatrixlist_TE = leftmatrixlist_s[np.ix_(np.arange(leftmatrixlist_s.shape[0]),TEč,TEč)]
|
||||||
|
leftmatrixlist_TM = leftmatrixlist_s[np.ix_(np.arange(leftmatrixlist_s.shape[0]),TMč,TMč)]
|
||||||
|
#svarr = np.linalg.svd(leftmatrixlist_TE, compute_uv=False)
|
||||||
|
#argsortlist = np.argsort(svarr, axis=-1)[...,:svn]
|
||||||
|
#minsvTElist[nnlist] = svarr[...,argsortlist]
|
||||||
|
#minsvTElist[nnlist] = np.amin(np.linalg.svd(leftmatrixlist_TE, compute_uv=False), axis=-1)
|
||||||
|
if svdout:
|
||||||
|
svUfullTElist[nnlist], svSfullTElist[nnlist], svVfullTElist[nnlist] = np.linalg.svd(leftmatrixlist_TE, compute_uv=True)
|
||||||
|
svUfullTMlist[nnlist], svSfullTMlist[nnlist], svVfullTMlist[nnlist] = np.linalg.svd(leftmatrixlist_TM, compute_uv=True)
|
||||||
|
svUfullTElistlist.append(svUfullTElist)
|
||||||
|
svVfullTElistlist.append(svVfullTElist)
|
||||||
|
svSfullTElistlist.append(svSfullTElist)
|
||||||
|
svUfullTMlistlist.append(svUfullTMlist)
|
||||||
|
svVfullTMlistlist.append(svVfullTMlist)
|
||||||
|
svSfullTMlistlist.append(svSfullTMlist)
|
||||||
|
minsvTElist[nnlist] = np.linalg.svd(leftmatrixlist_TE, compute_uv=False)[...,-svn:]
|
||||||
|
#svarr = np.linalg.svd(leftmatrixlist_TM, compute_uv=False)
|
||||||
|
#argsortlist = np.argsort(svarr, axis=-1)[...,:svn]
|
||||||
|
#minsvTMlist[nnlist] = svarr[...,argsortlist]
|
||||||
|
#minsvTMlist[nnlist] = np.amin(np.linalg.svd(leftmatrixlist_TM, compute_uv=False), axis=-1)
|
||||||
|
minsvTMlist[nnlist] = np.linalg.svd(leftmatrixlist_TM, compute_uv=False)[...,-svn:]
|
||||||
|
minsvTMlistlist.append(minsvTMlist)
|
||||||
|
minsvTElistlist.append(minsvTElist)
|
||||||
|
|
||||||
|
minsvTElistarr = np.array(minsvTElistlist)
|
||||||
|
minsvTMlistarr = np.array(minsvTMlistlist)
|
||||||
|
del minsvTElistlist, minsvTMlistlist
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistarr = np.array(svUfullTElistlist)
|
||||||
|
svVfullTElistarr = np.array(svVfullTElistlist)
|
||||||
|
svSfullTElistarr = np.array(svSfullTElistlist)
|
||||||
|
del svUfullTElistlist, svVfullTElistlist, svSfullTElistlist
|
||||||
|
svUfullTMlistarr = np.array(svUfullTMlistlist)
|
||||||
|
svVfullTMlistarr = np.array(svVfullTMlistlist)
|
||||||
|
svSfullTMlistarr = np.array(svSfullTMlistlist)
|
||||||
|
del svUfullTMlistlist, svVfullTMlistlist, svSfullTMlistlist
|
||||||
|
omegalist = np.array(omegalist)
|
||||||
|
# order to make the scatter plots "nice"
|
||||||
|
omegaorder = np.argsort(omegalist)
|
||||||
|
omegalist = omegalist[omegaorder]
|
||||||
|
minsvTElistarr = minsvTElistarr[omegaorder]
|
||||||
|
minsvTMlistarr = minsvTMlistarr[omegaorder]
|
||||||
|
if svdout:
|
||||||
|
svUfullTElistarr = svUfullTElistarr[omegaorder]
|
||||||
|
svVfullTElistarr = svVfullTElistarr[omegaorder]
|
||||||
|
svSfullTElistarr = svSfullTElistarr[omegaorder]
|
||||||
|
svUfullTMlistarr = svUfullTMlistarr[omegaorder]
|
||||||
|
svVfullTMlistarr = svVfullTMlistarr[omegaorder]
|
||||||
|
svSfullTMlistarr = svSfullTMlistarr[omegaorder]
|
||||||
|
np.savez(svdout, omega = omegalist, klist = klist, bzpoints = np.array([bz_0, bz_K1, bz_K2, bz_M, B1, B2]),
|
||||||
|
uTE = svUfullTElistarr,
|
||||||
|
vTE = svVfullTElistarr,
|
||||||
|
sTE = svSfullTElistarr,
|
||||||
|
uTM = svUfullTMlistarr,
|
||||||
|
vTM = svVfullTMlistarr,
|
||||||
|
sTM = svSfullTMlistarr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
omlist = np.broadcast_to(omegalist[:,nx], minsvTElistarr[...,0].shape)
|
||||||
|
kxmlarr = np.broadcast_to(kxmaplist[nx,:], minsvTElistarr[...,0].shape)
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
for minN in reversed(range(svn)):
|
||||||
|
f, ax = plt.subplots(1, figsize=(20,15))
|
||||||
|
sc = ax.scatter(kxmlarr, omlist/eV*hbar, c = np.sqrt(minsvTMlistarr[...,minN]), s =40, lw=0)
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(klist,axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B2-B1, axis=-1)*cdn, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B1-B2, axis=-1)*cdn, '-',
|
||||||
|
)
|
||||||
|
ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([2.15,2.30])
|
||||||
|
ax.set_ylim([np.min(omlist/eV*hbar),np.max(omlist/eV*hbar)])
|
||||||
|
ax.set_xticks([0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]])
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
f.colorbar(sc)
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
f, ax = plt.subplots(1, figsize=(20,15))
|
||||||
|
sc = ax.scatter(kxmlarr, omlist/eV*hbar, c = np.sqrt(minsvTElistarr[...,minN]), s =40, lw=0)
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(klist,axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist+B2+B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B2-B1, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
kxmaplist, np.linalg.norm(klist-2*B1-2*B2, axis=-1)*cdn/eV*hbar, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B2-B1, axis=-1)*cdn, '-',
|
||||||
|
# kxmaplist, np.linalg.norm(klist+2*B1-B2, axis=-1)*cdn, '-',
|
||||||
|
)
|
||||||
|
ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([2.15,2.30])
|
||||||
|
ax.set_ylim([np.min(omlist/eV*hbar),np.max(omlist/eV*hbar)])
|
||||||
|
ax.set_xticks([0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]])
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
f.colorbar(sc)
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
pdf.close()
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
subprocess.run(['scp', pdfout, scp_dest])
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,403 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the pdf and/or npz output (will be appended frequency and hexside)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--output', action='store', help='Path to output PDF')
|
||||||
|
parser.add_argument('--store_SVD', action='store_false', help='If specified without --SVD_output, it will save the data in a file named as the PDF output, but with .npz extension instead')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--nSV', action='store', metavar='N', type=int, default=1, help='Store and draw N minimun singular values')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
pdfout = pargs.output if pargs.output else (
|
||||||
|
'%s_%dnm_%.4f.pdf' % (pargs.output_prefix,hexside/1e-9,eVfreq) if pargs.output_prefix else
|
||||||
|
(''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) + '.pdf'))
|
||||||
|
print(pdfout)
|
||||||
|
if(pargs.store_SVD):
|
||||||
|
if re.search('.pdf$', pdfout):
|
||||||
|
svdout = re.sub('.pdf$', r'.npz', pdfout)
|
||||||
|
else:
|
||||||
|
svdout = pdfout + '.npz'
|
||||||
|
else:
|
||||||
|
svdout = None
|
||||||
|
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
svn = pargs.nSV
|
||||||
|
|
||||||
|
# TODO multiplier operation definitions and parsing
|
||||||
|
#factor13inc = 10
|
||||||
|
#factor13scat=10
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
#ops = (
|
||||||
|
# # co, typ operace (symetrizace / transformace / kopie), specifikace (operace nebo zdroj),
|
||||||
|
# # co: 0, 1, (0,1), (0,), (1,), #NI: 'all'
|
||||||
|
# # typ operace: sym, tr, copy
|
||||||
|
# # specifikace:
|
||||||
|
# # sym, tr: 'σ_z', 'σ_y', 'C2'; sym: 'C3',
|
||||||
|
# # copy: 0, 1 (zdroj)
|
||||||
|
# ((0,1), 'sym', 'σ_z'),
|
||||||
|
# #((0,1), 'sym', 'σ_x'),
|
||||||
|
# #((0,1), 'sym', 'σ_y'),
|
||||||
|
# ((0,1), 'sym', 'C3'),
|
||||||
|
# ((1), 'tr', 'C2'),
|
||||||
|
#
|
||||||
|
#)
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
import time
|
||||||
|
begtime=time.time()
|
||||||
|
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from matplotlib.backends.backend_pdf import PdfPages
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdf = PdfPages(pdfout)
|
||||||
|
|
||||||
|
# In[3]:
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# In[4]:
|
||||||
|
if(pargs.plot_TMatrix):
|
||||||
|
om = np.linspace(np.min(freqs_orig), np.max(freqs_orig),100)
|
||||||
|
TMatrix0ip = np.reshape(TMatrices_interp(om)[:,0], (len(om), 2*nelem*2*nelem))
|
||||||
|
f, axa = plt.subplots(2, 2, figsize=(15,15))
|
||||||
|
|
||||||
|
#print(TMatrices.shape)
|
||||||
|
#plt.plot(om, TMatrices[:,0,0,0,0].imag,'r',om, TMatrices[:,0,0,0,0].real,'r--',om, TMatrices[:,0,2,0,2].imag,'b',om, TMatrices[:,0,2,0,2].real,'b--'))
|
||||||
|
|
||||||
|
ax = axa[0,0]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, TMatrix0ip[:,:].imag,'-',om, TMatrix0ip[:,:].real,'--',
|
||||||
|
)
|
||||||
|
ax = axa[0,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, abs(TMatrix0ip[:,:]),'-'
|
||||||
|
)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
|
||||||
|
ax = axa[1,1]
|
||||||
|
ax2 = ax.twiny()
|
||||||
|
ax2.set_xlim([ax.get_xlim()[0]/eV*hbar,ax.get_xlim()[1]/eV*hbar])
|
||||||
|
ax.plot(
|
||||||
|
om, np.unwrap(np.angle(TMatrix0ip[:,:]),axis=0),'-'
|
||||||
|
)
|
||||||
|
|
||||||
|
ax = axa[1,0]
|
||||||
|
ax.text(0.5,0.5,str(pargs).replace(',',',\n'),horizontalalignment='center',verticalalignment='center',transform=ax.transAxes)
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
'''
|
||||||
|
#kdensity = 66 #defined from cl arguments
|
||||||
|
bz_0 = np.array((0,0,0.,))
|
||||||
|
bz_K1 = np.array((1.,0,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4,0))*4*np.pi/3/hexside/s3
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,kdensity)[:,nx]
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
klist = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(klist, axis=0), axis=-1))))
|
||||||
|
'''
|
||||||
|
klist = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=(0 if svdout else svn))
|
||||||
|
if svdout:
|
||||||
|
((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
(minsvElist, minsvTMlist) = (svSfullTElist[...,-svn:], svSfullTMlist[...,-svn:])
|
||||||
|
else:
|
||||||
|
minsvTElist, minsvTMlist = svdres
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' The new pretty diffracted order drawing '''
|
||||||
|
maxlayer_reciprocal=4
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
bz_0 = np.array((0,0,))
|
||||||
|
bz_K1 = np.array((1.,0))*4*np.pi/3/hexside/s3
|
||||||
|
bz_K2 = np.array((1./2.,s3/2))*4*np.pi/3/hexside/s3
|
||||||
|
bz_M = np.array((3./4, s3/4))*4*np.pi/3/hexside/s3
|
||||||
|
|
||||||
|
# reciprocal lattice basis
|
||||||
|
B1 = 2* bz_K1 - bz_K2
|
||||||
|
B2 = 2* bz_K2 - bz_K1
|
||||||
|
|
||||||
|
if svdout:
|
||||||
|
np.savez(svdout, omega = freq, klist = klist, bzpoints = np.array([bz_0, bz_K1, bz_K2, bz_M, B1, B2]),
|
||||||
|
uTE = svUfullTElist,
|
||||||
|
vTE = svVfullTElist,
|
||||||
|
sTE = svSfullTElist,
|
||||||
|
uTM = svUfullTMlist,
|
||||||
|
vTM = svVfullTMlist,
|
||||||
|
sTM = svSfullTMlist,
|
||||||
|
)
|
||||||
|
|
||||||
|
k2density = 100
|
||||||
|
k0Mlist = bz_0 + (bz_M-bz_0) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kMK1list = bz_M + (bz_K1-bz_M) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kK10list = bz_K1 + (bz_0-bz_K1) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
k0K2list = bz_0 + (bz_K2-bz_0) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
kK2Mlist = bz_K2 + (bz_M-bz_K2) * np.linspace(0,1,k2density)[:,nx]
|
||||||
|
k2list = np.concatenate((k0Mlist,kMK1list,kK10list,k0K2list,kK2Mlist), axis=0)
|
||||||
|
kxmaplist = np.concatenate((np.array([0]),np.cumsum(np.linalg.norm(np.diff(k2list, axis=0), axis=-1))))
|
||||||
|
|
||||||
|
centers2=qpms.generate_trianglepoints(maxlayer_reciprocal, v3d = False, include_origin= True)*4*np.pi/3/hexside
|
||||||
|
rot90 = np.array([[0,-1],[1,0]])
|
||||||
|
centers2=np.dot(centers2,rot90)
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib
|
||||||
|
from matplotlib.path import Path
|
||||||
|
import matplotlib.patches as patches
|
||||||
|
cmap = matplotlib.cm.prism
|
||||||
|
colormax = np.amax(np.linalg.norm(centers2,axis=0))
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
for minN in reversed(range(svn)):
|
||||||
|
f, axes = plt.subplots(1,3, figsize=(20,4.8))
|
||||||
|
ax = axes[0]
|
||||||
|
sc = ax.scatter(klist[:,0], klist[:,1], c = np.clip(np.abs(minsvTElist[:,minN]),0,1), lw=0)
|
||||||
|
for center in centers2:
|
||||||
|
circle=plt.Circle((center[0],center[1]),omega/cdn, facecolor='none', edgecolor=cmap(np.linalg.norm(center)/colormax),lw=0.5)
|
||||||
|
ax.add_artist(circle)
|
||||||
|
verts = [(math.cos(math.pi*i/3)*4*np.pi/3/hexside/s3,math.sin(math.pi*i/3)*4*np.pi/3/hexside/s3) for i in range(6 +1)]
|
||||||
|
codes = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.CLOSEPOLY,]
|
||||||
|
path = Path(verts, codes)
|
||||||
|
patch = patches.PathPatch(path, facecolor='none', edgecolor='black', lw=1)
|
||||||
|
ax.add_patch(patch)
|
||||||
|
ax.set_xticks([])
|
||||||
|
ax.set_yticks([])
|
||||||
|
ax.title.set_text('E in-plane ("TE")')
|
||||||
|
f.colorbar(sc,ax=ax)
|
||||||
|
|
||||||
|
|
||||||
|
ax = axes[1]
|
||||||
|
sc = ax.scatter(klist[:,0], klist[:,1], c = np.clip(np.abs(minsvTMlist[:,minN]),0,1), lw=0)
|
||||||
|
for center in centers2:
|
||||||
|
circle=plt.Circle((center[0],center[1]),omega/cdn, facecolor='none', edgecolor=cmap(np.linalg.norm(center)/colormax),lw=0.5)
|
||||||
|
ax.add_artist(circle)
|
||||||
|
verts = [(math.cos(math.pi*i/3)*4*np.pi/3/hexside/s3,math.sin(math.pi*i/3)*4*np.pi/3/hexside/s3) for i in range(6 +1)]
|
||||||
|
codes = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.CLOSEPOLY,]
|
||||||
|
path = Path(verts, codes)
|
||||||
|
patch = patches.PathPatch(path, facecolor='none', edgecolor='black', lw=1)
|
||||||
|
ax.add_patch(patch)
|
||||||
|
ax.set_xticks([])
|
||||||
|
ax.set_yticks([])
|
||||||
|
ax.title.set_text('E perpendicular ("TM")')
|
||||||
|
f.colorbar(sc,ax=ax)
|
||||||
|
|
||||||
|
ax = axes[2]
|
||||||
|
for center in centers2:
|
||||||
|
ax.plot(kxmaplist, np.linalg.norm(k2list-center,axis=-1)*cdn, '-', color=cmap(np.linalg.norm(center)/colormax))
|
||||||
|
|
||||||
|
#ax.set_xlim([np.min(kxmlarr),np.max(kxmlarr)])
|
||||||
|
#ax.set_ylim([np.min(omegalist),np.max(omegalist)])
|
||||||
|
xticklist = [0, kxmaplist[len(k0Mlist)-1], kxmaplist[len(k0Mlist)+len(kMK1list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)-1], kxmaplist[len(k0Mlist)+len(kMK1list)+len(kK10list)+len(k0K2list)+len(kK2Mlist)-1]]
|
||||||
|
ax.set_xticks(xticklist)
|
||||||
|
for xt in xticklist:
|
||||||
|
ax.axvline(xt, ls='dotted', lw=0.3,c='k')
|
||||||
|
ax.set_xticklabels(['Γ', 'M', 'K', 'Γ', 'K\'','M'])
|
||||||
|
ax.axhline(omega, c='black')
|
||||||
|
ax.set_ylim([0,5e15])
|
||||||
|
ax2 = ax.twinx()
|
||||||
|
ax2.set_ylim([ax.get_ylim()[0]/eV*hbar,ax.get_ylim()[1]/eV*hbar])
|
||||||
|
|
||||||
|
pdf.savefig(f)
|
||||||
|
|
||||||
|
pdf.close()
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
subprocess.run(['scp', pdfout, scp_dest])
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,239 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=1000, help='Number of k-points per output file (default 1000)')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--tr0', dest='ops', action=make_action_sharedlist('tr0', 'ops'))
|
||||||
|
popgrp.add_argument('--tr1', dest='ops', action=make_action_sharedlist('tr1', 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
popgrp.add_argument('--sym0', dest='ops', action=make_action_sharedlist('sym0', 'ops'))
|
||||||
|
popgrp.add_argument('--sym1', dest='ops', action=make_action_sharedlist('sym1', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
popgrp.add_argument('--multl0', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl0', 'ops'))
|
||||||
|
popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else (0,1), opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
print(ops)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
klist_full = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.shape[0] / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points in %d chunks' % (klist_full.shape[0], chunkn), file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'lMax' : lMax,
|
||||||
|
'maxlayer' : maxlayer,
|
||||||
|
'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
})
|
||||||
|
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
svdout = '%s_%dnm_%.4f_c%03d.npz' % (pargs.output_prefix, hexside/1e-9, eVfreq, chunki)
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=False, verbose=verbose)
|
||||||
|
|
||||||
|
#((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
|
||||||
|
np.savez(svdout, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
uTE = svdres[0][0],
|
||||||
|
vTE = svdres[0][2],
|
||||||
|
sTE = svdres[0][1],
|
||||||
|
uTM = svdres[1][0],
|
||||||
|
vTM = svdres[1][2],
|
||||||
|
sTM = svdres[1][1],
|
||||||
|
|
||||||
|
)
|
||||||
|
svdres=None
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
||||||
|
#print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -1,719 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import qpms\n",
|
|
||||||
"import warnings\n",
|
|
||||||
"from qpms.cybspec import BaseSpec\n",
|
|
||||||
"from qpms.cytmatrices import CTMatrix, TMatrixGenerator, TMatrixInterpolator\n",
|
|
||||||
"from qpms.qpms_c import Particle, pgsl_ignore_error\n",
|
|
||||||
"from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude\n",
|
|
||||||
"from qpms.cycommon import DebugFlags, dbgmsg_enable\n",
|
|
||||||
"from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar\n",
|
|
||||||
"import scipy.constants as sci\n",
|
|
||||||
"eh = eV/hbar"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#TODO\n",
|
|
||||||
"period = 520e-9\n",
|
|
||||||
"a1 = np.array([0,period]) \n",
|
|
||||||
"a2 = np.array([period,0])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Particle positions\n",
|
|
||||||
"orig_x = [0]\n",
|
|
||||||
"orig_y = [0]\n",
|
|
||||||
"orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"period = 0.52\n",
|
|
||||||
"refractive_index = 1.52 # for background medium\n",
|
|
||||||
"height = 50e-9 # Particle height\n",
|
|
||||||
"radius = 50e-9 # Particle radius\n",
|
|
||||||
"medium = EpsMu(refractive_index**2) # non-lossy background medium with constant refr. index #OK\n",
|
|
||||||
"# global symmetry group of the system\n",
|
|
||||||
"#sym = FinitePointGroup(point_group_info['D4h'])\n",
|
|
||||||
"omega = 1.58*eh\n",
|
|
||||||
"metal = lorentz_drude['Ag']\n",
|
|
||||||
"kx_lim = np.array([-0.2, 0.2], dtype=float)\n",
|
|
||||||
"N=501"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(7.59633723939313, 8.305328715069821, 7.94387469344152, 8.001475225494097)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"omega_scuff_min=1.5*eh/3e14\n",
|
|
||||||
"omega_scuff_max=1.64*eh/3e14\n",
|
|
||||||
"omega_scuff=omega/3e14\n",
|
|
||||||
"omega_scuff_slr=(2*np.pi*sci.c/(1.52*0.52e-6))/3e14\n",
|
|
||||||
"omega_scuff_min, omega_scuff_max, omega_scuff_slr, omega_scuff"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"bspec = BaseSpec(lMax = 1)\n",
|
|
||||||
"\n",
|
|
||||||
"tmfile_scuffOld = '/home/javier/tmatrices/sphereAg_50nm_oldScuff.TMatrix'\n",
|
|
||||||
"tmfile_scuffNew = '/home/javier/tmatrices/sphere50nm_newScuff.TMatrix'\n",
|
|
||||||
"interp_old = TMatrixInterpolator(tmfile_scuffOld, bspec, atol=1e-8) \n",
|
|
||||||
"interp_new = TMatrixInterpolator(tmfile_scuffNew, bspec, atol=1e-8) \n",
|
|
||||||
"tmscuff_not_fixed = interp_old(omega)\n",
|
|
||||||
"tmscuff_bugfixed = interp_new(omega)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 7,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"tmgen = TMatrixGenerator.sphere(medium, metal, radius)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 8,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"tmgen_omega=tmgen(bspec,omega)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 9,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , -0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , -0.07824951+0.25215549j, 0. +0.j , 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j, 0. +0.j , 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j, 0. +0.j ],\n",
|
|
||||||
" [ 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , 0. +0.j , -0.00083788-0.01420874j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 9,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmgen_omega.as_ndarray() # T-Matrix from generator"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-4.70886671e-03+1.79440815e-02j, 1.60098226e-13+4.20092462e-13j, 2.26455777e-07+3.98932962e-07j, -2.13258227e-14-6.01930824e-14j, 7.66251504e-08-1.32539814e-08j,\n",
|
|
||||||
" -7.76488937e-14+1.08532726e-13j],\n",
|
|
||||||
" [-4.41531068e-13+9.81757019e-14j, -4.70582367e-03+1.79389513e-02j, -1.60702588e-13-4.19762769e-13j, 6.32372612e-08+4.71302619e-08j, -2.36039655e-14+1.00983241e-13j,\n",
|
|
||||||
" 7.76590838e-08-1.38092126e-08j],\n",
|
|
||||||
" [-4.58579591e-07-7.49053314e-09j, 4.41175187e-13-9.87457125e-14j, -4.70886672e-03+1.79440815e-02j, 2.13790755e-14+1.31812722e-13j, 6.25535562e-08+4.61875295e-08j,\n",
|
|
||||||
" 4.59276044e-14-4.47400043e-14j],\n",
|
|
||||||
" [ 4.93366461e-14-4.29235249e-14j, -6.94450011e-09-1.60278760e-08j, -7.79609985e-14+1.07845028e-13j, -3.03166095e-05-2.01474828e-03j, -2.39253108e-13-1.34944425e-13j,\n",
|
|
||||||
" 1.16328171e-08+6.36863105e-09j],\n",
|
|
||||||
" [ 8.21008790e-09-1.53591010e-08j, -2.36580203e-14+1.00878213e-13j, -5.41800099e-09-1.65573897e-08j, 2.26431323e-13-1.55248143e-13j, -3.03231670e-05-2.01493037e-03j,\n",
|
|
||||||
" 2.38800352e-13+1.35401679e-13j],\n",
|
|
||||||
" [ 2.18731933e-14+1.31428484e-13j, 7.13657440e-09-1.65412452e-08j, -2.48667583e-14-6.12974376e-14j, -1.11447700e-08+7.19733229e-09j, -2.26916383e-13+1.54810715e-13j,\n",
|
|
||||||
" -3.03166170e-05-2.01474828e-03j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmscuff_not_fixed.as_ndarray() # T-Matrix of not fixed version of Scuff-EM"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"array([[-9.43033280e-02+3.59361755e-01j, 3.20658236e-12+8.41416904e-12j, 5.13892659e-06+8.57797510e-06j, -4.28949536e-13-1.20456867e-12j, 1.41239218e-06-2.46862181e-07j,\n",
|
|
||||||
" -1.55480479e-12+2.17400571e-12j],\n",
|
|
||||||
" [-8.84386127e-12+1.96169624e-12j, -9.42395846e-02+3.59248336e-01j, -3.22166474e-12-8.40342496e-12j, 1.16868119e-06+8.68484583e-07j, -4.72874254e-13+2.02296639e-12j,\n",
|
|
||||||
" 1.43308826e-06-2.58864855e-07j],\n",
|
|
||||||
" [-9.99885677e-06+6.63229466e-08j, 8.83605486e-12-1.97841571e-12j, -9.43033282e-02+3.59361755e-01j, 4.27888728e-13+2.63976219e-12j, 1.15544356e-06+8.48824647e-07j,\n",
|
|
||||||
" 9.21093604e-13-8.94225073e-13j],\n",
|
|
||||||
" [ 9.85267406e-13-8.59818272e-13j, -1.43866720e-06+2.57952214e-07j, -1.56233879e-12+2.15974773e-12j, -6.07143255e-04-4.03488631e-02j, -4.79139425e-12-2.70322093e-12j,\n",
|
|
||||||
" 1.52945653e-07+8.36194839e-08j],\n",
|
|
||||||
" [-1.15196465e-06-8.46913318e-07j, -4.73514628e-13+2.02574744e-12j, -1.40806670e-06+2.47097086e-07j, 4.53481568e-12-3.10854698e-12j, -6.07256494e-04-4.03513114e-02j,\n",
|
|
||||||
" 4.78231690e-12+2.71099900e-12j],\n",
|
|
||||||
" [ 4.39050064e-13+2.63269196e-12j, -1.17350730e-06-8.70822943e-07j, -4.95069921e-13-1.22744130e-12j, -1.44529174e-07+9.78280211e-08j, -4.54412580e-12+3.10101417e-12j,\n",
|
|
||||||
" -6.07143303e-04-4.03488631e-02j]])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tmscuff_bugfixed.as_ndarray() # T-Matrix of FIXED version of Scuff-EM"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(matrix([[-9.43033280e-02+3.59361755e-01j, 3.20658236e-12+8.41416904e-12j],\n",
|
|
||||||
" [-8.84386127e-12+1.96169624e-12j, -9.42395846e-02+3.59248336e-01j]]),\n",
|
|
||||||
" matrix([[-9.43033280e-02-3.59361755e-01j, -8.84386127e-12-1.96169624e-12j],\n",
|
|
||||||
" [ 3.20658236e-12-8.41416904e-12j, -9.42395846e-02-3.59248336e-01j]]))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#I play around with the different operations so everything is correct\n",
|
|
||||||
"tmscuffnew = tmscuff_bugfixed.as_ndarray()\n",
|
|
||||||
"tmscuffnew_mat = np.asmatrix(tmscuffnew)\n",
|
|
||||||
"tmscuffnew_dag = tmscuffnew_mat.getH()\n",
|
|
||||||
"tmscuffnew_mat[0:2,0:2], tmscuffnew_dag[0:2,0:2]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 13,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(matrix([[1, 0],\n",
|
|
||||||
" [9, 4]]), matrix([[4, 9],\n",
|
|
||||||
" [0, 1]]))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 13,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"A = np.matrix([[0,1],[2,3]])\n",
|
|
||||||
"B = np.matrix([[3,2],[1,0]])\n",
|
|
||||||
"AB = np.dot(A,B)\n",
|
|
||||||
"BA = np.dot(B,A)\n",
|
|
||||||
"AB,BA"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 14,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"sum1new = np.dot(tmscuffnew_dag,tmscuffnew) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2new = 0.5*tmscuffnew.__add__(tmscuffnew_dag) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 15,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew = sum1new.__add__(sum2new) #powermatrix for bugfixed scuff"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 16,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix for NOT bugfixed scuff\n",
|
|
||||||
"tmscuffold = tmscuff_not_fixed.as_ndarray()\n",
|
|
||||||
"tmscuffold_mat = np.asmatrix(tmscuffold)\n",
|
|
||||||
"tmscuffold_dag = tmscuffold_mat.getH()\n",
|
|
||||||
"sum1old = np.dot(tmscuffold_dag,tmscuffold) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2old = 0.5*tmscuffold.__add__(tmscuffold_dag)\n",
|
|
||||||
"\n",
|
|
||||||
"powermatrix_scuffold = sum1old.__add__(sum2old) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 17,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix for T matrix generator\n",
|
|
||||||
"tmscuffgen = tmgen_omega.as_ndarray()\n",
|
|
||||||
"tmscuffgen_mat = np.asmatrix(tmscuffgen)\n",
|
|
||||||
"tmscuffgen_dag = tmscuffgen_mat.getH()\n",
|
|
||||||
"sum1gen = np.dot(tmscuffgen_dag,tmscuffgen) #is this the right order? Regarding the above, yes it is.\n",
|
|
||||||
"sum2gen = 0.5*tmscuffgen.__add__(tmscuffgen_dag)\n",
|
|
||||||
"\n",
|
|
||||||
"powermatrix_scuffgen = sum1gen.__add__(sum2gen) "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.008544129580638216+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j),\n",
|
|
||||||
" (-0.0006352854997266949+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Power matrix of generator is diagonal and all its eigenvalues are negative:\n",
|
|
||||||
"powermatrix_scuffgen[0,0], powermatrix_scuffgen[1,1], powermatrix_scuffgen[2,2], powermatrix_scuffgen[3,3], powermatrix_scuffgen[4,4], powermatrix_scuffgen[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 19,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((0.04373066071852283+0j),\n",
|
|
||||||
" (0.04370088172427582+0j),\n",
|
|
||||||
" (0.043730660553373296+0j),\n",
|
|
||||||
" (0.001021256123757952+0j),\n",
|
|
||||||
" (0.0010213406041430792+0j),\n",
|
|
||||||
" (0.0010212560750220145+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 19,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew[0,0], powermatrix_scuffnew[1,1], powermatrix_scuffnew[2,2], powermatrix_scuffnew[3,3], powermatrix_scuffnew[4,4], powermatrix_scuffnew[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 20,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-0.004364703222422517+0j),\n",
|
|
||||||
" (-0.004361872918812184+0j),\n",
|
|
||||||
" (-0.004364703232328262+0j),\n",
|
|
||||||
" (-2.6256479824067564e-05+0j),\n",
|
|
||||||
" (-2.6262303053141142e-05+0j),\n",
|
|
||||||
" (-2.6256487319428013e-05+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 20,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffold[0,0], powermatrix_scuffold[1,1], powermatrix_scuffold[2,2], powermatrix_scuffold[3,3], powermatrix_scuffold[4,4], powermatrix_scuffold[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-10.019160178833705-0j),\n",
|
|
||||||
" (-10.018834234211564-0j),\n",
|
|
||||||
" (-10.019160118257586-0j),\n",
|
|
||||||
" (-38.895393845668316-0j),\n",
|
|
||||||
" (-38.88998623145963-0j),\n",
|
|
||||||
" (-38.89538088616882-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#So! There is a fixed factor between the N/M elements of Scuff new and old:\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/powermatrix_scuffold[0,0], powermatrix_scuffnew[1,1]/powermatrix_scuffold[1,1], powermatrix_scuffnew[2,2]/powermatrix_scuffold[2,2], powermatrix_scuffnew[3,3]/powermatrix_scuffold[3,3], powermatrix_scuffnew[4,4]/powermatrix_scuffold[4,4], powermatrix_scuffnew[5,5]/powermatrix_scuffold[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-5.118211317583541-0j),\n",
|
|
||||||
" (-5.11472600126595-0j),\n",
|
|
||||||
" (-5.118211298254535-0j),\n",
|
|
||||||
" (-1.6075545942687262-0j),\n",
|
|
||||||
" (-1.6076875744566317-0j),\n",
|
|
||||||
" (-1.60755451755371-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#And there is a fixed factor for new / generated as well! (hence also for old / generated)\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/powermatrix_scuffgen[0,0], powermatrix_scuffnew[1,1]/powermatrix_scuffgen[1,1], powermatrix_scuffnew[2,2]/powermatrix_scuffgen[2,2], powermatrix_scuffnew[3,3]/powermatrix_scuffgen[3,3], powermatrix_scuffnew[4,4]/powermatrix_scuffgen[4,4], powermatrix_scuffnew[5,5]/powermatrix_scuffgen[5,5]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-1.60755451755371-0j), (-2.557363000632975+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"powermatrix_scuffnew[5,5]/powermatrix_scuffgen[5,5], powermatrix_scuffnew[1,1]/powermatrix_scuffgen[1,1]/2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((1.599227713011597e-16-0j),\n",
|
|
||||||
" (8.902299490051238e-14+0j),\n",
|
|
||||||
" (1.504486797691096e-21-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Let's also calculate the determinants\n",
|
|
||||||
"detnew = powermatrix_scuffnew[0,0]*powermatrix_scuffnew[1,1]*powermatrix_scuffnew[2,2]*powermatrix_scuffnew[3,3]*powermatrix_scuffnew[4,4]*powermatrix_scuffnew[5,5]\n",
|
|
||||||
"detold = powermatrix_scuffold[0,0]*powermatrix_scuffold[1,1]*powermatrix_scuffold[2,2]*powermatrix_scuffold[3,3]*powermatrix_scuffold[4,4]*powermatrix_scuffold[5,5]\n",
|
|
||||||
"detgen = powermatrix_scuffgen[0,0]*powermatrix_scuffgen[1,1]*powermatrix_scuffgen[2,2]*powermatrix_scuffgen[3,3]*powermatrix_scuffgen[4,4]*powermatrix_scuffgen[5,5]\n",
|
|
||||||
"detgen, detnew, detold"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((1.5992277130116025e-16+0j),\n",
|
|
||||||
" (8.902299447416401e-14+2.6128569373609595e-39j),\n",
|
|
||||||
" (1.504486701753944e-21-2.892571608172536e-45j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 23,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"np.linalg.det(powermatrix_scuffgen), np.linalg.det(powermatrix_scuffnew), np.linalg.det(powermatrix_scuffold)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 24,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#We try to normalize the power matrix elements for each case with the corresponding determinants."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 25,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-53426597795433.88+0j),\n",
|
|
||||||
" (-53426597795433.88+0j),\n",
|
|
||||||
" (-53426597795433.88+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j),\n",
|
|
||||||
" (-3972451793812.1055+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 25,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#T-matrix generator: \n",
|
|
||||||
"powermatrix_scuffgen[0,0]/detgen, powermatrix_scuffgen[1,1]/detgen, powermatrix_scuffgen[2,2]/detgen, powermatrix_scuffgen[3,3]/detgen, powermatrix_scuffgen[4,4]/detgen, powermatrix_scuffgen[5,5]/detgen "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 26,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((-2.901124309712079e+18+0j),\n",
|
|
||||||
" (-2.899243067806416e+18+0j),\n",
|
|
||||||
" (-2.901124316296214e+18+0j),\n",
|
|
||||||
" (-1.7452117136795634e+16+0j),\n",
|
|
||||||
" (-1.7455987711853198e+16+0j),\n",
|
|
||||||
" (-1.7452122118800434e+16+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 26,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Not bugfixed Scuff-EM: \n",
|
|
||||||
"powermatrix_scuffold[0,0]/detold, powermatrix_scuffold[1,1]/detold, powermatrix_scuffold[2,2]/detold, powermatrix_scuffold[3,3]/detold, powermatrix_scuffold[4,4]/detold, powermatrix_scuffold[5,5]/detold "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 27,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((491228819782.9563+0j),\n",
|
|
||||||
" (490894310768.96173+0j),\n",
|
|
||||||
" (491228817927.8229+0j),\n",
|
|
||||||
" (11471823936.043226+0j),\n",
|
|
||||||
" (11472772908.667904+0j),\n",
|
|
||||||
" (11471823388.58987+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 27,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#New Scuff-EM: \n",
|
|
||||||
"powermatrix_scuffnew[0,0]/detnew, powermatrix_scuffnew[1,1]/detnew, powermatrix_scuffnew[2,2]/detnew, powermatrix_scuffnew[3,3]/detnew, powermatrix_scuffnew[4,4]/detnew, powermatrix_scuffnew[5,5]/detnew "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 28,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"#It might make more sense to renormalize the electric and magnetic parts of the power matrices separately:"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((13698.226641508763-0j),\n",
|
|
||||||
" (13698.226641508763-0j),\n",
|
|
||||||
" (13698.226641508763-0j),\n",
|
|
||||||
" (2477776.413504498-0j),\n",
|
|
||||||
" (2477776.413504498-0j),\n",
|
|
||||||
" (2477776.413504498-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#T-matrix generator:\n",
|
|
||||||
"detgen_el = powermatrix_scuffgen[0,0]*powermatrix_scuffgen[1,1]*powermatrix_scuffgen[2,2]\n",
|
|
||||||
"detgen_mag = powermatrix_scuffgen[3,3]*powermatrix_scuffgen[4,4]*powermatrix_scuffgen[5,5]\n",
|
|
||||||
"powermatrix_scuffgen[0,0]/detgen_el, powermatrix_scuffgen[1,1]/detgen_el, powermatrix_scuffgen[2,2]/detgen_el, powermatrix_scuffgen[3,3]/detgen_mag, powermatrix_scuffgen[4,4]/detgen_mag, powermatrix_scuffgen[5,5]/detgen_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 30,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((52525.751093170744-0j),\n",
|
|
||||||
" (52491.69062780147-0j),\n",
|
|
||||||
" (52525.75121237855-0j),\n",
|
|
||||||
" (1450208903.6280527-0j),\n",
|
|
||||||
" (1450530534.6580672-0j),\n",
|
|
||||||
" (1450209317.614944-0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 30,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#NOT bugfixed Scuff-EM:\n",
|
|
||||||
"detold_el = powermatrix_scuffold[0,0]*powermatrix_scuffold[1,1]*powermatrix_scuffold[2,2]\n",
|
|
||||||
"detold_mag = powermatrix_scuffold[3,3]*powermatrix_scuffold[4,4]*powermatrix_scuffold[5,5]\n",
|
|
||||||
"powermatrix_scuffold[0,0]/detold_el, powermatrix_scuffold[1,1]/detold_el, powermatrix_scuffold[2,2]/detold_el, powermatrix_scuffold[3,3]/detold_mag, powermatrix_scuffold[4,4]/detold_mag, powermatrix_scuffold[5,5]/detold_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"((523.2675016470721+0j),\n",
|
|
||||||
" (522.9111754524715+0j),\n",
|
|
||||||
" (523.2674996709441+0j),\n",
|
|
||||||
" (958726.5381294343+0j),\n",
|
|
||||||
" (958805.8459399715+0j),\n",
|
|
||||||
" (958726.4923775065+0j))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"#Bugfixed Scuff-EM:\n",
|
|
||||||
"detnew_el = powermatrix_scuffnew[0,0]*powermatrix_scuffnew[1,1]*powermatrix_scuffnew[2,2]\n",
|
|
||||||
"detnew_mag = powermatrix_scuffnew[3,3]*powermatrix_scuffnew[4,4]*powermatrix_scuffnew[5,5]\n",
|
|
||||||
"powermatrix_scuffnew[0,0]/detnew_el, powermatrix_scuffnew[1,1]/detnew_el, powermatrix_scuffnew[2,2]/detnew_el, powermatrix_scuffnew[3,3]/detnew_mag, powermatrix_scuffnew[4,4]/detnew_mag, powermatrix_scuffnew[5,5]/detnew_mag "
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.6.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
|
@ -1,362 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, make_dict_action, sslice, annotate_pdf_metadata
|
|
||||||
figscale=3
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega'])
|
|
||||||
ap.add_argument("-k", '--wavevector', nargs=2, type=float, required=True, help='"Bloch" vector, modulating phase of the driving', metavar=('KX', 'KY'), default=(0., 0.))
|
|
||||||
# ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
ap.add_argument("-S", "--symmetry-adapted", default=None, help="Use a symmetry-adapted basis of a given point group instead of individual spherical harmonics")
|
|
||||||
ap.add_argument("-d", "--ccd-distance", type=float, default=math.nan, help='Far-field "CCD" distance from the sample')
|
|
||||||
ap.add_argument("-D", "--ccd-size", type=float, default=math.nan, help='Far-field "CCD" width and heighth')
|
|
||||||
ap.add_argument("-R", "--ccd-resolution", type=int, default=101, help='Far-field "CCD" resolution')
|
|
||||||
ap.add_argument("--xslice", default={None:None}, nargs=2,
|
|
||||||
action=make_dict_action(argtype=sslice, postaction='append', first_is_key=True),
|
|
||||||
)
|
|
||||||
ap.add_argument("--yslice", default={None:None}, nargs=2,
|
|
||||||
action=make_dict_action(argtype=sslice, postaction='append', first_is_key=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#ap.add_argument("--irrep", type=str, default="none", help="Irrep subspace (irrep index from 0 to 7, irrep label, or 'none' for no irrep decomposition")
|
|
||||||
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
Nx, Ny = a.size
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "cd_%s_p%gnmx%gnm_%dx%d_m%s_n%s_k_%g_%g_f%geV_L%d_micro-%s" % (
|
|
||||||
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), str(a.background), a.wavevector[0], a.wavevector[1], a.eV, a.lMax, "SO3" if a.symmetry_adapted is None else a.symmetry_adapted)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, qpms_library_version
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# Check slice ranges and generate all corresponding combinations
|
|
||||||
slicepairs = []
|
|
||||||
slicelabels = set(a.xslice.keys()) | set(a.yslice.keys())
|
|
||||||
for label in slicelabels:
|
|
||||||
rowslices = a.xslice.get(label, None)
|
|
||||||
colslices = a.yslice.get(label, None)
|
|
||||||
# TODO check validity of the slices.
|
|
||||||
if rowslices is None:
|
|
||||||
rowslices = [slice(None, None, None)]
|
|
||||||
if colslices is None:
|
|
||||||
colslices = [slice(None, None, None)]
|
|
||||||
for rs in rowslices:
|
|
||||||
for cs in colslices:
|
|
||||||
slicepairs.append((rs, cs))
|
|
||||||
|
|
||||||
def realdipfieldlabels(yp):
|
|
||||||
if yp == 0: return 'x'
|
|
||||||
if yp == 1: return 'y'
|
|
||||||
if yp == 2: return 'z'
|
|
||||||
raise ValueError
|
|
||||||
def realdipfields(vecgrid, yp):
|
|
||||||
if yp == 1:
|
|
||||||
return vecgrid[...,0] + vecgrid[...,2]
|
|
||||||
if yp == 0:
|
|
||||||
return -1j*(vecgrid[...,0] - vecgrid[...,2])
|
|
||||||
if yp == 2:
|
|
||||||
return vecgrid[...,1]
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
def float_nicestr(x, tol=1e-5):
|
|
||||||
x = float(x)
|
|
||||||
if .5**2 - abs(x) < tol:
|
|
||||||
return(("-" if x < 0 else '+') + "2^{-2}")
|
|
||||||
else:
|
|
||||||
return "%+.3g" % x
|
|
||||||
|
|
||||||
def cplx_nicestr(x, tol=1e-5):
|
|
||||||
x = complex(x)
|
|
||||||
if x == 0:
|
|
||||||
return '0'
|
|
||||||
ret = ""
|
|
||||||
if x.real:
|
|
||||||
ret = ret + float_nicestr(x.real, tol)
|
|
||||||
if x.imag:
|
|
||||||
ret = ret + float_nicestr(x.imag, tol) + 'i'
|
|
||||||
if x.real and x.imag:
|
|
||||||
return '(' + ret + ')'
|
|
||||||
else:
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def cleanarray(a, atol=1e-10, copy=True):
|
|
||||||
a = np.array(a, copy=copy)
|
|
||||||
sieve = abs(a.real) < atol
|
|
||||||
a[sieve] = 1j * a[sieve].imag
|
|
||||||
sieve = abs(a.imag) < atol
|
|
||||||
a[sieve] = a[sieve].real
|
|
||||||
return a
|
|
||||||
|
|
||||||
def nicerot(a, atol=1e-10, copy=True): #gives array a "nice" phase
|
|
||||||
a = np.array(a, copy=copy)
|
|
||||||
i = np.argmax(abs(a))
|
|
||||||
a = a / a[i] * abs(a[i])
|
|
||||||
return a
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
|
||||||
orig_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
|
||||||
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
|
||||||
|
|
||||||
|
|
||||||
omega = ap.omega
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
medium = EpsMuGenerator(ap.background_epsmu)
|
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info['D2h'])
|
|
||||||
ss, ssw = ScatteringSystem.create(particles=particles, medium=medium, omega=omega, sym=sym)
|
|
||||||
|
|
||||||
wavenumber = ap.background_epsmu.k(omega) # Currently, ScatteringSystem does not "remember" frequency nor wavenumber
|
|
||||||
|
|
||||||
# Mapping between ss particles and grid positions
|
|
||||||
positions = ss.positions
|
|
||||||
xpositions = np.unique(positions[:,0])
|
|
||||||
assert(len(xpositions) == Nx)
|
|
||||||
ypositions = np.unique(positions[:,1])
|
|
||||||
assert(len(ypositions == Ny))
|
|
||||||
# particle positions as integer indices
|
|
||||||
posmap = np.empty((positions.shape[0],2), dtype=int)
|
|
||||||
invposmap = np.empty((Nx, Ny), dtype=int)
|
|
||||||
for i, pos in enumerate(positions):
|
|
||||||
posmap[i,0] = np.searchsorted(xpositions, positions[i,0])
|
|
||||||
posmap[i,1] = np.searchsorted(ypositions, positions[i,1])
|
|
||||||
invposmap[posmap[i,0], posmap[i, 1]] = i
|
|
||||||
|
|
||||||
def fullvec2grid(fullvec, swapxy=False):
|
|
||||||
arr = np.empty((Nx,Ny,nelem), dtype=complex)
|
|
||||||
for pi, offset in enumerate(ss.fullvec_poffsets):
|
|
||||||
ix, iy = posmap[pi]
|
|
||||||
arr[ix, iy] = fullvec[offset:offset+nelem]
|
|
||||||
return np.swapaxes(arr, 0, 1) if swapxy else arr
|
|
||||||
|
|
||||||
|
|
||||||
outfile_tmp = defaultprefix + ".tmp" if a.output is None else a.output + ".tmp"
|
|
||||||
|
|
||||||
nelem = len(bspec)
|
|
||||||
phases = np.exp(1j*np.dot(ss.positions[:,:2], np.array(a.wavevector)))
|
|
||||||
driving_full = np.zeros((nelem, ss.fecv_size),dtype=complex)
|
|
||||||
if a.symmetry_adapted is not None:
|
|
||||||
ss1, ssw1 = ScatteringSystem.create(particles=[Particle((0,0,0), ap.tmgen, bspec)], medium=medium, omega=omega,
|
|
||||||
sym=FinitePointGroup(point_group_info[a.symmetry_adapted]))
|
|
||||||
fvcs1 = np.empty((nelem, nelem), dtype=complex)
|
|
||||||
y = 0
|
|
||||||
iris1 = []
|
|
||||||
for iri1 in range(ss1.nirreps):
|
|
||||||
for j in range(ss1.saecv_sizes[iri1]):
|
|
||||||
pvc1 = np.zeros((ss1.saecv_sizes[iri1],), dtype=complex)
|
|
||||||
pvc1[j] = 1
|
|
||||||
fvcs1[y] = ss1.unpack_vector(pvc1, iri1)
|
|
||||||
fvcs1[y] = cleanarray(nicerot(fvcs1[y], copy=False), copy=False)
|
|
||||||
driving_full[y] = (phases[:, None] * fvcs1[y][None,:]).flatten()
|
|
||||||
y += 1
|
|
||||||
iris1.append(iri1)
|
|
||||||
iris1 = np.array(iris1)
|
|
||||||
else:
|
|
||||||
for y in range(nelem):
|
|
||||||
driving_full[y,y::nelem] = phases
|
|
||||||
|
|
||||||
|
|
||||||
# Apply the driving on the specified slices only
|
|
||||||
nsp = len(slicepairs)
|
|
||||||
driving_full_sliced = np.zeros((nsp,) + driving_full.shape, dtype=complex)
|
|
||||||
p1range = np.arange(nelem)
|
|
||||||
for spi in range(nsp):
|
|
||||||
xs, ys = slicepairs[spi]
|
|
||||||
driven_pi = invposmap[xs, ys].flatten()
|
|
||||||
driven_y = ((driven_pi * nelem)[:,None] + p1range[None,:]).flatten()
|
|
||||||
driving_full_sliced[spi][:, driven_y] = driving_full[:, driven_y]
|
|
||||||
|
|
||||||
scattered_full = np.zeros((nsp, nelem, ss.fecv_size),dtype=complex)
|
|
||||||
scattered_ir = [None for iri in range(ss.nirreps)]
|
|
||||||
|
|
||||||
ir_contained = np.ones((nsp, nelem, ss.nirreps), dtype=bool)
|
|
||||||
|
|
||||||
for iri in range(ss.nirreps):
|
|
||||||
logging.info("processing irrep %d/%d" % (iri, ss.nirreps))
|
|
||||||
LU = None # to trigger garbage collection before the next call
|
|
||||||
translation_matrix = None
|
|
||||||
LU = ssw.scatter_solver(iri)
|
|
||||||
logging.info("LU solver created")
|
|
||||||
#translation_matrix = ss.translation_matrix_packed(wavenumber, iri, BesselType.REGULAR) + np.eye(ss.saecv_sizes[iri])
|
|
||||||
#logging.info("auxillary translation matrix created")
|
|
||||||
|
|
||||||
scattered_ir[iri] = np.zeros((nsp, nelem, ss.saecv_sizes[iri]), dtype=complex)
|
|
||||||
scattered_ir_unpacked = np.zeros((nsp, nelem, ss.fecv_size), dtype=complex)
|
|
||||||
|
|
||||||
for spi in range(nsp):
|
|
||||||
for y in range(nelem):
|
|
||||||
ã = driving_full_sliced[spi,y]
|
|
||||||
ãi = cleanarray(ss.pack_vector(ã, iri), copy=False)
|
|
||||||
if np.all(ãi == 0):
|
|
||||||
ir_contained[spi, y, iri] = False
|
|
||||||
continue
|
|
||||||
Tã = ssw.apply_Tmatrices_full(ã)
|
|
||||||
Tãi = ss.pack_vector(Tã, iri)
|
|
||||||
fi = LU(Tãi)
|
|
||||||
scattered_ir[iri][spi, y] = fi
|
|
||||||
scattered_ir_unpacked[spi, y] = ss.unpack_vector(fi, iri)
|
|
||||||
scattered_full[spi, y] += scattered_ir_unpacked[spi, y]
|
|
||||||
if a.save_gradually:
|
|
||||||
iriout = outfile_tmp + ".%d" % iri
|
|
||||||
np.savez(iriout, iri=iri, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
|
||||||
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
|
|
||||||
positions = ss.positions[:,:2],
|
|
||||||
scattered_ir_packed = scattered_ir[iri],
|
|
||||||
scattered_ir_full = scattered_ir_unpacked,
|
|
||||||
)
|
|
||||||
logging.info("partial results saved to %s"%iriout)
|
|
||||||
|
|
||||||
t, l, m = bspec.tlm()
|
|
||||||
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
logging.info("Computing the far fields")
|
|
||||||
if math.isnan(a.ccd_size):
|
|
||||||
a.ccd_size = (50 * a.ccd_distance / (max(Nx*px, Ny*py) *ssw.wavenumber.real))
|
|
||||||
ccd_size = a.ccd_size
|
|
||||||
ccd_x = np.linspace(-ccd_size/2, ccd_size/2, a.ccd_resolution)
|
|
||||||
ccd_y = np.linspace(-ccd_size/2, ccd_size/2, a.ccd_resolution)
|
|
||||||
ccd_grid = np.meshgrid(ccd_x, ccd_y, (a.ccd_distance,), indexing='ij')
|
|
||||||
ccd_points = np.swapaxes(np.stack(ccd_grid, axis=-1).squeeze(axis=-2), 0,1) # First axis is y, second is x, because of imshow...
|
|
||||||
ccd_fields = np.empty((nsp, nelem,) + ccd_points.shape, dtype=complex)
|
|
||||||
for spi in range(nsp):
|
|
||||||
for y in range(nelem):
|
|
||||||
ccd_fields[spi, y] = ssw.scattered_E(scattered_full[spi, y], ccd_points, btyp=BesselType.HANKEL_PLUS)
|
|
||||||
logging.info("Far fields done")
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
|
||||||
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
|
|
||||||
positions = ss.positions[:,:2],
|
|
||||||
scattered_ir_packed = np.array(scattered_ir, dtype=np.object),
|
|
||||||
scattered_full = scattered_full,
|
|
||||||
ir_contained = ir_contained,
|
|
||||||
t=t, l=l, m=m,
|
|
||||||
iris1 = iris1 if (a.symmetry_adapted is not None) else None,
|
|
||||||
irnames1 = ss1.irrep_names if (a.symmetry_adapted is not None) else None,
|
|
||||||
fvcs1 = fvcs1 if (a.symmetry_adapted is not None) else None,
|
|
||||||
#ccd_size = ccd_size if not math.isnan(a.ccd_distance) else None,
|
|
||||||
ccd_points = ccd_points if not math.isnan(a.ccd_distance) else None,
|
|
||||||
ccd_fields = ccd_fields if not math.isnan(a.ccd_distance) else None,
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
|
|
||||||
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt, cm
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
t, l, m = bspec.tlm()
|
|
||||||
phasecm = cm.twilight
|
|
||||||
pmcm = cm.bwr
|
|
||||||
abscm = cm.plasma
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
pp = PdfPages(plotfile)
|
|
||||||
|
|
||||||
for spi in range(nsp):
|
|
||||||
fig, axes = plt.subplots(nelem, 12 if math.isnan(a.ccd_distance) else 16, figsize=(figscale*(12 if math.isnan(a.ccd_distance) else 16), figscale*nelem))
|
|
||||||
for yp in range(0,3): # TODO xy-dipoles instead?
|
|
||||||
axes[0,4*yp+0].set_title("abs / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+1].set_title("arg / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+2].set_title("Fabs / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
axes[0,4*yp+3].set_title("Farg / (E,1,%s)" % realdipfieldlabels(yp))
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
#axes[0,12].set_title("$E_{xy}$ @ $z = %g; \phi$" % a.ccd_distance)
|
|
||||||
#axes[0,13].set_title("$E_{xy}$ @ $z = %g; \phi + \pi/2$" % a.ccd_distance)
|
|
||||||
axes[0,12].set_title("$|E_{x}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,13].set_title("$|E_{y}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,14].set_title("$|E_x + E_y|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
axes[0,15].set_title("$|E_{z}|^2$ @ $z = %g\,\mathrm{m}$" % a.ccd_distance)
|
|
||||||
for gg in range(12,16):
|
|
||||||
axes[-1,gg].set_xlabel("$x/\mathrm{m}$")
|
|
||||||
|
|
||||||
|
|
||||||
for y in range(nelem):
|
|
||||||
fulvec = scattered_full[spi,y]
|
|
||||||
if a.symmetry_adapted is not None:
|
|
||||||
driving_nonzero_y = [j for j in range(nelem) if abs(fvcs1[y,j]) > 1e-5]
|
|
||||||
driving_descr = ss1.irrep_names[iris1[y]]+'\n'+', '.join(('$'+cplx_nicestr(fvcs1[y,j])+'$' +
|
|
||||||
"(%s,%d,%+d)" % (("E" if t[j] == 2 else "M"), l[j], m[j]) for j in
|
|
||||||
driving_nonzero_y)) # TODO shorten the complex number precision
|
|
||||||
else:
|
|
||||||
driving_descr = "%s,%d,%+d"%('E' if t[y]==2 else 'M', l[y], m[y],)
|
|
||||||
axes[y,0].set_ylabel(driving_descr)
|
|
||||||
axes[y,-1].yaxis.set_label_position("right")
|
|
||||||
axes[y,-1].set_ylabel("$y/\mathrm{m}$\n"+driving_descr)
|
|
||||||
vecgrid = fullvec2grid(fulvec, swapxy=True)
|
|
||||||
vecgrid_ff = np.fft.fftshift(np.fft.fft2(vecgrid, axes=(0,1)),axes=(0,1))
|
|
||||||
lemax = np.amax(abs(vecgrid))
|
|
||||||
for yp in range(0,3):
|
|
||||||
if(np.amax(abs(realdipfields(vecgrid,yp))) > lemax*1e-5):
|
|
||||||
axes[y,yp*4].imshow(abs(realdipfields(vecgrid,yp)), vmin=0, interpolation='none')
|
|
||||||
axes[y,yp*4].text(0.5, 0.5, '%g' % np.amax(abs(realdipfields(vecgrid,yp))), horizontalalignment='center', verticalalignment='center', transform=axes[y,yp*4].transAxes)
|
|
||||||
axes[y,yp*4+1].imshow(np.angle(realdipfields(vecgrid,yp)), vmin=-np.pi, vmax=np.pi, cmap=phasecm, interpolation='none')
|
|
||||||
axes[y,yp*4+2].imshow(abs(realdipfields(vecgrid_ff,yp)), vmin=0, interpolation='none')
|
|
||||||
axes[y,yp*4+3].imshow(np.angle(realdipfields(vecgrid_ff,yp)), vmin=-np.pi, vmax=np.pi, cmap=phasecm, interpolation='none')
|
|
||||||
else:
|
|
||||||
for c in range(0,4):
|
|
||||||
axes[y,yp*4+c].tick_params(bottom=False, left=False, labelbottom=False, labelleft=False)
|
|
||||||
if not math.isnan(a.ccd_distance):
|
|
||||||
fxye=(-ccd_size/2, ccd_size/2, -ccd_size/2, ccd_size/2)
|
|
||||||
e2vmax = np.amax(np.linalg.norm(ccd_fields[spi,y], axis=-1)**2)
|
|
||||||
xint = abs(ccd_fields[spi,y,...,0])**2
|
|
||||||
yint = abs(ccd_fields[spi,y,...,1])**2
|
|
||||||
xyint = abs(ccd_fields[spi,y,...,0] + ccd_fields[spi,y,...,1])**2
|
|
||||||
zint = abs(ccd_fields[spi,y,...,2])**2
|
|
||||||
xintmax = np.amax(xint)
|
|
||||||
yintmax = np.amax(yint)
|
|
||||||
zintmax = np.amax(zint)
|
|
||||||
xyintmax = np.amax(xyint)
|
|
||||||
axes[y, 12].imshow(xint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 13].imshow(yint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 14].imshow(xyint, origin="lower", extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 15].imshow(zint, origin='lower', extent=fxye, cmap=abscm, interpolation='none')
|
|
||||||
axes[y, 12].text(0.5, 0.5, '%g\n%g' % (xintmax,xintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,12].transAxes)
|
|
||||||
axes[y, 13].text(0.5, 0.5, '%g\n%g' % (yintmax,yintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,13].transAxes)
|
|
||||||
axes[y, 14].text(0.5, 0.5, '%g\n%g' % (xyintmax,xyintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,14].transAxes)
|
|
||||||
axes[y, 15].text(0.5, 0.5, '%g\n%g' % (zintmax,zintmax/e2vmax),
|
|
||||||
horizontalalignment='center', verticalalignment='center', transform=axes[y,15].transAxes)
|
|
||||||
for gg in range(12,16):
|
|
||||||
axes[y,gg].yaxis.tick_right()
|
|
||||||
for gg in range(12,15):
|
|
||||||
axes[y,gg].yaxis.set_major_formatter(plt.NullFormatter())
|
|
||||||
fig.text(0, 0, str(slicepairs[spi]), horizontalalignment='left', verticalalignment='bottom')
|
|
||||||
pp.savefig()
|
|
||||||
annotate_pdf_metadata(pp, scriptname="finiterectlat-constant-driving.py")
|
|
||||||
pp.close()
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
from qpms.argproc import ArgParser
|
||||||
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'background_analytical', 'single_particle', 'single_lMax', ])
|
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', ])
|
||||||
|
|
||||||
ap.add_argument("-t", "--rank-tolerance", type=float, default=1e11)
|
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("-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')
|
||||||
|
@ -19,9 +19,8 @@ ap.add_argument("-f", "--centre", type=complex, required=True, help='Contour cen
|
||||||
ap.add_argument("--ai", type=float, default=0.05, help="Contour imaginary half-axis 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("--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("-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")
|
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()
|
a=ap.parse_args()
|
||||||
|
|
||||||
|
@ -31,15 +30,11 @@ logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
||||||
Nx, Ny = a.size
|
Nx, Ny = a.size
|
||||||
px, py = a.period
|
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))
|
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)
|
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" % (
|
defaultprefix = "%s_p%gnmx%gnm_%dx%d_m%s_n%g_L%d_c(%s±%g±%gj)eV_cn%d" % (
|
||||||
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), str(a.background), a.lMax,
|
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), a.refractive_index, a.lMax,
|
||||||
str(a.centre), a.ar, a.ai, a.N,
|
str(a.centre), a.ai, a.ar, a.N)
|
||||||
thegroup,
|
|
||||||
)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
logging.info("Default file prefix: %s" % defaultprefix)
|
||||||
|
|
||||||
def inside_ellipse(point_xy, centre_xy, halfaxes_xy):
|
def inside_ellipse(point_xy, centre_xy, halfaxes_xy):
|
||||||
|
@ -74,9 +69,9 @@ bspec = BaseSpec(lMax = a.lMax)
|
||||||
medium = EpsMuGenerator(ap.background_epsmu)
|
medium = EpsMuGenerator(ap.background_epsmu)
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
particles= [Particle(orig_xy[i], ap.tmgen, bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info[thegroup])
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
logging.info("Creating scattering system object")
|
logging.info("Creating scattering system object")
|
||||||
ss, ssw = ScatteringSystem.create(particles, medium, a.centre * eh, sym=sym)
|
ss, ssw = ScatteringSystem.create(particles, medium, sym, a.centre * eh)
|
||||||
|
|
||||||
if a.irrep == 'none':
|
if a.irrep == 'none':
|
||||||
iri = None # no irrep decomposition
|
iri = None # no irrep decomposition
|
||||||
|
@ -100,7 +95,7 @@ results['inside_contour'] = inside_ellipse((results['eigval'].real, results['eig
|
||||||
results['refractive_index_internal'] = [medium(om).n for om in results['eigval']]
|
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
|
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)
|
np.savez(outfile, meta=vars(a), **results)
|
||||||
logging.info("Saved to %s" % outfile)
|
logging.info("Saved to %s" % outfile)
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -110,7 +105,7 @@ if a.plot or (a.plot_out is not None):
|
||||||
import matplotlib
|
import matplotlib
|
||||||
matplotlib.use('pdf')
|
matplotlib.use('pdf')
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
fig = plt.figure()
|
fig = plt.figure()
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
ax.plot(sinalpha_list, σ_ext*1e12,label='$\sigma_\mathrm{ext}$')
|
ax.plot(sinalpha_list, σ_ext*1e12,label='$\sigma_\mathrm{ext}$')
|
||||||
|
@ -121,9 +116,7 @@ if a.plot or (a.plot_out is not None):
|
||||||
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
||||||
with PdfPages(plotfile) as pdf:
|
fig.savefig(plotfile)
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='finiterectlat-modes.py')
|
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
import math
|
import math
|
||||||
pi = math.pi
|
from qpms.argproc import ArgParser
|
||||||
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
|
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega'])
|
||||||
|
ap.add_argument("-k", '--kx-lim', nargs=2, type=float, required=True, help='k vector', metavar=('KX_MIN', 'KX_MAX'))
|
||||||
|
# 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", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
||||||
|
ap.add_argument("-N", type=int, default="151", help="Number of angles")
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
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("-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("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
||||||
|
@ -17,9 +19,18 @@ a=ap.parse_args()
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
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 = "%s_p%gnmx%gnm_%dx%d_m%s_n%g_angles(%g_%g)_Ey_f%geV_L%d_cn%d" % (
|
||||||
|
particlestr, px*1e9, py*1e9, Nx, Ny, str(a.material), a.refractive_index, a.kx_lim[0], a.kx_lim[1], a.eV, a.lMax, a.N)
|
||||||
|
logging.info("Default file prefix: %s" % defaultprefix)
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import qpms
|
import qpms
|
||||||
from qpms.qpms_p import cart2sph, sph2cart, sph_loccart2cart, sph_loccart_basis
|
|
||||||
from qpms.cybspec import BaseSpec
|
from qpms.cybspec import BaseSpec
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
||||||
from qpms.qpms_c import Particle
|
from qpms.qpms_c import Particle
|
||||||
|
@ -31,209 +42,94 @@ eh = eV/hbar
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
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
|
#Particle positions
|
||||||
orig_x = (np.arange(Nx/2) + (0 if (Nx % 2) else .5)) * px
|
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_y = (np.arange(Ny/2) + (0 if (Ny % 2) else .5)) * py
|
||||||
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
orig_xy = np.stack(np.meshgrid(orig_x, orig_y), axis = -1)
|
||||||
|
|
||||||
|
|
||||||
|
omega = ap.omega
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
bspec = BaseSpec(lMax = a.lMax)
|
||||||
particles= [Particle(orig_xy[i], ap.tmgen, bspec=bspec) for i in np.ndindex(orig_xy.shape[:-1])]
|
Tmatrix = ap.tmgen(bspec, ap.omega)
|
||||||
|
particles= [Particle(orig_xy[i], Tmatrix) for i in np.ndindex(orig_xy.shape[:-1])]
|
||||||
|
|
||||||
sym = FinitePointGroup(point_group_info['D2h'])
|
sym = FinitePointGroup(point_group_info['D2h'])
|
||||||
ss, ssw = ScatteringSystem.create(particles, ap.background_emg, ap.allomegas[0], sym=sym)
|
ss = ScatteringSystem(particles, sym)
|
||||||
|
|
||||||
|
wavenumber = ap.background_epsmu.k(omega).real # Currently, ScatteringSystem does not "remember" frequency nor wavenumber
|
||||||
|
|
||||||
## Plane wave data
|
sinalpha_list = np.linspace(a.kx_lim[0],a.kx_lim[1],a.N)
|
||||||
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)
|
# Plane wave data
|
||||||
E_cart_list = sph_loccart2cart(E_sph, dir_sph_list)
|
E_cart_list = np.empty((a.N,3), dtype=complex)
|
||||||
|
E_cart_list[:,:] = np.array((0,1,0))[None,:]
|
||||||
|
k_cart_list = np.empty((a.N,3), dtype=float)
|
||||||
|
k_cart_list[:,0] = sinalpha_list
|
||||||
|
k_cart_list[:,1] = 0
|
||||||
|
k_cart_list[:,2] = np.sqrt(1-sinalpha_list**2)
|
||||||
|
k_cart_list *= wavenumber
|
||||||
|
|
||||||
nfreq = len(ap.allomegas)
|
σ_ext_list_ir = np.empty((a.N, ss.nirreps), dtype=float)
|
||||||
ndir = a.theta.shape[0]
|
σ_scat_list_ir = np.empty((a.N, ss.nirreps), dtype=float)
|
||||||
|
|
||||||
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"
|
outfile_tmp = defaultprefix + ".tmp" if a.output is None else a.output + ".tmp"
|
||||||
|
|
||||||
for i, omega in enumerate(ap.allomegas):
|
for iri in range(ss.nirreps):
|
||||||
logging.info("Processing frequency %g eV" % (omega / eV,))
|
logging.info("processing irrep %d/%d" % (iri, ss.nirreps))
|
||||||
if i != 0:
|
LU = None # to trigger garbage collection before the next call
|
||||||
ssw = ss(omega)
|
translation_matrix = None
|
||||||
if ssw.wavenumber.imag != 0:
|
LU = ss.scatter_solver(wavenumber,iri)
|
||||||
warnings.warn("The background medium wavenumber has non-zero imaginary part. Don't expect emaningful results for cross sections.")
|
logging.info("LU solver created")
|
||||||
wavenumber = ssw.wavenumber.real
|
translation_matrix = ss.translation_matrix_packed(wavenumber, iri, BesselType.REGULAR) + np.eye(ss.saecv_sizes[iri])
|
||||||
wavenumbers[i] = wavenumber
|
logging.info("auxillary translation matrix created")
|
||||||
|
|
||||||
k_sph_list = np.array(dir_sph_list, copy=True)
|
for j in range(a.N):
|
||||||
k_sph_list[:,0] = wavenumber
|
# the following two could be calculated only once, but probably not a big deal
|
||||||
|
ã = ss.planewave_full(k_cart=k_cart_list[j], E_cart=E_cart_list[j])
|
||||||
|
Tã = ss.apply_Tmatrices_full(ã)
|
||||||
|
|
||||||
k_cart_arr[i] = sph2cart(k_sph_list)
|
Tãi = ss.pack_vector(Tã, iri)
|
||||||
|
ãi = ss.pack_vector(ã, iri)
|
||||||
|
fi = LU(Tãi)
|
||||||
|
σ_ext_list_ir[j, iri] = -np.vdot(ãi, fi).real/wavenumber**2
|
||||||
|
σ_scat_list_ir[j, iri] = np.vdot(fi,np.dot(translation_matrix, fi)).real/wavenumber**2
|
||||||
|
if a.save_gradually:
|
||||||
|
iriout = outfile_tmp + ".%d" % iri
|
||||||
|
np.savez(iriout, iri=iri, meta=vars(a), sinalpha=sinalpha_list, k_cart = k_cart_list, E_cart=E_cart_list,
|
||||||
|
omega=omega, wavenumber=wavenumber, σ_ext_list_ir=σ_ext_list_ir[:,iri], σ_scat_list_ir=σ_scat_list_ir[:,iri])
|
||||||
|
logging.info("partial results saved to %s"%iriout)
|
||||||
|
|
||||||
for iri in range(ss.nirreps):
|
σ_abs_list_ir = σ_ext_list_ir - σ_scat_list_ir
|
||||||
logging.info("processing irrep %d/%d" % (iri, ss.nirreps))
|
σ_abs= np.sum(σ_abs_list_ir, axis=-1)
|
||||||
LU = None # to trigger garbage collection before the next call
|
σ_scat= np.sum(σ_scat_list_ir, axis=-1)
|
||||||
translation_matrix = None
|
σ_ext= np.sum(σ_ext_list_ir, axis=-1)
|
||||||
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
|
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
|
np.savez(outfile, meta=vars(a), sinalpha=sinalpha_list, k_cart = k_cart_list, E_cart=E_cart_list, σ_ext=σ_ext,σ_abs=σ_abs,σ_scat=σ_scat,
|
||||||
k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph),
|
σ_ext_ir=σ_ext_list_ir,σ_abs_ir=σ_abs_list_ir,σ_scat_ir=σ_scat_list_ir, omega=omega, wavenumber=wavenumber
|
||||||
σ_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)
|
logging.info("Saved to %s" % outfile)
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
if a.plot or (a.plot_out is not None):
|
||||||
import matplotlib
|
import matplotlib
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
matplotlib.use('pdf')
|
matplotlib.use('pdf')
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
from scipy.interpolate import griddata
|
|
||||||
|
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
|
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
||||||
with PdfPages(plotfile) as pdf:
|
fig.savefig(plotfile)
|
||||||
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)
|
exit(0)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,376 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse, re, random, string, sys
|
||||||
|
import subprocess
|
||||||
|
import warnings
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
|
||||||
|
unitcell_size = 1 # rectangular lattice
|
||||||
|
unitcell_indices = tuple(range(unitcell_size))
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
parser.add_argument('--TMatrix', action='store', required=True, help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', '-p', '-o', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
parser.add_argument('--nosuffix', action='store_true', help='Do not add dimension metadata to the output filenames')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
#parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--dx', action='store', type=float, required=True, help='x-direction lattice constant')
|
||||||
|
parser.add_argument('--dy', action='store', type=float, required=True, help='y-direction lattice constant')
|
||||||
|
|
||||||
|
parser.add_argument('--Nx', '--nx', action='store', type=int, required=True, help='Lattice points in the x-direction')
|
||||||
|
parser.add_argument('--Ny', '--ny', action='store', type=int, required=True, help='Lattice points in the y-direction')
|
||||||
|
|
||||||
|
# In these default settings, the area is 2x2 times larger than first BZ
|
||||||
|
parser.add_argument('--kxmin', action='store', type=float, default=-1., help='TODO')
|
||||||
|
parser.add_argument('--kxmax', action='store', type=float, default=1., help='TODO')
|
||||||
|
parser.add_argument('--kymin', action='store', type=float, default=-1., help='TODO')
|
||||||
|
parser.add_argument('--kymax', action='store', type=float, default=1., help='TODO')
|
||||||
|
|
||||||
|
#parser.add_argument('--kdensity', action='store', type=int, default=33, help='Number of k-points per x-axis segment')
|
||||||
|
parser.add_argument('--kxdensity', action='store', type=int, default=51, help='k-space resolution in the x-direction')
|
||||||
|
parser.add_argument('--kydensity', action='store', type=int, default=51, help='k-space resolution in the y-direction')
|
||||||
|
|
||||||
|
partgrp = parser.add_mutually_exclusive_group()
|
||||||
|
partgrp.add_argument('--only_TE', action='store_true', help='Calculate only the projection on the E⟂z modes')
|
||||||
|
partgrp.add_argument('--only_TM', action='store_true', help='Calculate only the projection on the E∥z modes')
|
||||||
|
partgrp.add_argument('--serial', action='store_true', help='Calculate the TE and TM parts separately to save memory')
|
||||||
|
|
||||||
|
parser.add_argument('--nocentre', action='store_true', help='Place the coordinate origin to the left bottom corner rather that to the centre of the array')
|
||||||
|
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=3000, help='Number of k-points per output file (default 3000)')
|
||||||
|
parser.add_argument('--lMax', action='store', type=int, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
#parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--tr%d'%i, dest='ops', action=make_action_sharedlist('tr%d'%i, 'ops'))
|
||||||
|
popgrp.add_argument('--sym', dest='ops', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--sym%d'%i, dest='ops', action=make_action_sharedlist('sym%d'%i, 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult0', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult0', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult1', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult1', 'ops'))
|
||||||
|
popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
for i in unitcell_indices:
|
||||||
|
popgrp.add_argument('--multl%d'%i, dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl%d'%i, 'ops'))
|
||||||
|
#popgrp.add_argument('--multl1', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl1', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
# TODO enable more flexible per-sublattice specification
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
if pargs.verbose:
|
||||||
|
print(pargs, file = sys.stderr)
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
dy = pargs.dy
|
||||||
|
dx = pargs.dx
|
||||||
|
Ny = pargs.Ny
|
||||||
|
Nx = pargs.Nx
|
||||||
|
|
||||||
|
TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
#gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kxdensity = pargs.kxdensity
|
||||||
|
kydensity = pargs.kydensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
ops = list()
|
||||||
|
opre = re.compile('(tr|sym|copy|multl|mult)(\d*)')
|
||||||
|
for oparg in pargs.ops:
|
||||||
|
opm = opre.match(oparg[0])
|
||||||
|
if opm:
|
||||||
|
ops.append(((opm.group(2),) if opm.group(2) else unitcell_indices, opm.group(1), oparg[1]))
|
||||||
|
else:
|
||||||
|
raise # should not happen
|
||||||
|
if(verbose):
|
||||||
|
print(ops, file = sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
refind = math.sqrt(epsilon_b)
|
||||||
|
cdn = c / refind
|
||||||
|
k_0 = freq * refind / c # = freq / cdn
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),unitcell_size,2,nelem,2,nelem)) )
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
#targets = (0,1)
|
||||||
|
targets = unitcell_indices
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
|
||||||
|
xpositions = np.arange(Nx) * dx
|
||||||
|
ypositions = np.arange(Ny) * dy
|
||||||
|
if not pargs.nocentre:
|
||||||
|
xpositions -= Nx * dx / 2
|
||||||
|
ypositions -= Ny * dy / 2
|
||||||
|
xpositions, ypositions = np.meshgrid(xpositions, ypositions, indexing='ij', copy=False)
|
||||||
|
positions=np.stack((xpositions.ravel(),ypositions.ravel()), axis=-1)
|
||||||
|
positions=positions[np.random.permutation(len(positions))]
|
||||||
|
N = positions.shape[0]
|
||||||
|
|
||||||
|
kx = np.linspace(pargs.kxmin, pargs.kxmax, num=pargs.kxdensity, endpoint=True) * 2*np.pi / dx
|
||||||
|
ky = np.linspace(pargs.kymin, pargs.kymax, num=pargs.kydensity, endpoint=True) * 2*np.pi / dy
|
||||||
|
kx, ky = np.meshgrid(kx, ky, indexing='ij', copy=False)
|
||||||
|
kz = np.sqrt(k_0**2 - (kx ** 2 + ky ** 2))
|
||||||
|
|
||||||
|
klist_full = np.stack((kx,ky,kz), axis=-1).reshape((-1,3))
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.size / 3 / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points' % klist_full.size + ('in %d chunks'%chunkn) if chunkn>1 else '' , file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = qpms.__version__
|
||||||
|
except NameError:
|
||||||
|
version = None
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'script': os.path.basename(__file__),
|
||||||
|
'version': version,
|
||||||
|
'type' : 'Plane wave scattering on a finite rectangular lattice',
|
||||||
|
'lMax' : lMax,
|
||||||
|
'dx' : dx,
|
||||||
|
'dy' : dy,
|
||||||
|
'Nx' : Nx,
|
||||||
|
'Ny' : Ny,
|
||||||
|
#'maxlayer' : maxlayer,
|
||||||
|
#'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
#'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'chunki' : 0,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
'centred' : not pargs.nocentre
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
scat = qpms.Scattering_2D_zsym(positions, TMatrices_om, k_0, verbose=verbose)
|
||||||
|
|
||||||
|
if pargs.only_TE:
|
||||||
|
actions = (0,)
|
||||||
|
elif pargs.only_TM:
|
||||||
|
actions = (1,)
|
||||||
|
elif pargs.serial:
|
||||||
|
actions = (0,1)
|
||||||
|
else:
|
||||||
|
actions = (None,)
|
||||||
|
|
||||||
|
xu = np.array((1,0,0))
|
||||||
|
yu = np.array((0,1,0))
|
||||||
|
zu = np.array((0,0,1))
|
||||||
|
TEč, TMč = qpms.symz_indexarrays(lMax)
|
||||||
|
|
||||||
|
klist_full_2D = klist_full[...,:2]
|
||||||
|
klist_full_dir = klist_full/np.linalg.norm(klist_full, axis=-1, keepdims=True)
|
||||||
|
for action in actions:
|
||||||
|
if action is None:
|
||||||
|
scat.prepare(verbose=verbose)
|
||||||
|
actionstring = ''
|
||||||
|
else:
|
||||||
|
scat.prepare_partial(action, verbose=verbose)
|
||||||
|
actionstring = '.TM' if action else '.TE'
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
sbtime = _time_b(verbose, step='Solving the scattering problem, chunk %d'%chunki+actionstring)
|
||||||
|
if pargs.nosuffix:
|
||||||
|
outfile = pargs.output_prefix + actionstring + (
|
||||||
|
('.%03d' % chunki) if chunkn > 1 else '')
|
||||||
|
else:
|
||||||
|
outfile = '%s_%dx%d_%.0fnmx%.0fnm_%.4f%s%s.npz' % (
|
||||||
|
pargs.output_prefix, Nx, Ny, dx/1e-9, dy/1e-9,
|
||||||
|
eVfreq, actionstring,
|
||||||
|
(".%03d" % chunki) if chunkn > 1 else '')
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
klist2d = klist_full_2D[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
klistdir = klist_full_dir[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
'''
|
||||||
|
The following loop is a fuckup that has its roots in the fact that
|
||||||
|
the function qpms.get_π̃τ̃_y1 in qpms_p.py is not vectorized
|
||||||
|
(and consequently, neither is plane_pq_y.)
|
||||||
|
|
||||||
|
And Scattering_2D_zsym.scatter_partial is not vectorized, either.
|
||||||
|
'''
|
||||||
|
if action == 0 or action is None:
|
||||||
|
xresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
yresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
if action == 1 or action is None:
|
||||||
|
zresult = np.full((klist.shape[0], N, nelem), np.nan, dtype=complex)
|
||||||
|
for i in range(klist.shape[0]):
|
||||||
|
if math.isnan(klist[i,2]):
|
||||||
|
if(verbose):
|
||||||
|
print("%d. momentum %s invalid (k_0=%f), skipping" % (i, str(klist[i]),k_0))
|
||||||
|
continue
|
||||||
|
kdir = klistdir[i]
|
||||||
|
phases = np.exp(-1j*np.sum(klist2d[i] * positions, axis=-1))
|
||||||
|
if action == 0 or action is None:
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, xu)).ravel()[TEč] * phases[:, nx]
|
||||||
|
xresult[i] = scat.scatter_partial(0, pq)
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, yu)).ravel()[TEč] * phases[:, nx]
|
||||||
|
yresult[i] = scat.scatter_partial(0, pq)
|
||||||
|
if action == 1 or action is None:
|
||||||
|
pq = np.array(qpms.plane_pq_y(lMax, kdir, zu)).ravel()[TMč] * phases[:, nx]
|
||||||
|
zresult[i] = scat.scatter_partial(1, pq)
|
||||||
|
_time_e(sbtime, verbose, step='Solving the scattering problem, chunk %d'%chunki+actionstring)
|
||||||
|
|
||||||
|
metadata[()]['chunki'] = chunki
|
||||||
|
if action is None:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_x=xresult,
|
||||||
|
ab_y=yresult,
|
||||||
|
ab_z=zresult
|
||||||
|
)
|
||||||
|
elif action == 0:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_x=xresult,
|
||||||
|
ab_y=yresult,
|
||||||
|
)
|
||||||
|
elif action == 1:
|
||||||
|
np.savez(outfile, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
positions=positions,
|
||||||
|
ab_z=zresult
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if outfile:
|
||||||
|
subprocess.run(['scp', outfile, scp_dest])
|
||||||
|
scat.forget_matrices() # free memory in case --serial was used
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
|
@ -0,0 +1,340 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
'''
|
||||||
|
Bulk SVD mode computation for compact scatterer 2D lattices
|
||||||
|
'''
|
||||||
|
|
||||||
|
__TODOs__ = '''
|
||||||
|
BIG TODO: Use more efficient way to calculate the interaction sums: perhaps some customized Ewald-type summation?
|
||||||
|
|
||||||
|
Small TODOs:
|
||||||
|
- Implement a more user-friendly way to define the lattice base vectors and positions of the particles.
|
||||||
|
cf. https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string/2371789
|
||||||
|
- low priority: allow to perform some more custom operations on T-Matrix, using some kind of parsing from the previous point
|
||||||
|
- Autodetect symmetries
|
||||||
|
|
||||||
|
'''
|
||||||
|
import argparse, re, random, string
|
||||||
|
import subprocess
|
||||||
|
from scipy.constants import hbar, e as eV, pi, c
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
def make_action_sharedlist(opname, listname):
|
||||||
|
class opAction(argparse.Action):
|
||||||
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
if (not hasattr(args, listname)) or getattr(args, listname) is None:
|
||||||
|
setattr(args, listname, list())
|
||||||
|
getattr(args,listname).append((opname, values))
|
||||||
|
return opAction
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
#TODO? použít type=argparse.FileType('r') ?
|
||||||
|
#TODO create some user-friendlier way to define lattice vectors, cf. https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string/2371789
|
||||||
|
parser.add_argument('--lattice_base', nargs=4, action='store', type=float, required=True, help='Lattice basis vectors x1, y1, x2, y2')
|
||||||
|
parser.add_argument('--particle', '-p', nargs='+', action=make_action_sharedlist('particle', 'particlespec'), help='Particle label, coordinates x,y, and (optionally) path to the T-Matrix.')
|
||||||
|
parser.add_argument('--TMatrix', '-t', nargs='+', action=make_action_sharedlist('TMatrix_path', 'particlespec'), help='Path to TMatrix file')
|
||||||
|
#parser.add_argument('--griddir', action='store', required=True, help='Path to the directory with precalculated translation operators')
|
||||||
|
parser.add_argument('--output_prefix', action='store', required=True, help='Prefix to the npz output (will be appended frequency, hexside and chunkno)')
|
||||||
|
#sizepar = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
#DEL parser.add_argument('--hexside', action='store', type=float, required=True, help='Lattice hexagon size length')
|
||||||
|
parser.add_argument('--plot_TMatrix', action='store_true', help='Visualise TMatrix on the first page of the output')
|
||||||
|
#parser.add_argument('--SVD_output', action='store', help='Path to output singular value decomposition result')
|
||||||
|
parser.add_argument('--maxlayer', action='store', type=int, default=100, help='How far to sum the lattice points to obtain the dispersion')
|
||||||
|
parser.add_argument('--scp_to', action='store', metavar='N', type=str, help='SCP the output files to a given destination')
|
||||||
|
parser.add_argument('--background_permittivity', action='store', type=float, default=1., help='Background medium relative permittivity (default 1)')
|
||||||
|
parser.add_argument('--eVfreq', action='store', required=True, type=float, help='Frequency in eV')
|
||||||
|
parser.add_argument('--kdensity', '--k_density', action='store', type=int, default=33, help='Number of k-points per x-axis segment FIXME DESCRIPTION')
|
||||||
|
parser.add_argument('--bz_coverage', action='store', type=float, default=1., help='Brillouin zone coverage in relative length (default 1 for whole 1. BZ)')
|
||||||
|
parser.add_argument('--bz_edge_width', action='store', type=float, default=0., help='Width of the more densely covered belt along the 1. BZ edge in relative lengths')
|
||||||
|
parser.add_argument('--bz_edge_factor', action='store', type=float, default=8., help='Relative density of the belt along the 1. BZ edge w.r.t. k_density (default==8)')
|
||||||
|
parser.add_argument('--bz_edge_twoside', action='store_true', help='Compute also the parts of the densely covered edge belt outside the 1. BZ')
|
||||||
|
parser.add_argument('--bz_corner_width', action='store', type=float, default=0., help='Size of the more densely covered subcell along the 1. BZ corners in relative lengths')
|
||||||
|
parser.add_argument('--bz_corner_factor', action='store', type=float, default=16., help='Relative density of the subcell along the 1. BZ corner w.r.t. k_density (default==16)')
|
||||||
|
parser.add_argument('--bz_corner_twoside', action='store_true', help='Compute also the parts of the densely covered subcell outside the 1. BZ')
|
||||||
|
|
||||||
|
parser.add_argument('--chunklen', action='store', type=int, default=1000, help='Number of k-points per output file (default 1000)')
|
||||||
|
parser.add_argument('--lMax', action=make_action_sharedlist('lMax', 'particlespec'), nargs=+, help='Override lMax from the TMatrix file')
|
||||||
|
#TODO some more sophisticated x axis definitions
|
||||||
|
parser.add_argument('--gaussian', action='store', type=float, metavar='σ', help='Use a gaussian envelope for weighting the interaction matrix contributions (depending on the distance), measured in unit cell lengths (?) FIxME).')
|
||||||
|
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
|
||||||
|
popgrp=parser.add_argument_group(title='Operations')
|
||||||
|
popgrp.add_argument('--tr', dest='ops', nargs='+', action=make_action_sharedlist('tr', 'ops'), default=list()) # the default value for dest can be set once
|
||||||
|
popgrp.add_argument('--sym', dest='ops', nargs='+', action=make_action_sharedlist('sym', 'ops'))
|
||||||
|
#popgrp.add_argument('--mult', dest='ops', nargs=3, metavar=('INCSPEC', 'SCATSPEC', 'MULTIPLIER'), action=make_action_sharedlist('mult', 'ops'))
|
||||||
|
#popgrp.add_argument('--multl', dest='ops', nargs=3, metavar=('INCL[,INCL,...]', 'SCATL[,SCATL,...]', 'MULTIPLIER'), action=make_action_sharedlist('multl', 'ops'))
|
||||||
|
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
|
||||||
|
pargs=parser.parse_args()
|
||||||
|
print(pargs)
|
||||||
|
|
||||||
|
exit(0) ###
|
||||||
|
|
||||||
|
maxlayer=pargs.maxlayer
|
||||||
|
#DEL hexside=pargs.hexside
|
||||||
|
eVfreq = pargs.eVfreq
|
||||||
|
freq = eVfreq*eV/hbar
|
||||||
|
verbose=pargs.verbose
|
||||||
|
|
||||||
|
#DEL TMatrix_file = pargs.TMatrix
|
||||||
|
|
||||||
|
epsilon_b = pargs.background_permittivity #2.3104
|
||||||
|
gaussianSigma = pargs.gaussian if pargs.gaussian else None # hexside * 222 / 7
|
||||||
|
interpfreqfactor = pargs.frequency_multiplier
|
||||||
|
scp_dest = pargs.scp_to if pargs.scp_to else None
|
||||||
|
kdensity = pargs.kdensity
|
||||||
|
chunklen = pargs.chunklen
|
||||||
|
|
||||||
|
#### Nanoparticle position and T-matrix path parsing ####
|
||||||
|
TMatrix_paths = dict()
|
||||||
|
lMax_overrides = dict()
|
||||||
|
default_TMatrix_path = None
|
||||||
|
default_lMax_override = None
|
||||||
|
if not any((arg_type == 'particle') in (arg_type, arg_content) for in pargs.particlespec):
|
||||||
|
# no particles positions given: suppose only one per unit cell, in the cell origin
|
||||||
|
positions = {None: (0.0)}
|
||||||
|
else:
|
||||||
|
positions = dict()
|
||||||
|
for arg_type, arg_content in pargs.particlespec:
|
||||||
|
if arg_type == 'particle' # --particle option
|
||||||
|
if 3 <= len(arg_content) <= 4:
|
||||||
|
try:
|
||||||
|
positions[arg_content[0]] = (float(arg_content[1]), float(arg_content[2]))
|
||||||
|
except ValueError as e:
|
||||||
|
e.args += ("second and third argument of --particle must be valid floats, given: ", arg_content)
|
||||||
|
raise
|
||||||
|
if len(arg_content == 4):
|
||||||
|
if arg_content[0] in TMatrix_paths:
|
||||||
|
warnings.warn('T-matrix path for particle \'%s\' already specified.'
|
||||||
|
'Overriding with the last value.' % arg_content[0], SyntaxWarning)
|
||||||
|
TMatrix_paths[arg_content[0]] = arg_content[3]
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError("--particle expects 3 or 4 arguments, %d given: " % len(arg_content), arg_content)
|
||||||
|
elif arg_type == 'TMatrix_path': # --TMatrix option
|
||||||
|
if len(arg_content) == 1: # --TMatrix default_path
|
||||||
|
if default_TMatrix_path is not None:
|
||||||
|
warnings.warn('Default T-matrix path already specified. Overriding with the last value.', SyntaxWarning)
|
||||||
|
default_TMatrix_path = arg_content[0]
|
||||||
|
elif len(arg_content) > 1: # --TMatrix label [label2 [...]] path
|
||||||
|
for label in arg_content[:-1]:
|
||||||
|
if label in TMatrix_paths.keys():
|
||||||
|
warnings.warn('T-matrix path for particle \'%s\' already specified.'
|
||||||
|
'Overriding with the last value.' % label, SyntaxWarning)
|
||||||
|
TMatrix_paths[label] = arg_content[-1]
|
||||||
|
elif arg_type == 'lMax': # --lMax option
|
||||||
|
if len(arg_content) == 1: # --lMax default_lmax_override
|
||||||
|
if default_lMax_override is not None:
|
||||||
|
warnings.warn('Default lMax override value already specified. Overriding the last value.', SyntaxWarning)
|
||||||
|
default_lMax_override = int(arg_content[-1])
|
||||||
|
else:
|
||||||
|
for label in arg_content[:-1]:
|
||||||
|
if label in lMax_overrides.keys:
|
||||||
|
warnings.warn('lMax override for particle \'%s\' already specified.'
|
||||||
|
'overriding with the last value.' % label, SyntaxWarning)
|
||||||
|
lMax_overrides[label] = int(arg_content[-1])
|
||||||
|
else: assert False, 'unknown option type'
|
||||||
|
# Check the info from positions and TMatrix_paths and lMax_overrides
|
||||||
|
if not set(TMatrix_paths.keys()) <= set(positions.keys()):
|
||||||
|
raise ValueError("T-Matrix path(s) for particle(s) labeled %s was given, but not their positions"
|
||||||
|
% str(set(TMatrix_paths.keys()) - set(positions.keys())))
|
||||||
|
if not set(lMax_overrides.keys()) <= set(positions.keys()):
|
||||||
|
raise ValueError("lMax override(s) for particle(s) labeled %s was given, but not their positions"
|
||||||
|
%str(set(lMax_overrides.keys()) - set(positions.keys())))
|
||||||
|
if (set(TMatrix_paths.keys()) != set(positions.keys())) and default_TMatrix_path is None:
|
||||||
|
raise ValueError("Position(s) of particles(s) labeled %s was given without their T-matrix"
|
||||||
|
" and no default T-matrix was specified"
|
||||||
|
% str(set(positions.keys()) - set(TMatrix_paths_keys())))
|
||||||
|
for path in TMatrix_paths.values():
|
||||||
|
if not os.path.exists(path):
|
||||||
|
raise ValueError("Cannot access T-matrix file %s. Does it exist?" % path)
|
||||||
|
|
||||||
|
# Assign (pre-parse) the T-matrix operations to individual particles
|
||||||
|
ops = dict()
|
||||||
|
for label in positions.keys(): ops[label] = list()
|
||||||
|
for optype, arg_content in pargs.ops:
|
||||||
|
# if, no label given, apply to all, otherwise on the specifield particles
|
||||||
|
for label in (positions.keys() if len(arg_content) == 1 else arg_content[:-1]):
|
||||||
|
try:
|
||||||
|
ops[label].append((optype, arg_content[-1]))
|
||||||
|
except KeyError as e:
|
||||||
|
e.args += 'Specified operation on undefined particle labeled \'%s\'' % label
|
||||||
|
raise
|
||||||
|
|
||||||
|
print(sys.stderr, "ops: ", ops) #DEBUG
|
||||||
|
|
||||||
|
#### Collect all the info about the particles / their T-matrices into one list ####
|
||||||
|
# Enumerate and assign all the _different_ T-matrices (without any intelligent group-theory checking, though)
|
||||||
|
TMatrix_specs = dict((spec, number)
|
||||||
|
for (number, spec) in enumerate(set(
|
||||||
|
(lMax_overrides[label] if label in lMax_overrides.keys() else None,
|
||||||
|
TMatrix_paths[label],
|
||||||
|
tuple(ops[label]))
|
||||||
|
for label in positions.keys()
|
||||||
|
)))
|
||||||
|
# particles_specs contains (label, (xpos, ypos), tmspec_index per element)
|
||||||
|
particles_specs = [(label, positions(label),
|
||||||
|
TMatrix_specs[(lMax_overrides[label] if label in lMax_overrides.keys() else None,
|
||||||
|
TMatrix_paths[label],
|
||||||
|
tuple(ops[label]))]
|
||||||
|
) for label in positions.keys()]
|
||||||
|
|
||||||
|
# -----------------finished basic CLI parsing (except for op arguments) ------------------
|
||||||
|
from qpms.timetrack import _time_b, _time_e
|
||||||
|
btime=_time_b(verbose)
|
||||||
|
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
import os, sys, warnings, math
|
||||||
|
from scipy import interpolate
|
||||||
|
nx = None
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
|
||||||
|
# specifikace T-matice zde
|
||||||
|
cdn = c/ math.sqrt(epsilon_b)
|
||||||
|
TMatrices_orig, freqs_orig, freqs_weirdunits_orig, lMaxTM = qpms.loadScuffTMatrices(TMatrix_file)
|
||||||
|
lMax = lMaxTM
|
||||||
|
if pargs.lMax:
|
||||||
|
lMax = pargs.lMax if pargs.lMax else lMaxTM
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
if pargs.lMax: #force commandline specified lMax
|
||||||
|
TMatrices_orig = TMatrices_orig[...,0:nelem,:,0:nelem]
|
||||||
|
|
||||||
|
TMatrices = np.array(np.broadcast_to(TMatrices_orig[:,nx,:,:,:,:],(len(freqs_orig),2,2,nelem,2,nelem)) )
|
||||||
|
|
||||||
|
#TMatrices[:,:,:,:,:,ny==3] *= factor13inc
|
||||||
|
#TMatrices[:,:,:,ny==3,:,:] *= factor13scat
|
||||||
|
xfl = qpms.xflip_tyty(lMax)
|
||||||
|
yfl = qpms.yflip_tyty(lMax)
|
||||||
|
zfl = qpms.zflip_tyty(lMax)
|
||||||
|
c2rot = qpms.apply_matrix_left(qpms.yflip_yy(3),qpms.xflip_yy(3),-1)
|
||||||
|
|
||||||
|
reCN = re.compile('(\d*)C(\d+)')
|
||||||
|
#TODO C nekonečno
|
||||||
|
|
||||||
|
for op in ops:
|
||||||
|
if op[0] == 'all':
|
||||||
|
targets = (0,1)
|
||||||
|
elif isinstance(op[0],int):
|
||||||
|
targets = (op[0],)
|
||||||
|
else:
|
||||||
|
targets = op[0]
|
||||||
|
|
||||||
|
if op[1] == 'sym':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1)))/2
|
||||||
|
elif op[2] == 'C2': # special case of the latter
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = (TMatrices[:,t] + qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1))/2
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
for i in range(rotN):
|
||||||
|
rotangle = 2*np.pi*i / rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax,np.array([0,0,-rotangle]))
|
||||||
|
TMatrix_contribs[i] = qpms.apply_matrix_left(rot,qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
TMatrices[:,t] = np.sum(TMatrix_contribs, axis=0) / rotN
|
||||||
|
else:
|
||||||
|
raise ValueError('\'%d\' is not an implemented symmetry operation' % op[2])
|
||||||
|
elif op[1] == 'tr':
|
||||||
|
mCN = reCN.match(op[2]) # Fuck van Rossum for not having assignments inside expressions
|
||||||
|
if op[2] == 'σ_z':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(zfl,qpms.apply_ndmatrix_left(zfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_y':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(yfl,qpms.apply_ndmatrix_left(yfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'σ_x':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_ndmatrix_left(xfl,qpms.apply_ndmatrix_left(xfl, TMatrices[:,t], (-4,-3)),(-2,-1))
|
||||||
|
elif op[2] == 'C2':
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(c2rot,qpms.apply_matrix_left(c2rot, TMatrices[:,t], -3),-1)
|
||||||
|
elif mCN:
|
||||||
|
rotN = int(mCN.group(2))
|
||||||
|
power = int(mCN.group(1)) if mCN.group(1) else 1
|
||||||
|
TMatrix_contribs = np.empty((rotN,TMatrices.shape[0],2,nelem,2,nelem), dtype=np.complex_)
|
||||||
|
for t in targets:
|
||||||
|
rotangle = 2*np.pi*power/rotN
|
||||||
|
rot = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,rotangle]))
|
||||||
|
rotinv = qpms.WignerD_yy_fromvector(lMax, np.array([0,0,-rotangle]))
|
||||||
|
TMatrices[:,t] = qpms.apply_matrix_left(rot, qpms.apply_matrix_left(rotinv, TMatrices[:,t], -3),-1)
|
||||||
|
else:
|
||||||
|
raise ValueError('\'%d\' is not an implemented T-matrix transformation operation' % op[2])
|
||||||
|
elif op[1] == 'copy':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'mult':
|
||||||
|
raise # not implemented
|
||||||
|
elif op[1] == 'multl':
|
||||||
|
incy = np.full((nelem,), False, dtype=bool)
|
||||||
|
for incl in op[2][0].split(','):
|
||||||
|
l = int(incl)
|
||||||
|
incy += (l == ny)
|
||||||
|
scaty = np.full((nelem,), False, dtype=bool)
|
||||||
|
for scatl in op[2][1].split(','):
|
||||||
|
l = int(scatl)
|
||||||
|
scaty += (l == ny)
|
||||||
|
for t in targets:
|
||||||
|
TMatrices[np.ix_(np.arange(TMatrices.shape[0]),np.array([t]),np.array([0,1]),scaty,np.array([0,1]),incy)] *= float(op[2][2])
|
||||||
|
else:
|
||||||
|
raise #unknown operation; should not happen
|
||||||
|
|
||||||
|
TMatrices_interp = interpolate.interp1d(freqs_orig*interpfreqfactor, TMatrices, axis=0, kind='linear',fill_value="extrapolate")
|
||||||
|
|
||||||
|
klist_full = qpms.generate_trianglepoints(kdensity, v3d=True, include_origin=True)*3*math.pi/(3*kdensity*hexside)
|
||||||
|
TMatrices_om = TMatrices_interp(freq)
|
||||||
|
|
||||||
|
chunkn = math.ceil(klist_full.shape[0] / chunklen)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print('Evaluating %d k-points in %d chunks' % (klist_full.shape[0], chunkn), file = sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
metadata = np.array({
|
||||||
|
'lMax' : lMax,
|
||||||
|
'maxlayer' : maxlayer,
|
||||||
|
'gaussianSigma' : gaussianSigma,
|
||||||
|
'epsilon_b' : epsilon_b,
|
||||||
|
'hexside' : hexside,
|
||||||
|
'chunkn' : chunkn,
|
||||||
|
'TMatrix_file' : TMatrix_file,
|
||||||
|
'ops' : ops,
|
||||||
|
})
|
||||||
|
|
||||||
|
for chunki in range(chunkn):
|
||||||
|
svdout = '%s_%dnm_%.4f_c%03d.npz' % (pargs.output_prefix, hexside/1e-9, eVfreq, chunki)
|
||||||
|
|
||||||
|
klist = klist_full[chunki * chunklen : (chunki + 1) * chunklen]
|
||||||
|
|
||||||
|
svdres = qpms.hexlattice_zsym_getSVD(lMax=lMax, TMatrices_om=TMatrices_om, epsilon_b=epsilon_b, hexside=hexside, maxlayer=maxlayer,
|
||||||
|
omega=freq, klist=klist, gaussianSigma=gaussianSigma, onlyNmin=False, verbose=verbose)
|
||||||
|
|
||||||
|
#((svUfullTElist, svSfullTElist, svVfullTElist), (svUfullTMlist, svSfullTMlist, svVfullTMlist)) = svdres
|
||||||
|
|
||||||
|
np.savez(svdout, omega = freq, klist = klist,
|
||||||
|
metadata=metadata,
|
||||||
|
uTE = svdres[0][0],
|
||||||
|
vTE = svdres[0][2],
|
||||||
|
sTE = svdres[0][1],
|
||||||
|
uTM = svdres[1][0],
|
||||||
|
vTM = svdres[1][2],
|
||||||
|
sTM = svdres[1][1],
|
||||||
|
|
||||||
|
)
|
||||||
|
svdres=None
|
||||||
|
|
||||||
|
if scp_dest:
|
||||||
|
if svdout:
|
||||||
|
subprocess.run(['scp', svdout, scp_dest])
|
||||||
|
|
||||||
|
_time_e(btime, verbose)
|
||||||
|
#print(time.strftime("%H.%M:%S",time.gmtime(time.time()-begtime)))
|
|
@ -0,0 +1,35 @@
|
||||||
|
import qpms
|
||||||
|
import numpy as np
|
||||||
|
from numpy import newaxis as nx
|
||||||
|
import math
|
||||||
|
import cmath
|
||||||
|
import os
|
||||||
|
from scipy.constants import c, e as eV, hbar
|
||||||
|
s3 = math.sqrt(3)
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("omega")
|
||||||
|
#parser.add_argument("maxlayer")
|
||||||
|
args = parser.parse_args()
|
||||||
|
omega_eV = float(args.omega)
|
||||||
|
|
||||||
|
print(omega_eV)
|
||||||
|
|
||||||
|
epsilon_b = 2.3104
|
||||||
|
hexside = 375e-9
|
||||||
|
lMax = 3
|
||||||
|
maxlayer = 222
|
||||||
|
my, ny = qpms.get_mn_y(lMax)
|
||||||
|
nelem = len(my)
|
||||||
|
|
||||||
|
omega = omega_eV * eV / hbar
|
||||||
|
|
||||||
|
k_0 = omega * math.sqrt(epsilon_b) / c
|
||||||
|
|
||||||
|
output_prefix = '/tmp/diracpoints-newdata2/%d/' % maxlayer
|
||||||
|
|
||||||
|
os.makedirs(output_prefix, exist_ok=True)
|
||||||
|
qpms.hexlattice_precalc_AB_save(file=output_prefix+str(omega_eV), lMax=lMax, k_hexside=k_0*hexside,
|
||||||
|
maxlayer=maxlayer, savepointinfo=True)
|
|
@ -1,128 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq'])
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-s", "--singular_values", type=int, default=10, help="Number of singular values to plot")
|
|
||||||
ap.add_argument("--D2", action='store_true', help="Use D2h symmetry even if the x and y periods are equal")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
#Important! The particles are supposed to be of D2h/D4h symmetry
|
|
||||||
thegroup = 'D4h' if px == py and not a.D2 else 'D2h'
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_m%s_bg%s_f(%g..%g..%g)eV_L%d_SVGamma" % (
|
|
||||||
particlestr, px*1e9, py*1e9, str(a.material), str(a.background), *(a.eV_seq), a.lMax)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# not used; TODO:
|
|
||||||
irrep_labels = {"B2''":"$B_2''$",
|
|
||||||
"B2'":"$B_2'$",
|
|
||||||
"A1''":"$A_1''$",
|
|
||||||
"A1'":"$A_1'$",
|
|
||||||
"A2''":"$A_2''$",
|
|
||||||
"B1''":"$B_1''$",
|
|
||||||
"A2'":"$A_2'$",
|
|
||||||
"B1'":"$B_1'$",
|
|
||||||
"E'":"$E'$",
|
|
||||||
"E''":"$E''$",}
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = [0]
|
|
||||||
orig_y = [0]
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)
|
|
||||||
|
|
||||||
omegas = ap.omegas
|
|
||||||
|
|
||||||
logging.info("%d frequencies from %g to %g eV" % (len(omegas), omegas[0]/eh, omegas[-1]/eh))
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
nelem = len(bspec)
|
|
||||||
# The parameters here should probably be changed (needs a better qpms_c.Particle implementation)
|
|
||||||
pp = Particle(orig_xy[0][0], ap.tmgen, bspec=bspec)
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create([pp], ap.background_emg, omegas[0], latticebasis=ap.direct_basis)
|
|
||||||
k = np.array([0.,0.,0])
|
|
||||||
# Auxillary finite scattering system for irrep decomposition, quite a hack
|
|
||||||
ss1, ssw1 = ScatteringSystem.create([pp], ap.background_emg, omegas[0],sym=FinitePointGroup(point_group_info[thegroup]))
|
|
||||||
|
|
||||||
wavenumbers = np.empty(omegas.shape)
|
|
||||||
SVs = [None] * ss1.nirreps
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
SVs[iri] = np.empty(omegas.shape+(ss1.saecv_sizes[iri],))
|
|
||||||
for i, omega in enumerate(omegas):
|
|
||||||
ssw = ss(omega)
|
|
||||||
wavenumbers[i] = ssw.wavenumber.real
|
|
||||||
if ssw.wavenumber.imag:
|
|
||||||
warnings.warn("Non-zero imaginary wavenumber encountered")
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow; maybe not needed
|
|
||||||
ImTW = ssw.modeproblem_matrix_full(k)
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
if ss1.saecv_sizes[iri] == 0:
|
|
||||||
continue
|
|
||||||
ImTW_packed = ss1.pack_matrix(ImTW, iri)
|
|
||||||
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
cc = plt.rcParams['axes.prop_cycle']()
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
cargs = next(cc)
|
|
||||||
nlines = min(a.singular_values, ss1.saecv_sizes[iri])
|
|
||||||
for i in range(nlines):
|
|
||||||
ax.plot(omegas/eh, SVs[iri][:,-1-i],
|
|
||||||
label= None if i else irrep_labels[ss1.irrep_names[iri]],
|
|
||||||
**cargs)
|
|
||||||
ax.set_ylim([0,1.1])
|
|
||||||
ax.set_xlabel('$\hbar \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('Singular values')
|
|
||||||
ax.legend()
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='infiniterectlat-k0realfreqsvd.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
pi = math.pi
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
#ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
|
|
||||||
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.qpms_p import cart2sph, sph2cart, sph_loccart2cart, sph_loccart_basis
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
particlestr = ("sph" if a.height is None else "cyl") + ("_r%gnm" % (a.radius*1e9))
|
|
||||||
if a.height is not None: particlestr += "_h%gnm" % (a.height * 1e9)
|
|
||||||
defaultprefix = "%s_p%gnmx%gnm_m%s_bg%s_φ%g_θ(%g_%g)π_ψ%gπ_χ%gπ_f%s_L%d" % (
|
|
||||||
particlestr, px*1e9, py*1e9, str(a.material), str(a.background), a.phi/pi, np.amin(a.theta)/pi, np.amax(a.theta)/pi, a.psi/pi, a.chi/pi, ap.omega_descr, a.lMax)
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
#Particle positions
|
|
||||||
orig_x = [0]
|
|
||||||
orig_y = [0]
|
|
||||||
orig_xy = np.stack(np.meshgrid(orig_x,orig_y),axis=-1)
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
# The parameters here should probably be changed (needs a better qpms_c.Particle implementation)
|
|
||||||
pp = Particle(orig_xy[0][0], ap.tmgen, bspec=bspec)
|
|
||||||
par = [pp]
|
|
||||||
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(par, ap.background_emg, ap.allomegas[0], latticebasis = ap.direct_basis)
|
|
||||||
|
|
||||||
|
|
||||||
## Plane wave data
|
|
||||||
a.theta = np.array(a.theta)
|
|
||||||
dir_sph_list = np.stack((np.broadcast_to(1, a.theta.shape), a.theta, np.broadcast_to(a.phi, a.theta.shape)), axis=-1)
|
|
||||||
sψ, cψ = math.sin(a.psi), math.cos(a.psi)
|
|
||||||
sχ, cχ = math.sin(a.chi), math.cos(a.chi)
|
|
||||||
E_sph = (0., cψ*cχ + 1j*sψ*sχ, sψ*cχ + 1j*cψ*sχ)
|
|
||||||
|
|
||||||
dir_cart_list = sph2cart(dir_sph_list)
|
|
||||||
E_cart_list = sph_loccart2cart(E_sph, dir_sph_list)
|
|
||||||
|
|
||||||
nfreq = len(ap.allomegas)
|
|
||||||
ndir = len(dir_sph_list)
|
|
||||||
|
|
||||||
k_cart_arr = np.empty((nfreq, ndir, 3), dtype=float)
|
|
||||||
wavenumbers = np.empty((nfreq,), dtype=float)
|
|
||||||
|
|
||||||
σ_ext_arr = np.empty((nfreq,ndir), dtype=float)
|
|
||||||
σ_scat_arr = np.empty((nfreq,ndir), dtype=float)
|
|
||||||
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow
|
|
||||||
for i, omega in enumerate(ap.allomegas):
|
|
||||||
if i != 0:
|
|
||||||
ssw = ss(omega)
|
|
||||||
if ssw.wavenumber.imag != 0:
|
|
||||||
warnings.warn("The background medium wavenumber has non-zero imaginary part. Don't expect meaningful results for cross sections.")
|
|
||||||
wavenumber = ssw.wavenumber.real
|
|
||||||
wavenumbers[i] = wavenumber
|
|
||||||
|
|
||||||
k_sph_list = np.array(dir_sph_list, copy=True)
|
|
||||||
k_sph_list[:,0] = wavenumber
|
|
||||||
|
|
||||||
k_cart_arr[i] = sph2cart(k_sph_list)
|
|
||||||
|
|
||||||
|
|
||||||
for j in range(ndir):
|
|
||||||
k_cart = k_cart_arr[i,j]
|
|
||||||
blochvector = (k_cart[0], k_cart[1], 0)
|
|
||||||
# the following two could be calculated only once, but probably not a big deal
|
|
||||||
LU = ssw.scatter_solver(k=blochvector)
|
|
||||||
ã = ss.planewave_full(k_cart=k_cart, E_cart=E_cart_list[j])
|
|
||||||
Tã = ssw.apply_Tmatrices_full(ã)
|
|
||||||
f = LU(Tã)
|
|
||||||
|
|
||||||
σ_ext_arr[i,j] = -np.vdot(ã, f).real/wavenumber**2
|
|
||||||
translation_matrix = ssw.translation_matrix_full(blochvector=blochvector) + np.eye(ss.fecv_size)
|
|
||||||
σ_scat_arr[i,j] = np.vdot(f,np.dot(translation_matrix, f)).real/wavenumber**2
|
|
||||||
|
|
||||||
σ_abs_arr = σ_ext_arr - σ_scat_arr
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, dir_sph=dir_sph_list, k_cart = k_cart_arr, omega = ap.allomegas, E_cart = E_cart_list, wavenumbers= wavenumbers, σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from scipy.interpolate import griddata
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
ipm = 'nearest'
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
if False: #len(ap.omega_ranges) != 0:
|
|
||||||
# angle plot ---------------------------------
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = max(np.amax(σ_ext_arr), np.amax(σ_scat_arr), np.amax(σ_abs_arr))
|
|
||||||
vmin = min(np.amin(σ_ext_arr), np.amin(σ_scat_arr), np.amin(σ_abs_arr))
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_ext_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
ax.pcolormesh(a.theta, ap.allomegas/eh, σ_scat_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
im = ax.pcolormesh(a.theta, ap.allomegas/eh, σ_abs_arr, vmin=vmin, vmax=vmax)
|
|
||||||
ax.set_xlabel('$\\theta$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
if len(ap.omega_ranges) != 0:
|
|
||||||
# "k-space" plot -----------------------------
|
|
||||||
domega = np.amin(np.diff(ap.allomegas))
|
|
||||||
dsintheta = np.amin(abs(np.diff(sintheta)))
|
|
||||||
dk = dsintheta * wavenumbers[0]
|
|
||||||
|
|
||||||
# target image grid
|
|
||||||
grid_y, grid_x = np.mgrid[ap.allomegas[0] : ap.allomegas[-1] : domega, np.amin(sintheta) * wavenumbers[-1] : np.amax(sintheta) * wavenumbers[-1] : dk]
|
|
||||||
imextent = (np.amin(sintheta) * wavenumbers[-1] / 1e6, np.amax(sintheta) * wavenumbers[-1] / 1e6, ap.allomegas[0] / eh, ap.allomegas[-1] / eh)
|
|
||||||
|
|
||||||
# source coordinates for griddata
|
|
||||||
ktheta = sintheta[None, :] * wavenumbers[:, None]
|
|
||||||
omegapoints = np.broadcast_to(ap.allomegas[:, None], ktheta.shape)
|
|
||||||
points = np.stack( (ktheta.flatten(), omegapoints.flatten()), axis = -1)
|
|
||||||
|
|
||||||
fig = plt.figure(figsize=(210/25.4, 297/25.4))
|
|
||||||
vmax = np.amax(σ_ext_arr)
|
|
||||||
|
|
||||||
ax = fig.add_subplot(311)
|
|
||||||
grid_z = griddata(points, σ_ext_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{ext}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(312)
|
|
||||||
grid_z = griddata(points, σ_scat_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{scat}$')
|
|
||||||
|
|
||||||
ax = fig.add_subplot(313)
|
|
||||||
grid_z = griddata(points, σ_abs_arr.flatten(), (grid_x, grid_y), method = ipm)
|
|
||||||
im = ax.imshow(grid_z, extent = imextent, origin = 'lower', vmin = 0, vmax = vmax, aspect = 'auto', interpolation='none')
|
|
||||||
ax.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
|
|
||||||
ax.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
|
|
||||||
ax.set_title('$\\sigma_\\mathrm{abs}$')
|
|
||||||
|
|
||||||
fig.subplots_adjust(right=0.8)
|
|
||||||
fig.colorbar(im, cax = fig.add_axes([0.85, 0.15, 0.05, 0.7]))
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
|
|
||||||
for omega in ap.omega_singles:
|
|
||||||
i = np.searchsorted(ap.allomegas, omega)
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
fig.suptitle("%g eV" % (omega / eh))
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
sintheta = np.sin(a.theta)
|
|
||||||
ax.plot(sintheta, σ_ext_arr[i]*1e12,label='$\sigma_\mathrm{ext}$')
|
|
||||||
ax.plot(sintheta, σ_scat_arr[i]*1e12, label='$\sigma_\mathrm{scat}$')
|
|
||||||
ax.plot(sintheta, σ_abs_arr[i]*1e12, label='$\sigma_\mathrm{abs}$')
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel('$\sin\\theta$')
|
|
||||||
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
|
|
||||||
|
|
||||||
pdf.savefig(fig)
|
|
||||||
plt.close(fig)
|
|
||||||
annotate_pdf_metadata(pdf)
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['const_real_background', 'lattice2d', 'multi_particle']) # TODO general analytical background
|
|
||||||
|
|
||||||
ap.add_argument("-k", nargs=2, type=sfloat, required=True, help='k vector', metavar=('K_X', 'K_Y'))
|
|
||||||
ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
ap.add_argument("--rank-tol", type=float, required=False)
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-t", "--rank-tolerance", type=float, default=1e11)
|
|
||||||
ap.add_argument("-c", "--min-candidates", type=int, default=1, help='always try at least this many eigenvalue candidates, even if their SVs in the rank tests are lower than rank_tolerance')
|
|
||||||
ap.add_argument("-T", "--residual-tolerance", type=float, default=2.)
|
|
||||||
ap.add_argument("-N", type=int, default="150", help="Integration contour discretisation size")
|
|
||||||
|
|
||||||
|
|
||||||
#TODO alternative specification of the contour by center and half-axes
|
|
||||||
dospec = ap.add_argument_group("Eigenvalue search area by diffracted order specification", "Specification of eigenvalue search area by diffracted order number (requires constant real refractive index for background): the integration contour 'touches' the empty lattice band specified by -b, and its axis lying on the real axis reaches '-f'-way to the next diffractive order")
|
|
||||||
dospec.add_argument("-d", "--band-index", type=int, help="Argument's absolute value determines the empty lattice band order (counted from 1), -/+ determines whether the eigenvalues are searched below/above that empty lattice band.", required=True)
|
|
||||||
dospec.add_argument("-f", "--interval-factor", type=float, default=0.1, help="Relative length of the integration ellipse axis w.r.t. the interval between two empty lattice bands; this should be be less than 1.") #TODO check
|
|
||||||
dospec.add_argument("-i", "--imaginary-aspect-ratio", type=float, default=1., help="Aspect ratio of the integration ellipse (Im/Re); this should not exceed 1/interval_factor.")
|
|
||||||
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
|
|
||||||
a = ap.parse_args()
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
particlestr = "modes" # TODO particle string specifier or some hash, do this in argproc.py
|
|
||||||
defaultprefix = "%s_basis%gnm_%gnm__%gnm_%gnm_n%g_b%+d_k(%g_%g)um-1_cn%d" % (
|
|
||||||
particlestr, a1[0]*1e9, a1[1]*1e9, a2[0]*1e9, a2[1]*1e9, a.refractive_index, a.band_index, a.k[0]*1e-6, a.k[1]*1e-6, a.N)
|
|
||||||
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix
|
|
||||||
from qpms.qpms_c import Particle, ScatteringSystem, empty_lattice_modes_xy
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.constants import eV, hbar
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
def inside_ellipse(point_xy, centre_xy, halfaxes_xy):
|
|
||||||
x = point_xy[0] - centre_xy[0]
|
|
||||||
y = point_xy[1] - centre_xy[1]
|
|
||||||
ax = halfaxes_xy[0]
|
|
||||||
ay = halfaxes_xy[1]
|
|
||||||
return ((x/ax)**2 + (y/ay)**2) <= 1
|
|
||||||
|
|
||||||
beta = np.array(a.k)
|
|
||||||
|
|
||||||
if True: # TODO alternative specification of the contour by center and half-axes
|
|
||||||
empty_freqs = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, np.array([0,0]), 1)
|
|
||||||
empty_freqs = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, beta, (1+abs(a.band_index)) * empty_freqs[1])
|
|
||||||
|
|
||||||
# make the frequencies in the list unique
|
|
||||||
empty_freqs = list(empty_freqs)
|
|
||||||
i = 0
|
|
||||||
while i < len(empty_freqs) - 1:
|
|
||||||
if math.isclose(empty_freqs[i], empty_freqs[i+1], rel_tol=1e-13):
|
|
||||||
del empty_freqs[i+1]
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
logging.info("Empty freqs: %s", str(empty_freqs))
|
|
||||||
logging.info("Empty freqs (eV): %s", str([ff / eh for ff in empty_freqs]))
|
|
||||||
if a.band_index > 0:
|
|
||||||
top = empty_freqs[a.band_index]
|
|
||||||
bottom = empty_freqs[a.band_index - 1]
|
|
||||||
lebeta_om = bottom
|
|
||||||
else: # a.band_index < 0
|
|
||||||
top = empty_freqs[abs(a.band_index) - 1]
|
|
||||||
bottom = empty_freqs[abs(a.band_index) - 2] if abs(a.band_index) > 1 else 0.
|
|
||||||
lebeta_om = top
|
|
||||||
#print(top,bottom,lebeta_om)
|
|
||||||
freqradius = .5 * (top - bottom) * a.interval_factor
|
|
||||||
|
|
||||||
centfreq = bottom + freqradius if a.band_index > 0 else top - freqradius
|
|
||||||
if freqradius == 0:
|
|
||||||
raise ValueError("Integration contour radius is set to zero. Are you trying to look below the lowest empty lattice band at the gamma point?")
|
|
||||||
|
|
||||||
freqradius *= (1-1e-13) # to not totally touch the singularities
|
|
||||||
|
|
||||||
logging.info("Direct lattice basis: %s" % str(ap.direct_basis))
|
|
||||||
logging.info("Reciprocal lattice basis: %s" % str(ap.reciprocal_basis2pi))
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(ap.get_particles(), ap.background_emg, centfreq, latticebasis=ap.direct_basis)
|
|
||||||
|
|
||||||
logging.info("Finding eigenvalues around %s (= %s eV)" % (str(centfreq), str(centfreq/eh)))
|
|
||||||
logging.info("Real half-axis %s (= %s eV)" % (str(freqradius), str(freqradius/eh)))
|
|
||||||
logging.info("Imaginary half-axis %s (= %s eV)" % (str(freqradius*a.imaginary_aspect_ratio), str(freqradius*a.imaginary_aspect_ratio/eh)))
|
|
||||||
|
|
||||||
with qpms.pgsl_ignore_error(15):
|
|
||||||
res = ss.find_modes(centfreq, freqradius, freqradius * a.imaginary_aspect_ratio,
|
|
||||||
blochvector = a.k, contour_points = a.N, rank_tol = a.rank_tolerance,
|
|
||||||
res_tol = a.residual_tolerance, rank_min_sel = a.min_candidates)
|
|
||||||
|
|
||||||
logging.info("Eigenfrequencies found: %s" % str(res['eigval']))
|
|
||||||
logging.info("Eigenfrequencies found (eV): %s" % str(res['eigval'] / eh))
|
|
||||||
|
|
||||||
res['inside_contour'] = inside_ellipse((res['eigval'].real, res['eigval'].imag),
|
|
||||||
(centfreq.real, centfreq.imag), (freqradius, freqradius * a.imaginary_aspect_ratio))
|
|
||||||
|
|
||||||
#res['refractive_index_internal'] = [emg(om).n for om in res['eigval']]
|
|
||||||
|
|
||||||
#del res['omega'] If contour points are not needed...
|
|
||||||
#del res['ImTW'] # not if dbg=false anyway
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, empty_freqs=np.array(empty_freqs),
|
|
||||||
ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets,
|
|
||||||
ss_fullvec_psizes=ss.fullvec_psizes,
|
|
||||||
ss_bspecs_flat = np.concatenate(ss.bspecs),
|
|
||||||
ss_lattice_basis=ss.lattice_basis, ss_reciprocal_basis = ss.reciprocal_basis,
|
|
||||||
**res)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
if len(res['eigval']) == 0:
|
|
||||||
logging.info("No eigenvalues found; nothing to plot")
|
|
||||||
exit(1)
|
|
||||||
imcut = np.linspace(0, -freqradius)
|
|
||||||
recut1 = np.sqrt(lebeta_om**2+imcut**2) # incomplete Gamma-related cut
|
|
||||||
recut2 = np.sqrt((lebeta_om/2)**2-imcut**2) + lebeta_om/2 # odd-power-lilgamma-related cut
|
|
||||||
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111,)
|
|
||||||
#ax.plot(res['omega'].real/eh, res['omega'].imag/eh*1e3, ':') #res['omega'] not implemented in ScatteringSystem
|
|
||||||
ax.add_artist(matplotlib.patches.Ellipse((centfreq.real/eh, centfreq.imag/eh*1e3),
|
|
||||||
2*freqradius/eh, 2*freqradius*a.imaginary_aspect_ratio/eh*1e3, fill=False,
|
|
||||||
ls=':'))
|
|
||||||
ax.scatter(x=res['eigval'].real/eh, y=res['eigval'].imag/eh*1e3 , c = res['inside_contour']
|
|
||||||
)
|
|
||||||
ax.plot(recut1/eh, imcut/eh*1e3)
|
|
||||||
ax.plot(recut2/eh, imcut/eh*1e3)
|
|
||||||
for i,om in enumerate(res['eigval']):
|
|
||||||
ax.annotate(str(i), (om.real/eh, om.imag/eh*1e3))
|
|
||||||
xmin = np.amin(res['eigval'].real)/eh
|
|
||||||
xmax = np.amax(res['eigval'].real)/eh
|
|
||||||
xspan = xmax-xmin
|
|
||||||
ymin = np.amin(res['eigval'].imag)/eh*1e3
|
|
||||||
ymax = np.amax(res['eigval'].imag)/eh*1e3
|
|
||||||
yspan = ymax-ymin
|
|
||||||
ax.set_xlim([xmin-.1*xspan, xmax+.1*xspan])
|
|
||||||
ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan])
|
|
||||||
ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$')
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='lat2d_modes.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['background', 'lattice2d', 'multi_particle', 'omega_seq'])
|
|
||||||
|
|
||||||
ap.add_argument("-k", nargs=2, type=sfloat, required=True, help='k vector', metavar=('K_X', 'K_Y'))
|
|
||||||
ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
|
|
||||||
|
|
||||||
ap.add_argument("-g", "--little-group", type=str, default="trivial_g", help="Little group for subspace irrep classification", action="store")
|
|
||||||
|
|
||||||
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
|
|
||||||
ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
|
|
||||||
ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
|
|
||||||
ap.add_argument("-s", "--singular_values", type=int, default=10, help="Number of singular values to plot")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
#Important! The particles are supposed to be of D2h/D4h symmetry
|
|
||||||
# thegroup = 'D4h' if px == py and not a.D2 else 'D2h'
|
|
||||||
|
|
||||||
a1 = ap.direct_basis[0]
|
|
||||||
a2 = ap.direct_basis[1]
|
|
||||||
|
|
||||||
particlestr = "svdinterval" # TODO particle string specifier or some hash, do this in argproc.py
|
|
||||||
defaultprefix = "%s_basis%gnm_%gnm__%gnm_%gnm_f(%g..%g..%g)eV_k%g_%g" % (
|
|
||||||
particlestr, a1[0]*1e9, a1[1]*1e9, a2[0]*1e9, a2[1]*1e9, *(a.eV_seq), ap.k[0], ap.k[1])
|
|
||||||
logging.info("Default file prefix: %s" % defaultprefix)
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import qpms
|
|
||||||
import warnings
|
|
||||||
from qpms.cybspec import BaseSpec
|
|
||||||
from qpms.cytmatrices import CTMatrix, TMatrixGenerator
|
|
||||||
from qpms.qpms_c import Particle, pgsl_ignore_error, empty_lattice_modes_xy
|
|
||||||
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
|
|
||||||
from qpms.cycommon import DebugFlags, dbgmsg_enable
|
|
||||||
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
|
|
||||||
from qpms.symmetries import point_group_info
|
|
||||||
eh = eV/hbar
|
|
||||||
|
|
||||||
# not used; TODO:
|
|
||||||
irrep_labels = {"B2''":"$B_2''$",
|
|
||||||
"B2'":"$B_2'$",
|
|
||||||
"A1''":"$A_1''$",
|
|
||||||
"A1'":"$A_1'$",
|
|
||||||
"A2''":"$A_2''$",
|
|
||||||
"B1''":"$B_1''$",
|
|
||||||
"A2'":"$A_2'$",
|
|
||||||
"B1'":"$B_1'$",
|
|
||||||
"E'":"$E'$",
|
|
||||||
"E''":"$E''$",}
|
|
||||||
|
|
||||||
dbgmsg_enable(DebugFlags.INTEGRATION)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
omegas = ap.omegas
|
|
||||||
|
|
||||||
logging.info("%d frequencies from %g to %g eV" % (len(omegas), omegas[0]/eh, omegas[-1]/eh))
|
|
||||||
|
|
||||||
particles = ap.get_particles()
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create(particles, ap.background_emg, omegas[0], latticebasis=ap.direct_basis)
|
|
||||||
k = np.array([ap.k[0], ap.k[1], 0])
|
|
||||||
# Auxillary finite scattering system for irrep decomposition, quite a hack
|
|
||||||
ss1, ssw1 = ScatteringSystem.create(particles, ap.background_emg, omegas[0],sym=FinitePointGroup(point_group_info[ap.little_group]))
|
|
||||||
|
|
||||||
wavenumbers = np.empty(omegas.shape)
|
|
||||||
SVs = [None] * ss1.nirreps
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
SVs[iri] = np.empty(omegas.shape+(ss1.saecv_sizes[iri],))
|
|
||||||
for i, omega in enumerate(omegas):
|
|
||||||
ssw = ss(omega)
|
|
||||||
wavenumbers[i] = ssw.wavenumber.real
|
|
||||||
if ssw.wavenumber.imag:
|
|
||||||
warnings.warn("Non-zero imaginary wavenumber encountered")
|
|
||||||
with pgsl_ignore_error(15): # avoid gsl crashing on underflow; maybe not needed
|
|
||||||
ImTW = ssw.modeproblem_matrix_full(k)
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
ImTW_packed = ss1.pack_matrix(ImTW, iri)
|
|
||||||
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
|
|
||||||
|
|
||||||
outfile = defaultprefix + ".npz" if a.output is None else a.output
|
|
||||||
np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
|
|
||||||
)
|
|
||||||
logging.info("Saved to %s" % outfile)
|
|
||||||
|
|
||||||
|
|
||||||
if a.plot or (a.plot_out is not None):
|
|
||||||
import matplotlib
|
|
||||||
matplotlib.use('pdf')
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from matplotlib.backends.backend_pdf import PdfPages
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
cc = plt.rcParams['axes.prop_cycle']()
|
|
||||||
for iri in range(ss1.nirreps):
|
|
||||||
cargs = next(cc)
|
|
||||||
nlines = min(a.singular_values, ss1.saecv_sizes[iri])
|
|
||||||
for i in range(nlines):
|
|
||||||
ax.plot(omegas/eh, SVs[iri][:,-1-i],
|
|
||||||
label= None if i else irrep_labels.get(ss1.irrep_names[iri], ss1.irrep_names[iri]),
|
|
||||||
**cargs)
|
|
||||||
ax.set_ylim([0,1.1])
|
|
||||||
if hasattr(ap, "background_epsmu"):
|
|
||||||
xlim = ax.get_xlim()
|
|
||||||
omegas_empty = empty_lattice_modes_xy(ap.background_epsmu, ap.reciprocal_basis2pi, k, omegas[-1])
|
|
||||||
for om in omegas_empty:
|
|
||||||
if om/eh > xlim[0] and om/eh < xlim[1]:
|
|
||||||
ax.axvline(om/eh, ls=':')
|
|
||||||
ax.set_xlabel('$\hbar \omega / \mathrm{eV}$')
|
|
||||||
ax.set_ylabel('Singular values')
|
|
||||||
ax.legend()
|
|
||||||
|
|
||||||
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
|
|
||||||
with PdfPages(plotfile) as pdf:
|
|
||||||
pdf.savefig(fig)
|
|
||||||
annotate_pdf_metadata(pdf, scriptname='lat2d_realfreqsvd.py')
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from qpms import processWfiles_sameKs
|
||||||
|
|
||||||
|
npart = int(sys.argv[1])
|
||||||
|
dest = sys.argv[2]
|
||||||
|
srcs = sys.argv[3:]
|
||||||
|
|
||||||
|
processWfiles_sameKs(srcs, dest, f='d', nparticles=npart)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from qpms import processWfiles_sameKs
|
||||||
|
|
||||||
|
dest = sys.argv[1]
|
||||||
|
srcs = sys.argv[2:]
|
||||||
|
|
||||||
|
processWfiles_sameKs(srcs, dest, f='d')
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from qpms import processWfiles_sameKs
|
||||||
|
|
||||||
|
npart = int(sys.argv[1])
|
||||||
|
dest = sys.argv[2]
|
||||||
|
srcs = sys.argv[3:]
|
||||||
|
|
||||||
|
srcs_sorted = sorted(srcs, key=float)
|
||||||
|
|
||||||
|
processWfiles_sameKs(srcs_sorted, dest, f='d', nparticles=npart)
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import math
|
|
||||||
from qpms.argproc import ArgParser, annotate_pdf_metadata
|
|
||||||
|
|
||||||
ap = ArgParser(['rectlattice2d', 'const_real_background', 'single_particle', 'single_lMax']) # const_real_background needed for calculation of the diffracted orders
|
|
||||||
ap.add_argument("-k", nargs=2, type=float, 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("-b", "--band-index", type=int, required=True, 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.")
|
|
||||||
ap.add_argument("-f", "--interval-factor", type=float, default=0.1)
|
|
||||||
ap.add_argument("-N", type=int, default="150", help="Integration contour discretisation size")
|
|
||||||
ap.add_argument("-i", "--imaginary-aspect-ratio", type=float, default=1, help="Aspect ratio of the integration contour (Im/Re)")
|
|
||||||
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")
|
|
||||||
|
|
||||||
a=ap.parse_args()
|
|
||||||
|
|
||||||
px, py = a.period
|
|
||||||
|
|
||||||
if a.kpi:
|
|
||||||
a.k[0] *= math.pi/px
|
|
||||||
a.k[1] *= math.pi/py
|
|
||||||
|
|
||||||
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_n%g_b%+d_k(%g_%g)um-1_L%d_cn%d" % (
|
|
||||||
particlestr, px*1e9, py*1e9, str(a.material), a.refractive_index, a.band_index, a.k[0]*1e-6, a.k[1]*1e-6, a.lMax, 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
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
if a.material in lorentz_drude:
|
|
||||||
emg = EpsMuGenerator(lorentz_drude[a.material])
|
|
||||||
else: # constant refractive index
|
|
||||||
emg = EpsMuGenerator(EpsMu(a.material**2))
|
|
||||||
|
|
||||||
beta = np.array(a.k)
|
|
||||||
|
|
||||||
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))
|
|
||||||
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
|
|
||||||
|
|
||||||
bspec = BaseSpec(lMax = a.lMax)
|
|
||||||
pp = Particle(orig_xy[0][0], t = ap.tmgen, bspec=bspec)
|
|
||||||
|
|
||||||
ss, ssw = ScatteringSystem.create([pp], ap.background_emg, centfreq, latticebasis = ap.direct_basis)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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']))
|
|
||||||
|
|
||||||
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):
|
|
||||||
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="rectlat_simple_modes.py")
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
'''INCOMPLETE! This will read read the refractiveindex.info yaml files
|
||||||
|
and transforms the database into a C source.'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
try:
|
||||||
|
from yaml import CLoader as Loader, CDumper as Dumper
|
||||||
|
except ImportError:
|
||||||
|
from yaml import Loader, Dumper
|
||||||
|
|
||||||
|
# Right now, we can process only the 'tabulated nk' data
|
||||||
|
searchfor = '- type: tabulated nk'
|
||||||
|
searchfor = re.compile(searchfor)
|
||||||
|
|
||||||
|
ridatadir = "/u/46/necadam1/unix/repo/refractiveindex.info-database/database/data"
|
||||||
|
|
||||||
|
nktables = dict()
|
||||||
|
|
||||||
|
def find_files_by_pattern (pattern, dir):
|
||||||
|
r = re.compile(pattern)
|
||||||
|
for parent, dnames, fnames in os.walk(ridatadir):
|
||||||
|
for fname in fnames:
|
||||||
|
filename = os.path.join(parent, fname)
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
with open(filename) as f:
|
||||||
|
text = f.read()
|
||||||
|
if r.search(text):
|
||||||
|
yield (
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
ricbessel # ricatti-bessel psi
|
||||||
|
richankes # ricatti-hankel xi
|
||||||
|
cricbessel
|
||||||
|
crichankel # (same with complex argument)
|
||||||
|
cspherebessel # spherical Bessel jn(z), yn(z)
|
||||||
|
vcfunc # vector coupling coefficients C(m,n|k,l|m+k,w), w = |n-l|,...n+l
|
||||||
|
normalizedlegendre # normalized asssociated legendre functions
|
||||||
|
rotcoef # Generalized spherical functions
|
||||||
|
taufunc # vector spherical harmonics, normalized
|
||||||
|
pifunc # vector spherical harmonics, ?
|
||||||
|
planewavecoef # regular vswf expansion coefficients for a plane wave
|
||||||
|
gaussianbeamcoef # regular vsfw expansion for a gaussian beam
|
||||||
|
sphereplanewavecoef # plane wave expansion coefficients at sphere origins
|
||||||
|
axialtrancoefrecurrence # axial translation ceifficients
|
||||||
|
axialtrancoefinit
|
||||||
|
tranordertest # test to determine convergence of regular vswf addition theorem
|
||||||
|
atcadd
|
||||||
|
atcdim
|
||||||
|
moffset
|
||||||
|
gentrancoef # calculates the vwh translation coefficients for a general translation from one origin to another
|
||||||
|
cartosphere # cartesian to spherical coorsinates
|
||||||
|
eulerrotation # euler rotation of a point specified in cartesian coords
|
||||||
|
ephicoef
|
||||||
|
planewavetruncationorder # test to determine max order of vswf expansion of a plane wave at distance r
|
||||||
|
vwhcalc # calculates the cartesian components of the vswf at position rpos
|
||||||
|
vwhaxialcalc # svwf calculation for an axial translation
|
||||||
|
twobytwoinverse # inverse of a 2x2 matrix
|
||||||
|
transfer
|
||||||
|
|
||||||
|
mpisetup
|
||||||
|
|
||||||
|
module spheredata (lots of declarations!, read all the shit)
|
||||||
|
(...)
|
||||||
|
|
||||||
|
module miecoefdata
|
||||||
|
miecoefcalc # calculation of the max order of sphere expansions and storage of mie coefficients
|
||||||
|
readtmatrix # reads and stores a PARTICLE T matrix
|
||||||
|
lrmodetran # transformation between lr and te tm basis
|
||||||
|
mieoa # optically aptive lorenz/mie coefficients
|
||||||
|
getmiedataall # retrieve the array of mie data
|
||||||
|
getmiedataone # retrieve mie data for a single sphere
|
||||||
|
onemiecoeffmult # multiplies coefficients for sphere i by appropriate lm coefficient
|
||||||
|
multmiecoeffmult # generalized mie coefficient mult
|
||||||
|
dotproduct # vectorproduct for each rhs element of coefficient array
|
||||||
|
|
||||||
|
module translation
|
||||||
|
hostconfiguration # calculates lists for identifying host and interior sphere
|
||||||
|
rottranmtrxsetup # sets up the stored translation matrices and sets other constants
|
||||||
|
rottranmtrxclear # clear the stored translation matrices
|
||||||
|
sphereinteraction # the general sphere interaction driver
|
||||||
|
external_to_external_expansion # outgoing translation operator: a(i) = H(i-j) a(j)
|
||||||
|
external_to_internal_expansion #
|
||||||
|
m1_to_the_n # sign flipped for odd degrees
|
||||||
|
rottranfarfield # far field formula for outgoing vswf translation
|
||||||
|
farfieldtranslationerror # correction ter for hybrid bcgm solution
|
||||||
|
rottran # the vectorized rotation translation-rotation operation !!!!
|
||||||
|
spheregaussianbeamcoef # GB coefficients for sphere-centered expansion, obtained via translation
|
||||||
|
rotvec # rotation of expansion coefficients amn by euler angles
|
||||||
|
|
||||||
|
module scatprops
|
||||||
|
tranorders # determinaniot of maximum orders for target-based expansions
|
||||||
|
amncommonorigin # translation of sphere-based expansions to common target origin
|
||||||
|
lrsphereqeff # general efficiency factor calculation
|
||||||
|
qefficiencyfactors # calling routine for efficiency calculation
|
||||||
|
scatteringmatrix # scattering amplitude sa and matrix sm calculation
|
||||||
|
s11expansion
|
||||||
|
fosmcalc # azimuth-averaged scattering matrix
|
||||||
|
formexpansion # determine the generalized sf expansion for the azimuth-averaged scatt. matrix
|
||||||
|
ranorientscatmatrix
|
||||||
|
ranorientscatmatrixcalc
|
||||||
|
|
||||||
|
module nearfield
|
||||||
|
packcoefficient
|
||||||
|
unpackcoefficient
|
||||||
|
nearfieldspherepart # the field at point xg generated by the spheres
|
||||||
|
nearfieldincidentpart # the incident field at point xg using a regular vswh expansion
|
||||||
|
nearfieldincidentcoef # reshaped array of incident field coefficients
|
||||||
|
nearfieldpointcalc # !
|
||||||
|
nearfieldgridcalc
|
||||||
|
|
||||||
|
module solver
|
||||||
|
tmatrixsoln # calculation of T-mat. via solution of interaction eqs for a generalized plane wave expansion
|
||||||
|
fixedorsoln # solution of interaction exuations for a fixed orientation
|
||||||
|
cbicgff # hybrid bcgm, using far field translation
|
||||||
|
cbicg # bcgm iteration solver
|
|
@ -0,0 +1,11 @@
|
||||||
|
f = 'out'
|
||||||
|
fc = 'outcs'
|
||||||
|
do for [t=3:137] {
|
||||||
|
y = ((t-3) % 45)/3
|
||||||
|
typ = (t-3) % 3
|
||||||
|
n = floor(sqrt(y+1))
|
||||||
|
m = y - (n*(n+1)-1)
|
||||||
|
print 'n = ', n, ', m = ', m, ', typ ', typ
|
||||||
|
plot f using 1:t w linespoints, fc using 1:t w linespoints
|
||||||
|
pause -1
|
||||||
|
}
|
|
@ -1,461 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\paperfontsize default
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize default
|
|
||||||
\use_geometry false
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Title
|
|
||||||
Periodic Green's functions vs.
|
|
||||||
VSWF lattice sums
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ud}{\mathrm{d}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\abs}[1]{\left|#1\right|}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vect}[1]{\mathbf{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\uvec}[1]{\hat{\mathbf{#1}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ush}[2]{Y_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ushD}[2]{Y'_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vsh}{\vect A}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vshD}{\vect{A'}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkc}{\vect y}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcout}{\vect u}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcreg}{\vect v}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcreg}{a}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcout}{f}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
Some definitions and useful relations
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\mathcal{H}_{l}^{m}\left(\vect d\right)\equiv h_{l}^{+}\left(\left|\vect d\right|\right)\ush lm\left(\uvec d\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\mathcal{J}_{l}^{m}\left(\vect d\right)\equiv j_{l}\left(\left|\vect d\right|\right)\ush lm\left(\uvec d\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Dual spherical harmonics and waves
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ush lm\ushD{l'}{m'}\,\ud\Omega=\delta_{l,l'}\delta_{m,m'}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\mathcal{J}'_{l}^{m}\left(\vect d\right)\equiv j_{l}\left(\left|\vect d\right|\right)\ushD lm\left(\uvec d\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Expansion of plane wave (CHECKME whether this is really convention-independent,
|
|
||||||
but it seems so)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
e^{i\kappa\vect r\cdot\uvec r'}=4\pi\sum_{l,m}i^{n}\mathcal{J}'_{l}^{m}\left(\kappa\vect r\right)\ush lm\left(\uvec r'\right)=4\pi\sum_{l,m}i^{n}\mathcal{J}{}_{l}^{m}\left(\kappa\vect r\right)\ushD lm\left(\uvec r'\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
This one should also be convention independent (similarly for
|
|
||||||
\begin_inset Formula $\mathcal{H}_{l}^{m}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
):
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\mathcal{J}_{l}^{m}\left(-\vect r\right)=\left(-1\right)^{l}\mathcal{J}_{l}^{m}\left(\vect r\right).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
Helmholtz equation and Green's functions (in 3D)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Note that the notation does not follow Linton's (where the wavenumbers are
|
|
||||||
often implicit)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\left(\nabla^{2}+\kappa^{2}\right)G^{(\kappa)}\left(\vect x,\vect x_{0}\right)=\delta\left(\vect x-\vect x_{0}\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
G_{0}^{(\kappa)}\left(\vect x,\vect x_{0}\right) & =G_{0}^{(\kappa)}\left(\vect x-\vect x_{0}\right)=-\frac{\cos\left(\kappa\left|\vect x-\vect x_{0}\right|\right)}{4\pi\left|\vect x-\vect x_{0}\right|}\\
|
|
||||||
G_{\pm}^{(\kappa)}\left(\vect x,\vect x_{0}\right) & =G_{\pm}^{(\kappa)}\left(\vect x-\vect x_{0}\right)=-\frac{e^{\pm i\kappa\left|\vect x-\vect x_{0}\right|}}{4\pi\left|\vect x-\vect x_{0}\right|}=-\frac{i\kappa}{4\pi}h_{0}^{\pm}\left(\kappa\left|\vect x-\vect x_{0}\right|\right)=-\frac{i\kappa}{\sqrt{4\pi}}\mathcal{H}_{0}^{0}\left(\kappa\left|\vect x-\vect x_{0}\right|\right)
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Marginal
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
\begin_inset Formula $G_{\pm}^{(\kappa)}\left(\vect x,\vect x_{0}\right)=-\frac{i\kappa}{\ush 00}\mathcal{H}_{0}^{0}\left(\kappa\left|\vect x-\vect x_{0}\right|\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
in case wacky conventions.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Lattice GF [Linton (2.3)]:
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
G_{\Lambda}^{(\kappa)}\left(\vect s,\vect k\right)\equiv\sum_{\vect R\in\Lambda}G_{+}^{\kappa}\left(\vect s-\vect R\right)e^{i\vect k\cdot\vect R}\label{eq:Lattice GF}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
GF expansion and lattice sum definition
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Let's define
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\sigma_{l}^{m}\left(\vect s,\vect k\right)=\sum_{\vect R\in\Lambda}\mathcal{H}_{l}^{m}\left(\kappa\left(\vect s+\vect R\right)\right)e^{i\vect k\cdot\vect R},
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and also its dual version
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\sigma'_{l}^{m}\left(\vect s,\vect k\right)=\sum_{\vect R\in\Lambda}\mathcal{H}'_{l}^{m}\left(\kappa\left(\vect s+\vect R\right)\right)e^{i\vect k\cdot\vect R}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Inspired by [Linton (4.1)]; assuming that
|
|
||||||
\begin_inset Formula $\vect s\notin\Lambda$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, let's expand the lattice Green's function around
|
|
||||||
\begin_inset Formula $\vect s$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
:
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right)=-i\kappa\sum_{l,m}\tau_{l}^{m}\left(\vect s,\vect k\right)\mathcal{J}_{l}^{m}\left(\kappa\vect r\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and multiply with a dual SH + integrate
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right)\ushD{l'}{m'}\left(\uvec r\right) & =-i\kappa\sum_{l,m}\tau_{l}^{m}\left(\vect s,\vect k\right)j_{l}\left(\kappa\left|\vect r\right|\right)\delta_{ll'}\delta_{mm'}\nonumber \\
|
|
||||||
& =-i\kappa\tau_{l'}^{m'}\left(\vect s,\vect k\right)j_{l'}\left(\kappa\left|\vect r\right|\right)\label{eq:tau extraction}
|
|
||||||
\end{align}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The expansion coefficients
|
|
||||||
\begin_inset Formula $\tau_{l}^{m}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is then typically extracted by taking the limit
|
|
||||||
\begin_inset Formula $\left|\vect r\right|\to0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
The relation between
|
|
||||||
\begin_inset Formula $\sigma_{l}^{m}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and
|
|
||||||
\begin_inset Formula $\tau_{l}^{m}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
can be obtained e.g.
|
|
||||||
from the addition theorem for scalar spherical wavefunctions [Linton (C.3)],
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\mathcal{H}_{l}^{m}\left(\vect a+\vect b\right)=\sum_{l'm'}S_{ll'}^{mm'}\left(\vect b\right)\mathcal{J}_{l'}^{m'}\left(\vect a\right),\quad\left|\vect a\right|<\left|\vect b\right|
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
where for the zeroth degree and order one has [Linton (C.3)]
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S_{0l'}^{0m'}\left(\vect b\right)=\sqrt{4\pi}\mathcal{H}'_{l'}^{m'}\left(-\vect b\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Marginal
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
In a totally convention-independent version probably looks like
|
|
||||||
\begin_inset Formula $S_{0l'}^{0m'}\left(\vect b\right)=\ush 00\mathcal{H}'_{l'}^{m'}\left(-\vect b\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, but the
|
|
||||||
\begin_inset Formula $Y_{0}^{0}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
will cancel with the expression for GF anyways, so no harm to the final
|
|
||||||
result.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
From the lattice GF definition
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:Lattice GF"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right) & \equiv\frac{-i\kappa}{\sqrt{4\pi}}\sum_{\vect R\in\Lambda}\mathcal{H}_{0}^{0}\left(\kappa\left(\vect s+\vect r-\vect R\right)\right)e^{i\vect k\cdot\vect R}\\
|
|
||||||
& =\frac{-i\kappa}{\sqrt{4\pi}}\sum_{\vect R\in\Lambda}\mathcal{H}_{0}^{0}\left(\kappa\left(\vect s+\vect r-\vect R\right)\right)e^{i\vect k\cdot\vect R}\\
|
|
||||||
& =\frac{-i\kappa}{\sqrt{4\pi}}\sum_{\vect R\in\Lambda}\sum_{l'm'}S_{0l'}^{0m'}\left(\kappa\left(\vect s-\vect R\right)\right)\mathcal{J}_{l'}^{m'}\left(\kappa\vect r\right)e^{i\vect k\cdot\vect R}\\
|
|
||||||
& =-i\kappa\sum_{\vect R\in\Lambda}\sum_{lm}\mathcal{H}'_{l}^{m}\left(-\kappa\left(\vect s-\vect R\right)\right)\mathcal{J}_{l}^{m}\left(\kappa\vect r\right)e^{i\vect k\cdot\vect R}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and mutliplying with dual SH and integrating
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right)\ushD{l'}{m'}\left(\uvec r\right) & =-i\kappa\sum_{\vect R\in\Lambda}\sum_{lm}\mathcal{H}'_{l}^{m}\left(-\kappa\left(\vect s-\vect R\right)\right)j_{l}\left(\kappa\left|\vect r\right|\right)\delta_{ll'}\delta_{mm'}e^{i\vect k\cdot\vect R}\\
|
|
||||||
& =-i\kappa\sum_{\vect R\in\Lambda}\mathcal{H}'_{l'}^{m'}\left(\kappa\left(-\vect s+\vect R\right)\right)j_{l'}\left(\kappa\left|\vect r\right|\right)e^{i\vect k\cdot\vect R}\\
|
|
||||||
& =-i\kappa\sigma'_{l'}^{m'}\left(-\vect s,\vect k\right)j_{l'}\left(\kappa\left|\vect r\right|\right)
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and comparing with
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:tau extraction"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\tau_{l}^{m}\left(\vect s,\vect k\right)=\sigma'_{l}^{m}\left(-\vect s,\vect k\right).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
TODO maybe also define some
|
|
||||||
\begin_inset Formula $\tau'_{l}^{m}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
as expansion coefficients of GF into dual regular SSWFs.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -1,107 +0,0 @@
|
||||||
# Installing QPMS on Android/AOSP (-based) systems
|
|
||||||
|
|
||||||
Yes, it is possible. Basically all you need is a device capable of running [Termux](https://termux.com/) with enough memory to build everything.
|
|
||||||
|
|
||||||
The following instructions have been tested with Termux version 0.118.0 on
|
|
||||||
[e/OS/ R development build on a Samsung Galaxy S10e](https://doc.e.foundation/devices/beyond0lte/install)
|
|
||||||
([e-1.0-r-20220526188878-dev-beyond0lte](https://images.ecloud.global/dev/beyond0lte/)).
|
|
||||||
Presumably, they should work also on stock Android as well, but who
|
|
||||||
in their right mind would run all the spyware by Google & al.?
|
|
||||||
|
|
||||||
Physical keyboard or [remote access](https://wiki.termux.com/wiki/Remote_Access) is strongly recommended. :D
|
|
||||||
|
|
||||||
## Get Termux
|
|
||||||
|
|
||||||
Just [install the Termux app from F-Droid or Github as per instructions](https://github.com/termux/termux-app#f-droid).
|
|
||||||
|
|
||||||
Open Termux; the following steps of these instructions are basically
|
|
||||||
just commands you need to type in Termux.
|
|
||||||
|
|
||||||
## Install prerequisities from termux repositories
|
|
||||||
|
|
||||||
```
|
|
||||||
pkg install python3 cmake git clang build-essential binutils
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build and install GSL
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -O https://www.nic.funet.fi/pub/gnu/ftp.gnu.org/pub/gnu/gsl/gsl-latest.tar.gz
|
|
||||||
tar xf gsl-latest.tar.gz
|
|
||||||
cd gsl-2.7.1
|
|
||||||
./configure --prefix=$PREFIX
|
|
||||||
make # add -j4 or so to make it faster on multicore systems
|
|
||||||
make install
|
|
||||||
cd -
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build and install OpenBLAS
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://github.com/xianyi/OpenBLAS.git
|
|
||||||
cd OpenBLAS
|
|
||||||
make
|
|
||||||
make PREFIX=$PREFIX install
|
|
||||||
cd -
|
|
||||||
```
|
|
||||||
|
|
||||||
### Workaround for "broken" setup.py script
|
|
||||||
|
|
||||||
The goal is to fix `setup.py` so that it finds the correct libraries automatically, but in the meantime, you can use this workaround to get the Python part of QPMS installed:
|
|
||||||
|
|
||||||
```
|
|
||||||
ln -s $PREFIX/lib/libopenblas.so $PREFIX/LIB/liblapacke.so
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build and install Numpy
|
|
||||||
|
|
||||||
(Successful build requires the `MATHLIB` environmental variable set, otherwise linking will fail; see https://wiki.termux.com/wiki/Python.)
|
|
||||||
|
|
||||||
```
|
|
||||||
MATHLIB=m pip3 install numpy
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install Sympy
|
|
||||||
|
|
||||||
```
|
|
||||||
pip3 install sympy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build and install QPMS
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://repo.or.cz/qpms.git
|
|
||||||
cd qpms
|
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX . # ugly, TODO make a separate build tree!
|
|
||||||
make install
|
|
||||||
|
|
||||||
python3 setup.py install
|
|
||||||
```
|
|
||||||
|
|
||||||
Hopefully, QPMS has installed successfully. At this point, you should be able
|
|
||||||
to import and use QPMS with some exceptions. First, there is some legacy code
|
|
||||||
in the `qpms.qpms_p` module (which is no longer imported automatically with
|
|
||||||
bare `import qpms`). You shouldn't need this unless you are trying to run some
|
|
||||||
historic Jupyter notebooks or other old custom scripts. It contains a scipy
|
|
||||||
dependence, and scipy is hard to get working in Android environment (as
|
|
||||||
it requires a Fortran compiler to build).
|
|
||||||
|
|
||||||
## Install matplotlib
|
|
||||||
|
|
||||||
If you try to run just `pip3 install matplotlib` in Termux, it might likely
|
|
||||||
fail when installing the `pillow` dependency.
|
|
||||||
First, according to [Termux wiki](https://wiki.termux.com/wiki/Python#Python_module_installation_tips_and_tricks),
|
|
||||||
pillow depends on `libpng` and `libjpeg-turbo`, which are fortunately
|
|
||||||
available in Termux packages.
|
|
||||||
Second, pillow instalation requires an additional environment variable
|
|
||||||
`LDFLAGS="-L/system/lib64"` to be set on 64-bit devices.
|
|
||||||
|
|
||||||
Hence:
|
|
||||||
```
|
|
||||||
pkg install libpng libjpeg-turbo
|
|
||||||
export LDFLAGS="-L/system/lib64" # on 64-bit devices
|
|
||||||
pip3 install matplotlib
|
|
||||||
```
|
|
||||||
|
|
||||||
After this step, you should be able to run the command-line scripts
|
|
||||||
from `misc/` directory and examples from `examples/` directory.
|
|
|
@ -1,266 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\paperfontsize default
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize default
|
|
||||||
\use_geometry false
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ud}{\mathrm{d}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
\Delta_{n}(x,z)\equiv\int_{x}^{\infty}t^{-\frac{1}{2}-n}e^{-t+\frac{z^{2}}{4t}}\ud t\label{eq:Delta definition}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Integration per partes:
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int t^{-\frac{1}{2}-n}\ud t=\frac{t^{\frac{1}{2}-n}}{\frac{1}{2}-n};
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\frac{\ud}{\ud t}e^{-t+\frac{z^{2}}{4t}}=\left(-1-\frac{z^{2}}{4t^{2}}\right)e^{-t+\frac{z^{2}}{4t}}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\left(\frac{1}{2}-n\right)\Delta_{n} & =-x^{\frac{1}{2}-n}e^{-x+\frac{z^{2}}{4x}}+\int_{x}^{\infty}t^{\frac{1}{2}-n}e^{-t+\frac{z^{2}}{4t}}\ud t+\frac{z^{2}}{4}\int_{x}^{\infty}t^{\frac{-3}{2}-n}e^{-t+\frac{z^{2}}{4t}}\ud t\\
|
|
||||||
& =-x^{\frac{1}{2}-n}e^{-x+\frac{z^{2}}{4x}}+\Delta_{n-1}+\frac{z^{2}}{4}\Delta_{n+1},
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
\Delta_{n+1}=\frac{4}{z^{2}}\left(\left(\frac{1}{2}-n\right)\Delta_{n}-\Delta_{n-1}+x^{\frac{1}{2}-n}e^{-x+\frac{z^{2}}{4x}}\right).\label{eq:Delta recurrence}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
There are obviously wrong signs in Kambe II, (A 3.3).
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Eq.
|
|
||||||
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:Delta recurrence"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is obviously unsuitable for numerical computation when
|
|
||||||
\begin_inset Formula $z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
approaches 0.
|
|
||||||
However, the definition
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:Delta definition"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
suggests that the function should be analytical around
|
|
||||||
\begin_inset Formula $z=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
If
|
|
||||||
\begin_inset Formula $z=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, one has (by definition of incomplete Г function)
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
\Delta_{n}(x,0)=\Gamma\left(\frac{1}{2}-n,x\right).\label{eq:Delta:z = 0}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
For convenience, label
|
|
||||||
\begin_inset Formula $w=z^{2}/4$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Delta'_{n}\left(x,w\right)\equiv\int_{x}^{\infty}t^{-\frac{1}{2}-n}e^{-t+\frac{w}{t}}\ud t.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Differentiating by parameter
|
|
||||||
\begin_inset Formula $w$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(which should be fine as long as the integration contour does not go through
|
|
||||||
zero) gives
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\frac{\partial\Delta'_{n}\left(x,w\right)}{\partial w}=\Delta'_{n+1}\left(x,w\right),
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
so by recurrence
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\frac{\partial^{k}}{\partial w^{k}}\Delta'_{n}\left(x,w\right)=\Delta'_{n+k}\left(x,w\right).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Together with
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:Delta:z = 0"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, this gives an expansion around
|
|
||||||
\begin_inset Formula $w=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
:
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Delta_{n}'\left(x,w\right)=\sum_{k=0}^{\infty}\Gamma\left(\frac{1}{2}-n-k,x\right)\frac{w^{k}}{k!},
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Delta_{n}\left(x,z\right)=\sum_{k=0}^{\infty}\Gamma\left(\frac{1}{2}-n-k,x\right)\frac{\left(z/2\right)^{2k}}{k!}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The big negative first arguments in incomplete
|
|
||||||
\begin_inset Formula $\Gamma$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
functions should be good (at least I think so, CHECKME), as well as the
|
|
||||||
|
|
||||||
\begin_inset Formula $1/k!$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
factor (of course).
|
|
||||||
I am not sure what the convergence radius is, but for
|
|
||||||
\begin_inset Formula $\left|z\right|<2$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
there seems to be absolutely no problem in using this formula.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -1,9 +1,7 @@
|
||||||
#LyX 2.3 created this file. For more info see http://www.lyx.org/
|
#LyX 2.1 created this file. For more info see http://www.lyx.org/
|
||||||
\lyxformat 544
|
\lyxformat 474
|
||||||
\begin_document
|
\begin_document
|
||||||
\begin_header
|
\begin_header
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass report
|
\textclass report
|
||||||
\begin_preamble
|
\begin_preamble
|
||||||
%\renewcommand*{\chapterheadstartvskip}{\vspace*{1cm}}
|
%\renewcommand*{\chapterheadstartvskip}{\vspace*{1cm}}
|
||||||
|
@ -15,18 +13,16 @@
|
||||||
\language_package default
|
\language_package default
|
||||||
\inputencoding auto
|
\inputencoding auto
|
||||||
\fontencoding global
|
\fontencoding global
|
||||||
\font_roman "default" "TeX Gyre Pagella"
|
\font_roman TeX Gyre Pagella
|
||||||
\font_sans "default" "default"
|
\font_sans default
|
||||||
\font_typewriter "default" "default"
|
\font_typewriter default
|
||||||
\font_math "auto" "auto"
|
\font_math auto
|
||||||
\font_default_family default
|
\font_default_family default
|
||||||
\use_non_tex_fonts true
|
\use_non_tex_fonts true
|
||||||
\font_sc false
|
\font_sc false
|
||||||
\font_osf true
|
\font_osf true
|
||||||
\font_sf_scale 100 100
|
\font_sf_scale 100
|
||||||
\font_tt_scale 100 100
|
\font_tt_scale 100
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures false
|
|
||||||
\graphics default
|
\graphics default
|
||||||
\default_output_format pdf4
|
\default_output_format pdf4
|
||||||
\output_sync 0
|
\output_sync 0
|
||||||
|
@ -67,7 +63,6 @@
|
||||||
\suppress_date false
|
\suppress_date false
|
||||||
\justification true
|
\justification true
|
||||||
\use_refstyle 1
|
\use_refstyle 1
|
||||||
\use_minted 0
|
|
||||||
\index Index
|
\index Index
|
||||||
\shortcut idx
|
\shortcut idx
|
||||||
\color #008000
|
\color #008000
|
||||||
|
@ -80,10 +75,7 @@
|
||||||
\tocdepth 3
|
\tocdepth 3
|
||||||
\paragraph_separation indent
|
\paragraph_separation indent
|
||||||
\paragraph_indentation default
|
\paragraph_indentation default
|
||||||
\is_math_indent 0
|
\quotes_language swedish
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style swedish
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
\papercolumns 1
|
||||||
\papersides 1
|
\papersides 1
|
||||||
\paperpagestyle default
|
\paperpagestyle default
|
||||||
|
@ -110,7 +102,7 @@
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Title
|
\begin_layout Title
|
||||||
Electromagnetic multiple scattering, spherical waves and conventions
|
Electromagnetic multiple scattering, spherical waves and ****
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Author
|
\begin_layout Author
|
||||||
|
@ -252,7 +244,7 @@ Pi and tau
|
||||||
Xu
|
Xu
|
||||||
\begin_inset CommandInset label
|
\begin_inset CommandInset label
|
||||||
LatexCommand label
|
LatexCommand label
|
||||||
name "subsec:Xu pitau"
|
name "sub:Xu pitau"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -381,7 +373,7 @@ The limiting expressions are obtained simply by multiplying the expressions
|
||||||
|
|
||||||
\begin_inset CommandInset ref
|
\begin_inset CommandInset ref
|
||||||
LatexCommand ref
|
LatexCommand ref
|
||||||
reference "subsec:Xu pitau"
|
reference "sub:Xu pitau"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -470,7 +462,6 @@ Jackson
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(9.101)"
|
after "(9.101)"
|
||||||
key "jackson_classical_1998"
|
key "jackson_classical_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -487,7 +478,6 @@ where
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(9.119)"
|
after "(9.119)"
|
||||||
key "jackson_classical_1998"
|
key "jackson_classical_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -509,7 +499,6 @@ Normalisation
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(9.120)"
|
after "(9.120)"
|
||||||
key "jackson_classical_1998"
|
key "jackson_classical_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -530,7 +519,6 @@ Local sum rule
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(9.153)"
|
after "(9.153)"
|
||||||
key "jackson_classical_1998"
|
key "jackson_classical_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -805,7 +793,6 @@ As in
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "eq. (36)"
|
after "eq. (36)"
|
||||||
key "xu_calculation_1996"
|
key "xu_calculation_1996"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -829,7 +816,6 @@ where CS is
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "eq. (81)"
|
after "eq. (81)"
|
||||||
key "xu_calculation_1996"
|
key "xu_calculation_1996"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -840,7 +826,7 @@ literal "true"
|
||||||
Relation between Kristensson and Taylor
|
Relation between Kristensson and Taylor
|
||||||
\begin_inset CommandInset label
|
\begin_inset CommandInset label
|
||||||
LatexCommand label
|
LatexCommand label
|
||||||
name "subsec:Kristensson-v-Taylor"
|
name "sub:Kristensson-v-Taylor"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -975,7 +961,7 @@ In this section I summarize the formulae for power
|
||||||
Kristensson
|
Kristensson
|
||||||
\begin_inset CommandInset label
|
\begin_inset CommandInset label
|
||||||
LatexCommand label
|
LatexCommand label
|
||||||
name "subsec:Radiated enenergy-Kristensson"
|
name "sub:Radiated enenergy-Kristensson"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1036,7 +1022,7 @@ Here I derive the radiated power in Taylor's convention by applying the
|
||||||
relations from subsection
|
relations from subsection
|
||||||
\begin_inset CommandInset ref
|
\begin_inset CommandInset ref
|
||||||
LatexCommand ref
|
LatexCommand ref
|
||||||
reference "subsec:Kristensson-v-Taylor"
|
reference "sub:Kristensson-v-Taylor"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1044,7 +1030,7 @@ reference "subsec:Kristensson-v-Taylor"
|
||||||
|
|
||||||
\begin_inset CommandInset ref
|
\begin_inset CommandInset ref
|
||||||
LatexCommand ref
|
LatexCommand ref
|
||||||
reference "subsec:Radiated enenergy-Kristensson"
|
reference "sub:Radiated enenergy-Kristensson"
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1124,7 +1110,6 @@ Jackson
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(9.155)"
|
after "(9.155)"
|
||||||
key "jackson_classical_1998"
|
key "jackson_classical_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1153,7 +1138,6 @@ TODO start from
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(A7)"
|
after "(A7)"
|
||||||
key "pustovit_plasmon-mediated_2010"
|
key "pustovit_plasmon-mediated_2010"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1333,7 +1317,6 @@ TODO start from
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(A11)"
|
after "(A11)"
|
||||||
key "pustovit_plasmon-mediated_2010"
|
key "pustovit_plasmon-mediated_2010"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1496,7 +1479,6 @@ Cruzan's formulation, Xu's normalisation
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(59)"
|
after "(59)"
|
||||||
key "xu_efficient_1998"
|
key "xu_efficient_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
|
@ -1513,7 +1495,6 @@ where
|
||||||
LatexCommand cite
|
LatexCommand cite
|
||||||
after "(28,5,60,61)"
|
after "(28,5,60,61)"
|
||||||
key "xu_efficient_1998"
|
key "xu_efficient_1998"
|
||||||
literal "true"
|
|
||||||
|
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
|
@ -1,677 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\float_placement class
|
|
||||||
\float_alignment class
|
|
||||||
\paperfontsize 10
|
|
||||||
\spacing single
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize a4paper
|
|
||||||
\use_geometry true
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\biblio_style plain
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\leftmargin 2cm
|
|
||||||
\topmargin 2cm
|
|
||||||
\rightmargin 2cm
|
|
||||||
\bottommargin 2cm
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Title
|
|
||||||
1D and 2D in 3D Ewald sum
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ud}{\mathrm{d}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\abs}[1]{\left|#1\right|}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vect}[1]{\mathbf{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\uvec}[1]{\hat{\mathbf{#1}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ush}[2]{Y_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ushD}[2]{Y'_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vsh}{\vect A}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vshD}{\vect{A'}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkc}{\vect y}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcout}{\vect u}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcreg}{\vect v}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcreg}{a}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcout}{f}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
General formula
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
We need to find the long-range part of the expansion coefficient
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{i}{\kappa j_{l'}\left(\kappa\left|\vect r\right|\right)}\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right)\ushD{l'}{m'}\left(\uvec r\right).\label{eq:tau extraction formula}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
We take [Linton, (2.24)] with slightly modified notation
|
|
||||||
\begin_inset Formula $\left(\vect k_{\vect K}\equiv\vect K+\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect r}\int_{1/\eta}^{\infty e^{i\pi/4}}e^{-\kappa^{2}\gamma^{2}t^{2}/4}e^{-\left|\vect r^{\bot}\right|^{2}/t^{2}}t^{1-d_{c}}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
or, evaluated at point
|
|
||||||
\begin_inset Formula $\vect s+\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
instead
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\left(\vect s+\vect r\right)}\int_{1/\eta}^{\infty e^{i\pi/4}}e^{-\kappa^{2}\gamma^{2}t^{2}/4}e^{-\left|\vect s^{\bot}+\vect r^{\bot}\right|^{2}/t^{2}}t^{1-d_{c}}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The integral can be by substitutions taken into the form
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{2\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta}^{\infty\exp\left(i\pi/4\right)}e^{-\kappa^{2}\gamma_{m}^{2}\zeta^{2}/4}e^{-\left|\vect r_{\bot}\right|^{2}/\zeta^{2}}\zeta^{1-d_{c}}\ud\zeta
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try substitution
|
|
||||||
\begin_inset Formula $t=\zeta^{2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
: then
|
|
||||||
\begin_inset Formula $\ud t=2\zeta\,\ud\zeta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(
|
|
||||||
\begin_inset Formula $\ud\zeta=\ud t/2t^{1/2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
) and
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\kappa^{2}\gamma_{m}^{2}t/4}e^{-\left|\vect r_{\bot}\right|^{2}/t}t^{\frac{-d_{c}}{2}}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try subst.
|
|
||||||
|
|
||||||
\begin_inset Formula $\tau=k^{2}\gamma_{m}^{2}/4$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\left(\frac{\kappa\gamma_{m}}{2}\right)^{d_{c}}\int_{\kappa^{2}\gamma_{m}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{m}^{2}/4\tau}\tau^{\frac{-d_{c}}{2}}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\left(\vect s+\vect r\right)}\int_{\kappa^{2}\gamma_{m}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{m}^{2}/4\tau}\tau^{-\frac{d_{c}}{2}}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Foot
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
[Linton, (2.25)] with slightly modified notation:
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect r\right)=-\frac{1}{\sqrt{4\pi}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect r}\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}\left|\vect r^{\bot}\right|^{2j}}{j!}\left(\frac{\kappa\gamma_{\vect{\vect k_{\vect K}}}}{2}\right)^{2j-1}\Gamma_{j\vect k_{\vect K}}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
We want to express an expansion in a shifted point, so let's substitute
|
|
||||||
|
|
||||||
\begin_inset Formula $\vect r\to\vect s+\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{\sqrt{4\pi}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\left(\vect s+\vect r\right)}\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}\left|\vect s^{\bot}+\vect r^{\bot}\right|^{2j}}{j!}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j-1}\Gamma_{j\vect k_{\vect K}}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's do the integration to get
|
|
||||||
\begin_inset Formula $\tau_{l}^{m}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\left(\vect s+\vect r\right)}\int_{\kappa^{2}\gamma_{\vect k_{\vect K}}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect k_{\vect K}}^{2}/4\tau}\tau^{-\frac{d_{c}}{2}}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The
|
|
||||||
\begin_inset Formula $\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-dependent plane wave factor can be also written as
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
e^{i\vect k_{\vect K}\cdot\vect r} & =e^{i\left|\vect k_{\vect K}\right|\vect r\cdot\uvec{\vect k_{\vect K}}}=4\pi\sum_{lm}i^{l}\mathcal{J}'_{l}^{m}\left(\left|\vect k_{\vect K}\right|\vect r\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\\
|
|
||||||
& =4\pi\sum_{lm}i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ushD lm\left(\uvec{\vect r}\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
or the other way around
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
e^{i\vect k_{\vect K}\cdot\vect r}=4\pi\sum_{lm}i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect r}\right)\ushD lm\left(\uvec{\vect k_{\vect K}}\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
so
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\frac{1}{2\pi\mathcal{A}}\times\\
|
|
||||||
\times\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ushD lm\left(\uvec r\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\int_{\kappa^{2}\gamma_{\vect{\vect k_{\vect K}}}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect{\vect k_{\vect K}}}^{2}/4\tau}\tau^{-\frac{d_{c}}{2}}\ud\tau
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
We also have
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau} & =e^{-\left(\left|\vect s_{\bot}\right|^{2}+\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\\
|
|
||||||
& =e^{-\left|\vect s_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\sum_{j=0}^{\infty}\frac{1}{j!}\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}}{4\tau}\right)^{j},
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
hence
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right) & =-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ushD lm\left(\uvec r\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\times\\
|
|
||||||
& \quad\times\sum_{j=0}^{\infty}\frac{1}{j!}\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect{\vect k_{\vect K}}}^{2}}{4}\right)^{j}\underbrace{\int_{\kappa^{2}\gamma_{\vect K}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\tau^{-\frac{d_{c}}{2}-j}\ud\tau}_{\Delta_{j}^{\left(d_{\Lambda}\right)}}\\
|
|
||||||
& =-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\sum_{j=0}^{\infty}\frac{\Delta_{j}^{\left(d_{\Lambda}\right)}}{j!}\times\\
|
|
||||||
& \quad\times\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect k_{\vect K}}^{2}}{4}\right)^{j}\\
|
|
||||||
& =-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\times\\
|
|
||||||
& \quad\times\left(\frac{\kappa\gamma_{\vect{\vect k_{\vect K}}}}{2}\right)^{2j}\sum_{k=0}^{j}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left|\vect r_{\bot}\right|^{2(j-k)}\left(2\vect r_{\bot}\cdot\vect s_{\bot}\right)^{k}.
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
If we label
|
|
||||||
\begin_inset Formula $\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|\cos\varphi\equiv\vect r_{\bot}\cdot\vect s_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\times\\
|
|
||||||
\times\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\sum_{k=0}^{j}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left|\vect r_{\bot}\right|^{2j-k}\left(\cos\varphi\right)^{k}
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and if we label
|
|
||||||
\begin_inset Formula $\left|\vect r\right|\sin\vartheta\equiv\left|\vect r_{\bot}\right|$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi^{d_{c}/2}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect k_{\vect K}}\right)\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\times\\
|
|
||||||
\times\sum_{k=0}^{j}\left|\vect r\right|^{2j-k}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{2j-k}\left(\cos\varphi\right)^{k}.
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Now let's put the RHS into
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:tau extraction formula"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and try eliminating some sum by taking the limit
|
|
||||||
\begin_inset Formula $\left|\vect r\right|\to0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
We have
|
|
||||||
\begin_inset Formula $j_{l}\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)\sim\left(\left|\vect k_{\vect K}\right|\left|\vect r\right|\right)^{l}/\left(2l+1\right)!!$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
; the denominator from
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:tau extraction formula"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
behaves like
|
|
||||||
\begin_inset Formula $j_{l'}\left(\kappa\left|\vect r\right|\right)\sim\left(\kappa\left|\vect r\right|\right)^{l'}/\left(2l'+1\right)!!.$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The leading terms are hence those with
|
|
||||||
\begin_inset Formula $\left|\vect r\right|^{l-l'+2j-k}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
So
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi^{d_{c}/2}\mathcal{A}\kappa^{1+l'}}\left(2l'+1\right)!!\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{lm}4\pi i^{l}\frac{\left|\vect k_{\vect K}\right|^{l}}{\left(2l+1\right)!!}\ush lm\left(\uvec{\vect k_{\vect K}}\right)\times\\
|
|
||||||
\times\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\sum_{k=0}^{j}\delta_{l'-l,2j-k}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{l'-l}\left(\cos\varphi\right)^{k}.
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's now focus on rearranging the sums; we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')\equiv\sum_{l=0}^{\infty}\sum_{j=0}^{\infty}\sum_{k=0}^{j}\delta_{l'-l,2j-k}f(l',l,j,k)=\sum_{l=0}^{\infty}\sum_{j=0}^{\infty}\sum_{k=0}^{j}\delta_{l'-l,2j-k}f(l',l,j,2j-l'+l)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
We have
|
|
||||||
\begin_inset Formula $0\le k\le j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence
|
|
||||||
\begin_inset Formula $0\le2j-l'+l\le j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence
|
|
||||||
\begin_inset Formula $-2j\le-l'+l\le-j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence also
|
|
||||||
\begin_inset Formula $l'-2j\le l\le l'-j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, which gives the opportunity to swap the
|
|
||||||
\begin_inset Formula $l,j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
sums and the
|
|
||||||
\begin_inset Formula $l$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-sum becomes finite; so also consuming
|
|
||||||
\begin_inset Formula $\sum_{k=0}^{j}\delta_{l'-l,2j-k}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
we get
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')=\sum_{j=0}^{\infty}\sum_{l=\max(0,l'-2j)}^{l'-j}f(l',l,j,2j-l'+l).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Finally, we see that the interval of valid
|
|
||||||
\begin_inset Formula $l$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
becomes empty when
|
|
||||||
\begin_inset Formula $l'-j<0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, i.e.
|
|
||||||
|
|
||||||
\begin_inset Formula $j>l'$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
; so we get a finite sum
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')=\sum_{j=0}^{l'}\sum_{l=\max(0,l'-2j)}^{l'-j}f(l',l,j,2j-l'+l).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Applying rearrangement,
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi^{d_{c}/2}\mathcal{A}\kappa}\frac{\left(2l'+1\right)!!}{\kappa^{l'}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{j=0}^{l'}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\times\sum_{l=\max\left(0,l'-2j\right)}^{l'-j}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2j-l'+l}\frac{\left|\vect k_{\vect K}\right|^{l}}{\left(2l+1\right)!!}\\
|
|
||||||
\times\sum_{m=-l}^{l}\ush lm\left(\uvec{\vect k_{\vect K}}\right)\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{l'-l}\left(\cos\varphi\right)^{2j-l'+l},
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
or replacing the angles with their original definition,
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi^{d_{c}/2}\mathcal{A}\kappa}\frac{\left(2l'+1\right)!!}{\kappa^{l'}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\sum_{j=0}^{l'}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2j}\times\sum_{l=\max\left(0,l'-2j\right)}^{l'-j}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2j-l'+l}\frac{\left|\vect k_{\vect K}\right|^{l}}{\left(2l+1\right)!!}\\
|
|
||||||
\times\sum_{m=-l}^{l}\ush lm\left(\uvec K\right)\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\frac{\left|\vect r_{\bot}\right|}{\left|\vect r\right|}\right)^{l'-l}\left(\frac{\vect r_{\bot}\cdot\vect s_{\bot}}{\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|}\right)^{2j-l'+l},
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and if we want a
|
|
||||||
\begin_inset Formula $\sigma_{l'}^{m'}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
instead, we reverse the sign of
|
|
||||||
\begin_inset Formula $\vect s$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and replace all spherical harmonics with their dual counterparts:
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\sigma_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi^{d_{c}/2}\mathcal{A}\kappa}\frac{\left(2l'+1\right)!!}{\kappa^{l'}}\sum_{\vect K\in\Lambda^{*}}e^{-i\vect k_{\vect K}\cdot\vect s}\sum_{j=0}^{l'}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\sum_{l=\max\left(0,l'-2j\right)}^{l'-j}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2j-l'+l}\frac{\left|\vect k_{\vect K}\right|^{l}}{\left(2l+1\right)!!}\times\\
|
|
||||||
\times\sum_{m=-l}^{l}\ushD lm\left(\uvec{\vect k_{\vect K}}\right)\int\ud\Omega_{\vect r}\,\ush{l'}{m'}\left(\uvec r\right)\ush lm\left(\uvec r\right)\left(\frac{\left|\vect r_{\bot}\right|}{\left|\vect r\right|}\right)^{l'-l}\left(\frac{-\vect r_{\bot}\cdot\vect s_{\bot}}{\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|}\right)^{2j-l'+l},
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and remembering that in the plane wave expansion the
|
|
||||||
\begin_inset Quotes eld
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
duality
|
|
||||||
\begin_inset Quotes erd
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is interchangeable,
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline*}
|
|
||||||
\sigma_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi^{d_{c}/2}\mathcal{A}\kappa}\frac{\left(2l'+1\right)!!}{\kappa^{l'}}\sum_{\vect K\in\Lambda^{*}}e^{-i\vect k_{\vect K}\cdot\vect s}\sum_{j=0}^{l'}\frac{\left(-1\right)^{j}}{j!}\Delta_{j}^{\left(d_{\Lambda}\right)}\left(\frac{\kappa\gamma_{\vect k_{\vect K}}}{2}\right)^{2j}\sum_{l=\max\left(0,l'-2j\right)}^{l'-j}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2j-l'+l}\frac{\left|\vect k_{\vect K}\right|^{l}}{\left(2l+1\right)!!}\times\\
|
|
||||||
\times\sum_{m=-l}^{l}\ush lm\left(\uvec{\vect k_{\vect K}}\right)\underbrace{\int\ud\Omega_{\vect r}\,\ush{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\frac{\left|\vect r_{\bot}\right|}{\left|\vect r\right|}\right)^{l'-l}\left(\frac{-\vect r_{\bot}\cdot\vect s_{\bot}}{\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|}\right)^{2j-l'+l}}_{\equiv A_{l',l,m',m,j}^{\left(d_{\Lambda}\right)}}.
|
|
||||||
\end{multline*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The angular integral is easier to evaluate when
|
|
||||||
\begin_inset Formula $d_{\Lambda}=2$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, because then
|
|
||||||
\begin_inset Formula $\vect r_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is parallel (or antiparallel) to
|
|
||||||
\begin_inset Formula $\vect s_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, which gives
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
A_{l',l,m',m,j}^{\left(2\right)}=\left(-\frac{\vect r_{\bot}\cdot\vect s_{\bot}}{\left|\vect r_{\bot}\cdot\vect s_{\bot}\right|}\right)^{2j-l'+l}\int\ud\Omega_{\vect r}\,\ush{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\frac{\left|\vect r_{\bot}\right|}{\left|\vect r\right|}\right)^{2j}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and if we set the normal of the lattice correspond to the
|
|
||||||
\begin_inset Formula $z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
axis, the azimuthal part of the integral will become zero unless
|
|
||||||
\begin_inset Formula $m'=m$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
for any meaningful spherical harmonics convention, and the polar part for
|
|
||||||
the only nonzero case has a closed-form expression, see e.g.
|
|
||||||
[Linton (A.15)], so one arrives at an expression similar to [Kambe II, (3.15)]
|
|
||||||
\lang english
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{multline}
|
|
||||||
\sigma_{l,m}^{\left(\mathrm{L},\eta\right)}\left(\vect k,\vect s\right)=-\frac{i^{l+1}}{\kappa^{2}\mathcal{A}}\pi^{3/2}2\left(\left(l-m\right)/2\right)!\left(\left(l+m\right)/2\right)!\times\\
|
|
||||||
\times\sum_{\vect K\in\Lambda^{*}}e^{i\vect k_{\vect K}\cdot\vect s}\ush lm\left(\vect k_{\vect K}\right)\sum_{j=0}^{l-\left|m\right|}\left(-1\right)^{j}\gamma_{\vect k_{\vect K}}^{2}{}^{2j+1}\times\\
|
|
||||||
\times\Delta_{j}\left(\frac{\kappa^{2}\gamma_{\vect k_{\vect K}}^{2}}{4\eta^{2}},-i\kappa\gamma_{\vect k_{\vect K}}^{2}s_{\perp}\right)\times\\
|
|
||||||
\times\sum_{\substack{s\\
|
|
||||||
j\le s\le\min\left(2j,l-\left|m\right|\right)\\
|
|
||||||
l-j+\left|m\right|\,\mathrm{evej}
|
|
||||||
}
|
|
||||||
}\frac{1}{\left(2j-s\right)!\left(s-j\right)!}\frac{\left(-\kappa s_{\perp}\right)^{2j-s}\left(\left|\vect k_{\vect K}\right|/\kappa\right)^{l-s}}{\left(\frac{1}{2}\left(l-m-s\right)\right)!\left(\frac{1}{2}\left(l+m-s\right)\right)!}\label{eq:Ewald in 3D long-range part 1D 2D-1}
|
|
||||||
\end{multline}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
where
|
|
||||||
\begin_inset Formula $s_{\perp}\equiv\vect s\cdot\uvec z=\vect s_{\bot}\cdot\uvec z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
If
|
|
||||||
\begin_inset Formula $d_{\Lambda}=1$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, the angular becomes more complicated to evaluate due to the different
|
|
||||||
behaviour of the
|
|
||||||
\begin_inset Formula $\vect r_{\bot}\cdot\vect s_{\bot}/\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
factor.
|
|
||||||
The choice of coordinates can make most of the terms dissapear: if the
|
|
||||||
lattice is set parallel to the
|
|
||||||
\begin_inset Formula $z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
axis,
|
|
||||||
\begin_inset Formula $A_{l',l,m',m,j}^{\left(1\right)}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is zero unless
|
|
||||||
\begin_inset Formula $m=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, but one still has
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
A_{l',l,m',0,j}^{\left(1\right)}=\pi\delta_{m',l'-l-2j}\lambda'_{l0}\lambda_{l'm'}\int_{-1}^{1}\ud x\,P_{l'}^{m'}\left(x\right)P_{l}^{0}\left(x\right)\left(1-x^{2}\right)^{\frac{l'-l}{2}}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
where
|
|
||||||
\begin_inset Formula $\lambda_{lm}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
are constants depending on the conventions for spherical harmonics.
|
|
||||||
This does not seem to have such a nice closed-form expression as in the
|
|
||||||
2D case, but it can be evaluated e.g.
|
|
||||||
using the common recurrence relations for associated Legendre polynomials.
|
|
||||||
Of course when
|
|
||||||
\begin_inset Formula $\vect s=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, one gets relatively nice closed expressions, such as those in [Linton].
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -1,976 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\float_placement class
|
|
||||||
\float_alignment class
|
|
||||||
\paperfontsize default
|
|
||||||
\spacing single
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize a4paper
|
|
||||||
\use_geometry true
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\biblio_style plain
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\leftmargin 2cm
|
|
||||||
\topmargin 2cm
|
|
||||||
\rightmargin 2cm
|
|
||||||
\bottommargin 2cm
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Title
|
|
||||||
1D in 3D Ewald sum
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ud}{\mathrm{d}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\abs}[1]{\left|#1\right|}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vect}[1]{\mathbf{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\uvec}[1]{\hat{\mathbf{#1}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ush}[2]{Y_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ushD}[2]{Y'_{#1}^{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vsh}{\vect A}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vshD}{\vect{A'}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkc}{\vect y}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcout}{\vect u}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wfkcreg}{\vect v}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcreg}{a}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\wckcout}{f}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
General formula
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
We need to find the expansion coefficient
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{equation}
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{i}{\kappa j_{l'}\left(\kappa\left|\vect r\right|\right)}\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(\kappa)}\left(\vect s+\vect r,\vect k\right)\ushD{l'}{m'}\left(\uvec r\right).\label{eq:tau extraction formula}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
[Linton, (2.24)] with slightly modified notation and setting
|
|
||||||
\begin_inset Formula $d_{c}=2$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
:
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect r\right)=-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect r}\int_{1/\eta}^{\infty e^{i\pi/4}}e^{-\kappa^{2}\gamma^{2}t^{2}/4}e^{-\left|\vect r^{\bot}\right|^{2}/t^{2}}t^{-1}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
or, evaluated at point
|
|
||||||
\begin_inset Formula $\vect s+\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
instead
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\left(\vect s+\vect r\right)}\int_{1/\eta}^{\infty e^{i\pi/4}}e^{-\kappa^{2}\gamma^{2}t^{2}/4}e^{-\left|\vect s^{\bot}+\vect r^{\bot}\right|^{2}/t^{2}}t^{-1}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The integral can be by substitutions taken into the form
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{2\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta}^{\infty\exp\left(i\pi/4\right)}e^{-\kappa^{2}\gamma_{m}^{2}\zeta^{2}/4}e^{-\left|\vect r_{\bot}\right|^{2}/\zeta^{2}}\zeta^{1-d_{c}}\ud\zeta
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try substitution
|
|
||||||
\begin_inset Formula $t=\zeta^{2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
: then
|
|
||||||
\begin_inset Formula $\ud t=2\zeta\,\ud\zeta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(
|
|
||||||
\begin_inset Formula $\ud\zeta=\ud t/2t^{1/2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
) and
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\kappa^{2}\gamma_{m}^{2}t/4}e^{-\left|\vect r_{\bot}\right|^{2}/t}t^{\frac{-d_{c}}{2}}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try subst.
|
|
||||||
|
|
||||||
\begin_inset Formula $\tau=k^{2}\gamma_{m}^{2}/4$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\left(\frac{\kappa\gamma_{m}}{2}\right)^{d_{c}}\int_{\kappa^{2}\gamma_{m}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{m}^{2}/4\tau}\tau^{\frac{-d_{c}}{2}}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\left(\vect s+\vect r\right)}\int_{\kappa^{2}\gamma_{m}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{m}^{2}/4\tau}\tau^{-1}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Foot
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
[Linton, (2.25)] with slightly modified notation:
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect r\right)=-\frac{1}{\sqrt{4\pi}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect r}\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}\left|\vect r^{\bot}\right|^{2j}}{j!}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2j-1}\Gamma_{j\vect K}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
We want to express an expansion in a shifted point, so let's substitute
|
|
||||||
|
|
||||||
\begin_inset Formula $\vect r\to\vect s+\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)=-\frac{1}{\sqrt{4\pi}\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\left(\vect s+\vect r\right)}\sum_{j=0}^{\infty}\frac{\left(-1\right)^{j}\left|\vect s^{\bot}+\vect r^{\bot}\right|^{2j}}{j!}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2j-1}\Gamma_{j\vect K}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's do the integration to get
|
|
||||||
\begin_inset Formula $\tau_{l}^{m}\left(\vect s,\vect k\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\left(\vect s+\vect r\right)}\int_{\kappa^{2}\gamma_{\vect K}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\tau^{-1}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The
|
|
||||||
\begin_inset Formula $\vect r$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-dependent plane wave factor can be also written as
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
e^{i\vect K\cdot\vect r} & =e^{i\left|\vect K\right|\vect r\cdot\uvec K}=4\pi\sum_{lm}i^{l}\mathcal{J}'_{l}^{m}\left(\left|\vect K\right|\vect r\right)\ush lm\left(\uvec K\right)\\
|
|
||||||
& =4\pi\sum_{lm}i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ushD lm\left(\uvec{\vect r}\right)\ush lm\left(\uvec K\right)
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
or the other way around
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
e^{i\vect K\cdot\vect r}=4\pi\sum_{lm}i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush lm\left(\uvec{\vect r}\right)\ushD lm\left(\uvec K\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
so
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ushD lm\left(\uvec r\right)\ush lm\left(\uvec K\right)\int_{\kappa^{2}\gamma_{\vect K}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\tau^{-1}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
We also have
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
e^{-\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau} & =e^{-\left(\left|\vect s_{\bot}\right|^{2}+\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\\
|
|
||||||
& =e^{-\left|\vect s_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\sum_{n=0}^{\infty}\frac{1}{n!}\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}}{4\tau}\right)^{n},
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
hence
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right) & =-\frac{1}{2\pi\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ushD lm\left(\uvec r\right)\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{1}{n!}\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}}{4}\right)^{n}\underbrace{\int_{\kappa^{2}\gamma_{\vect K}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect s_{\bot}\right|^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\tau^{-1-n}\ud\tau}_{\Delta_{n+1/2}}\\
|
|
||||||
& =-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{\Delta_{n+1/2}}{n!}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}}{4}\right)^{n}\\
|
|
||||||
& =-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{k=0}^{n}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left|\vect r_{\bot}\right|^{2(n-k)}\left(2\vect r_{\bot}\cdot\vect s_{\bot}\right)^{k}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
If we label
|
|
||||||
\begin_inset Formula $\left|\vect r_{\bot}\right|\left|\vect s_{\bot}\right|\cos\varphi\equiv\vect r_{\bot}\cdot\vect s_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{k=0}^{n}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left|\vect r_{\bot}\right|^{2n-k}\left(\cos\varphi\right)^{k}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and if we label
|
|
||||||
\begin_inset Formula $\left|\vect r\right|\sin\vartheta\equiv\left|\vect r_{\bot}\right|$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{k=0}^{n}\left|\vect r\right|^{2n-k}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{2n-k}\left(\cos\varphi\right)^{k}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Now let's put the RHS into
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:tau extraction formula"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and try eliminating some sum by taking the limit
|
|
||||||
\begin_inset Formula $\left|\vect r\right|\to0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
We have
|
|
||||||
\begin_inset Formula $j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\sim\left(\left|\vect K\right|\left|\vect r\right|\right)^{l}/\left(2l+1\right)!!$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
; the denominator from
|
|
||||||
\begin_inset CommandInset ref
|
|
||||||
LatexCommand eqref
|
|
||||||
reference "eq:tau extraction formula"
|
|
||||||
plural "false"
|
|
||||||
caps "false"
|
|
||||||
noprefix "false"
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
behaves like
|
|
||||||
\begin_inset Formula $j_{l'}\left(\kappa\left|\vect r\right|\right)\sim\left(\kappa\left|\vect r\right|\right)^{l'}/\left(2l'+1\right)!!.$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The leading terms are hence those with
|
|
||||||
\begin_inset Formula $\left|\vect r\right|^{l-l'+2n-k}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
So
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi\mathcal{A}\kappa^{1+l'}}\left(2l'+1\right)!!\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}\frac{\left|\vect K\right|^{l}}{\left(2l+1\right)!!}\ush lm\left(\uvec K\right)\sum_{n=0}^{\infty}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{k=0}^{n}\delta_{l'-l,2n-k}\left(2\left|\vect s_{\bot}\right|\right)^{k}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{l'-l}\left(\cos\varphi\right)^{k}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's now focus on rearranging the sums; we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')\equiv\sum_{l=0}^{\infty}\sum_{n=0}^{\infty}\sum_{k=0}^{n}\delta_{l'-l,2n-k}f(l',l,n,k)=\sum_{l=0}^{\infty}\sum_{n=0}^{\infty}\sum_{k=0}^{n}\delta_{l'-l,2n-k}f(l',l,n,2n-l'+l)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
We have
|
|
||||||
\begin_inset Formula $0\le k\le n$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence
|
|
||||||
\begin_inset Formula $0\le2n-l'+l\le n$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence
|
|
||||||
\begin_inset Formula $-2n\le-l'+l\le-n$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, hence also
|
|
||||||
\begin_inset Formula $l'-2n\le l\le l'-n$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, which gives the opportunity to swap the
|
|
||||||
\begin_inset Formula $l,n$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
sums and the
|
|
||||||
\begin_inset Formula $l$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-sum becomes finite; so also consuming
|
|
||||||
\begin_inset Formula $\sum_{k=0}^{n}\delta_{l'-l,2n-k}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
we get
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')=\sum_{n=0}^{\infty}\sum_{l=\max(0,l'-2n)}^{l'-n}f(l',l,n,2n-l'+l).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Finally, we see that the interval of valid
|
|
||||||
\begin_inset Formula $l$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
becomes empty when
|
|
||||||
\begin_inset Formula $l'-n<0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, i.e.
|
|
||||||
|
|
||||||
\begin_inset Formula $n>l'$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
; so we get a finite sum
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
S(l')=\sum_{n=0}^{l'}\sum_{l=\max(0,l'-2n)}^{l'-n}f(l',l,n,2n-l'+l).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Applying rearrangement,
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi\mathcal{A}\kappa^{1+l'}}\left(2l'+1\right)!!\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{n=0}^{l'}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{l=\max\left(0,l'-2n\right)}^{l'-n}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2n-l'+l}\frac{\left|\vect K\right|^{l}}{\left(2l+1\right)!!}\sum_{m=-l}^{l}\ush lm\left(\uvec K\right)\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{l'-l}\left(\cos\varphi\right)^{2n-l'+l}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
Z-aligned lattice
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Now we set some conventions: let the lattice lie on the
|
|
||||||
\begin_inset Formula $z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
axis, so that
|
|
||||||
\begin_inset Formula $\vect s_{\bot},\vect r_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
lie in the
|
|
||||||
\begin_inset Formula $xy$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-plane.
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
(TODO check the meaning of
|
|
||||||
\begin_inset Formula $\vect k$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and possible additional phase factor.)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
If we write
|
|
||||||
\begin_inset Formula $\vect s_{\bot}=\uvec x\left|\vect s_{\bot}\right|\cos\Phi+\uvec y\left|\vect s_{\bot}\right|\sin\Phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $\vect r_{\bot}=\uvec x\left|\vect r_{\bot}\right|\cos\phi+\uvec y\left|\vect r_{\bot}\right|\sin\phi=\uvec x\left|\vect r\right|\sin\theta\cos\phi+\uvec y\left|\vect r\right|\sin\theta\sin\phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have
|
|
||||||
\begin_inset Formula $\varphi=\phi-\Phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, and
|
|
||||||
\begin_inset Formula $\vartheta=\theta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
Also, in this convention
|
|
||||||
\begin_inset Formula $\ush lm\left(\uvec K\right)=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
for
|
|
||||||
\begin_inset Formula $m\ne0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, so
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\tau_{l'}^{m'}\left(\vect s,\vect k\right)=\frac{-i}{2\pi\mathcal{A}\kappa^{1+l'}}\left(2l'+1\right)!!\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{n=0}^{l'}\frac{\left(-1\right)^{n}}{n!}\Delta_{n+1/2}\left(\frac{\kappa\gamma_{\vect K}}{2}\right)^{2n}\sum_{l=\max\left(0,l'-2n\right)}^{l'-n}4\pi i^{l}\left(2\left|\vect s_{\bot}\right|\right)^{2n-l'+l}\frac{\left|\vect K\right|^{l}}{\left(2l+1\right)!!}\ush l0\left(\uvec K\right)\underbrace{\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD l0\left(\uvec r\right)\left(\sin\theta\right)^{l'-l}\left(\cos\varphi\right)^{2n-l'+l}}_{\equiv A_{l',l,n,m'}}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's also fix the (dual) spherical harmonics for now,
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\ushD lm\left(\uvec r\right)=\lambda'_{lm}e^{-im\phi}P_{l}^{-m}\left(\cos\theta\right);
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
the angular integral then becomes (we also use
|
|
||||||
\begin_inset Formula $e^{-im'\phi}=e^{im'\Phi}e^{-im'\varphi}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
)
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
A_{l',l,n,m'} & \equiv\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD l0\left(\uvec r\right)\left(\sin\theta\right)^{l'-l}\left(\cos\varphi\right)^{2n-l'+l}\\
|
|
||||||
& =\lambda'_{l'm'}\lambda'_{l0}e^{im'\Phi}\int_{0}^{\pi}\ud\theta\,\sin\theta P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)\left(\sin\theta\right)^{l'-l}\int_{0}^{2\pi}\ud\varphi\,e^{-im'\varphi}\left(\cos\varphi\right)^{2n-l'+l}.
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
The asimuthal integral evaluates to
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int_{0}^{2\pi}\ud\varphi\,e^{-im'\varphi}\left(\cos\varphi\right)^{2n-l'+l}=\pi\delta_{\left|m'\right|,2n-l'+l}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(note that
|
|
||||||
\begin_inset Formula $2n-l'+l\ge0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
as it's the former index
|
|
||||||
\begin_inset Formula $k$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
).
|
|
||||||
That eliminates one of the two remaining (finite) sums.
|
|
||||||
We are left with the polar integral
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int_{0}^{\pi}\ud\theta\,\sin\theta P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)\left(\sin\theta\right)^{l'-l}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
for which I couldn't find an explicit form yet.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
X-aligned lattice
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
If we instead set
|
|
||||||
\begin_inset Formula $\vect s_{\bot}=\uvec z\left|\vect s_{\bot}\right|\cos\Theta+\uvec y\left|\vect s_{\bot}\right|\sin\Theta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $\vect r_{\bot}=\uvec z\left|\vect r_{\bot}\right|\cos\theta+\uvec y\left|\vect r_{\bot}\right|\sin\theta=\uvec z\left|\vect r\right|\cos\theta+\uvec y\left|\vect r\right|\sin\theta\sin\phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have
|
|
||||||
\begin_inset Formula $\vartheta=\Theta-\theta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD lm\left(\uvec r\right)\left(\sin\vartheta\right)^{l'-l}\left(\cos\varphi\right)^{k}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
BTW:
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\left|\vect r_{\bot}\right|^{2} & =\left|\vect r\right|^{2}-\left|\vect r_{\parallel}\right|^{2}=\left|\vect r\right|^{2}-\left(\vect r\cdot\uvec K\right)^{2},\\
|
|
||||||
\vect r_{\bot}\cdot\vect s_{\bot} & =\vect r\cdot\vect s_{\bot}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Note Note
|
|
||||||
status open
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
Now we set the conventions: let the lattice lie on the
|
|
||||||
\begin_inset Formula $z$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
axis, so that
|
|
||||||
\begin_inset Formula $\vect s_{\bot},\vect r_{\bot}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
lie in the
|
|
||||||
\begin_inset Formula $xy$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
-plane, (TODO check the meaning of
|
|
||||||
\begin_inset Formula $\vect k$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and possible additional phase factor.) If we write
|
|
||||||
\begin_inset Formula $\vect s_{\bot}=\uvec xs_{\bot}\cos\Phi+\uvec ys_{\bot}\sin\Phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $\vect r_{\bot}=\uvec xr_{\bot}\cos\phi+\uvec yr_{\bot}\sin\phi=\uvec xr\sin\theta\cos\phi+\uvec yr\sin\theta\sin\phi$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\left|\vect s_{\bot}+\vect r_{\bot}\right|^{2}=s_{\bot}^{2}+r^{2}\left(\sin\theta\right)^{2}+2s_{\bot}r\sin\theta\cos\left(\phi-\Phi\right).
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
Also, in this convention
|
|
||||||
\begin_inset Formula $\ush lm\left(\uvec K\right)=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
for
|
|
||||||
\begin_inset Formula $m\ne0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, so
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right) & =-\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{lm}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ush l0\left(\uvec K\right)\times\\
|
|
||||||
& \quad\times\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\ushD l0\left(\uvec r\right)\sum_{n=0}^{\infty}\Delta_{n+1/2}\frac{1}{n!}\left(-\frac{\left(\left|\vect r_{\bot}\right|^{2}+2\vect r_{\bot}\cdot\vect s_{\bot}\right)\kappa^{2}\gamma_{\vect K}^{2}}{4}\right)^{n}.
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Let's also fix the spherical harmonics for now,
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\ushD lm\left(\uvec r\right)=\lambda'_{lm}e^{-im\phi}P_{l}^{-m}\left(\cos\theta\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Also, in this convention
|
|
||||||
\begin_inset Formula $\ush lm\left(\uvec K\right)=0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
for
|
|
||||||
\begin_inset Formula $m\ne0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, so
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int\ud\Omega_{\vect r}\,G_{\Lambda}^{(1;\kappa)}\left(\vect s+\vect r\right)\ushD{l'}{m'}\left(\uvec r\right)=-\frac{1}{2\pi\mathcal{A}}\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)\frac{1}{2\pi\mathcal{A}}\sum_{\vect K\in\Lambda^{*}}e^{i\vect K\cdot\vect s}\sum_{l}4\pi i^{l}j_{l}\left(\left|\vect K\right|\left|\vect r\right|\right)\ushD l0\left(\uvec r\right)\ush l0\left(\uvec K\right)\int_{\kappa^{2}\gamma_{\vect K}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left(s_{\bot}^{2}+r_{\bot}^{2}+2s_{\bot}r_{\bot}\cos\left(\phi-\Phi\right)\right)^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\tau^{-1}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
Let's also fix the spherical harmonics for now,
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\ushD lm\left(\uvec r\right)=\lambda'_{lm}e^{-im\phi}P_{l}^{-m}\left(\cos\theta\right)
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
The angular integral (assuming it can be separated from the rest like this)
|
|
||||||
is
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
I_{l'}^{m'}\equiv\int\ud\Omega_{\vect r}\,\ushD{l'}{m'}\left(\uvec r\right)e^{-\left(r_{\bot}^{2}+2s_{\bot}r_{\bot}\cos\left(\phi-\Phi\right)\right)^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
Let's further extract the azimuthal part
|
|
||||||
\begin_inset Formula $\left(w\equiv2r_{\bot}s_{\bot}\kappa^{2}\gamma_{\vect K}^{2}/4\tau\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
e^{-im'\Phi}A_{l'}^{m'}\equiv\int_{0}^{2\pi}e^{-im'\phi}e^{-w\cos\left(\phi-\Phi\right)}\ud\phi=e^{-im'\Phi}\int_{0}^{2\pi}e^{-im'\varphi}e^{-w\cos\varphi}\ud\varphi
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Using [DLMF 10.9.2],
|
|
||||||
\begin_inset Formula $\int_{0}^{2\pi}e^{-im'\varphi}e^{-w\cos\varphi}\ud\varphi=\int_{0}^{2\pi}\cos\left(m'\varphi\right)e^{i(iw)\cos\varphi}=2\pi i^{m'}J_{m'}\left(iw\right)$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
we have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
e^{-m'\Phi}A_{l'}^{m'}=2\pi i^{m'}J_{m'}\left(iw\right),
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
assuming that
|
|
||||||
\begin_inset Formula $w$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is real (which does not necessarily have to be true!); numerical experiments
|
|
||||||
in Sage show that the result is valid also for complex
|
|
||||||
\begin_inset Formula $w$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
\begin_inset Note Note
|
|
||||||
status collapsed
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
A_{l}^{m} & =\int_{0}^{2\pi}e^{-im\varphi}\sum_{n=0}^{\infty}\frac{\left(-w\cos\varphi\right)^{n}}{n!}\ud\varphi\\
|
|
||||||
& =\int_{0}^{2\pi}e^{-im\varphi}\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\left(e^{i\varphi}+e^{-i\varphi}\right)^{n}\ud\varphi\\
|
|
||||||
& =\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\int_{0}^{2\pi}e^{-im\varphi}\sum_{k=0}^{n}\binom{n}{k}e^{ik\varphi}e^{-i\left(n-k\right)\varphi}\ud\varphi\\
|
|
||||||
& =\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\int_{0}^{2\pi}e^{i\left(2k-n-m\right)\varphi}\ud\varphi\\
|
|
||||||
& =2\pi\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\delta_{2k-n-m=0}\\
|
|
||||||
& =2\pi\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\delta_{2k-n-m=0}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\sum_{n=k}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\binom{n}{k}\delta_{2k-n-m=0}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\frac{\left(-w\right)^{2k-m}}{2^{2k-m}\left(2k-m\right)!}\binom{2k-m}{k}\delta_{2k-m\ge k}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\frac{\left(-w\right)^{2k-m}}{2^{2k-m}}\frac{1}{k!\left(k-m\right)!}\delta_{k-m\ge0}\\
|
|
||||||
& =2\pi\sum_{k=\max\left(m,0\right)}^{\infty}\left(-\frac{w}{2}\right)^{2k-m}\frac{1}{k!\left(k-m\right)!}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Note Note
|
|
||||||
status collapsed
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
A_{l}^{m} & =\int_{0}^{2\pi}e^{-im\varphi}\sum_{n=0}^{\infty}\frac{\left(-w\cos\varphi\right)^{n}}{n!}\ud\varphi\\
|
|
||||||
& =\int_{0}^{2\pi}e^{-im\varphi}\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\left(e^{i\varphi}+e^{-i\varphi}\right)^{n}\ud\varphi\\
|
|
||||||
& =\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\int_{0}^{2\pi}e^{-im\varphi}\sum_{k=0}^{n}\binom{n}{k}e^{i\left(n-k\right)\varphi}e^{-ik\varphi}\ud\varphi\\
|
|
||||||
& =\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\int_{0}^{2\pi}e^{i\left(-2k+n-m\right)\varphi}\ud\varphi\\
|
|
||||||
& =2\pi\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\delta_{-2k+n-m=0}\\
|
|
||||||
& =2\pi\sum_{n=0}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\sum_{k=0}^{n}\binom{n}{k}\delta_{-2k+n-m=0}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\sum_{n=k}^{\infty}\frac{\left(-w\right)^{n}}{2^{n}n!}\binom{n}{k}\delta_{-2k+n-m=0}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\frac{\left(-w\right)^{2k+m}}{2^{2k+m}\left(2k+m\right)!}\binom{2k+m}{k}\delta_{2k+m\ge k}\\
|
|
||||||
& =2\pi\sum_{k=0}^{\infty}\frac{\left(-w\right)^{2k+m}}{2^{2k+m}}\frac{1}{k!\left(k+m\right)!}\delta_{k+m\ge0}\\
|
|
||||||
& =2\pi\sum_{k=\max\left(-m,0\right)}^{\infty}\frac{\left(-w\right)^{2k+m}}{2^{2k+m}}\frac{1}{k!\left(k+m\right)!}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Althought it's not superobvious, this sum is symmetric w.r.t.
|
|
||||||
sign change in
|
|
||||||
\begin_inset Formula $m$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Plain Layout
|
|
||||||
Let's do the polar integration next:
|
|
||||||
\begin_inset Formula $r_{\bot}=r\sin\theta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
B_{l'}^{m'}\equiv\int_{0}^{\pi}\sin\theta\ud\theta\,P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)e^{-\left(\sin\theta\right)^{2}r^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau}\left(-\sin\theta\,rs_{\bot}\kappa^{2}\gamma_{\vect K}^{2}/4\tau\right)^{2k-m'}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Label
|
|
||||||
\begin_inset Formula $u\equiv r^{2}\kappa^{2}\gamma_{\vect K}^{2}/4\tau,v\equiv rs_{\bot}\kappa^{2}\gamma_{\vect K}^{2}/4\tau$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
; then
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
B_{l'}^{m'} & =\int_{0}^{\pi}\sin\theta\ud\theta\,P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)e^{-u\left(\sin\theta\right)^{2}}\left(-v\sin\theta\right)^{2k-m'}\\
|
|
||||||
& =\int_{0}^{\pi}\sin\theta\ud\theta\,P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)\left(-v\sin\theta\right)^{2k-m'}\sum_{a=0}^{\infty}\frac{\left(-u\right)^{a}}{a!}\left(\sin\theta\right)^{2a}\\
|
|
||||||
& =\left(-v\right)^{2k-m'}\sum_{a=0}^{\infty}\frac{\left(-u\right)^{a}}{a!}\int_{0}^{\pi}\sin\theta\ud\theta\,P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)\left(\sin\theta\right)^{2a+2k-m'}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
If we now perform the limit
|
|
||||||
\begin_inset Formula $r\to0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and compare the radial parts (incl.
|
|
||||||
those in
|
|
||||||
\begin_inset Formula $u,v$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
) powers, the leading term indices will have
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
l'\sim l+2a+2k-m'
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
so we can fix
|
|
||||||
\begin_inset Formula $2a+2k-m'=l'-l$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and get
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\int_{0}^{\pi}\sin\theta\ud\theta\,P_{l'}^{-m'}\left(\cos\theta\right)P_{l}^{0}\left(\cos\theta\right)\left(\sin\theta\right)^{l'-l}=\begin{cases}
|
|
||||||
0 & l'-l+m'\text{ odd}\\
|
|
||||||
? & l'-l+m'\text{ even}
|
|
||||||
\end{cases}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula $ $
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -1,305 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\paperfontsize default
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize default
|
|
||||||
\use_geometry false
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\uoft}[1]{\mathfrak{F}#1}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\uaft}[1]{\mathfrak{\mathbb{F}}#1}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\usht}[2]{\mathbb{S}_{#1}#2}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\bsht}[2]{\mathrm{S}_{#1}#2}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\sgn}{\operatorname{sgn}}
|
|
||||||
{\mathrm{sgn}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\pht}[2]{\mathfrak{\mathbb{H}}_{#1}#2}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vect}[1]{\mathbf{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ud}{\mathrm{d}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\basis}[1]{\mathfrak{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\dc}[1]{Ш_{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\rec}[1]{#1^{-1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\recb}[1]{#1^{\widehat{-1}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ints}{\mathbb{Z}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\nats}{\mathbb{N}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\reals}{\mathbb{R}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ush}[2]{Y_{#1,#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\hgfr}{\mathbf{F}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\hgf}{F}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ghgf}[2]{\mbox{}_{#1}F_{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ghgfr}[2]{\mbox{}_{#1}\mathbf{F}_{#2}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\ph}{\mathrm{ph}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\kor}[1]{\underline{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\koru}[1]{\utilde{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\swv}{\mathscr{H}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\expint}{\mathrm{E}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{eqnarray}
|
|
||||||
\sigma_{n}^{m(1)} & = & -\frac{i^{n+1}}{2k^{2}\mathscr{A}}\left(-1\right)^{\left(n+m\right)/2}\sqrt{\left(2n+1\right)\left(n-m\right)!\left(n+m\right)!}\times\nonumber \\
|
|
||||||
& & \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}\sum_{j=0}^{\left[\left(n-\left|m\right|/2\right)\right]}\frac{\left(-1\right)^{j}\left(\beta_{pq}/2k\right)^{n-2j}e^{im\phi_{\vect{\beta}_{pq}}}\Gamma_{j,pq}}{j!\left(\frac{1}{2}\left(n-m\right)-j\right)!\left(\frac{1}{2}\left(n+m\right)-j\right)!}\left(\frac{\gamma_{pq}}{2}\right)^{2j-1}\nonumber \\
|
|
||||||
& = & -\frac{i^{n+1}}{2k^{2}\mathscr{A}}\sqrt{\pi}2^{n+1}\left(\left(n-m\right)/2\right)!\left(\left(n+m\right)/2\right)!\times\nonumber \\
|
|
||||||
& & \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}Y_{n}^{m}\left(\frac{\pi}{2},\phi_{\vect{\beta}_{pq}}\right)\sum_{j=0}^{\left[\left(n-\left|m\right|/2\right)\right]}\frac{\left(-1\right)^{j}\left(\beta_{pq}/2k\right)^{n-2j}\Gamma_{j,pq}}{j!\left(\frac{1}{2}\left(n-m\right)-j\right)!\left(\frac{1}{2}\left(n+m\right)-j\right)!}\left(\frac{\gamma_{pq}}{2}\right)^{2j-1}\nonumber \\
|
|
||||||
& = & -\frac{i^{n+1}}{k^{2}\mathscr{A}}\sqrt{\pi}2\left(\left(n-m\right)/2\right)!\left(\left(n+m\right)/2\right)!\times\nonumber \\
|
|
||||||
& & \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}Y_{n}^{m}\left(\frac{\pi}{2},\phi_{\vect{\beta}_{pq}}\right)\sum_{j=0}^{\left[\left(n-\left|m\right|/2\right)\right]}\frac{\left(-1\right)^{j}\left(\beta_{pq}/k\right)^{n-2j}\Gamma_{j,pq}}{j!\left(\frac{1}{2}\left(n-m\right)-j\right)!\left(\frac{1}{2}\left(n+m\right)-j\right)!}\left(\gamma_{pq}\right)^{2j-1}\label{eq:2D Ewald in 3D long-range part}
|
|
||||||
\end{eqnarray}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
For
|
|
||||||
\begin_inset Formula $z\ne0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
& =-\frac{i^{n+1}}{k^{2}\mathscr{A}}\sqrt{\pi}2\left(\left(n-m\right)/2\right)!\left(\left(n+m\right)/2\right)!\\
|
|
||||||
& \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}Y_{n}^{m}\left(\frac{\pi}{2},\phi_{\vect{\beta}_{pq}}\right)\sum_{j=0}^{n-\left|m\right|}\frac{\Delta_{npq}}{j!}\left(-1\right)^{j}\left(\gamma_{pq}\right)^{2j-1}\sum_{s\overset{*}{=}j}^{\min(2j,n-\left|m\right|)}\binom{j}{2j-s}\frac{\left(-\kappa z\right)^{2j-s}\left(\beta_{pq}/k\right)^{n-s}}{\left(\frac{1}{2}\left(n-m-s\right)\right)!\left(\frac{1}{2}\left(n+m-s\right)\right)!}\\
|
|
||||||
& =-\frac{i^{n+1}}{k^{2}\mathscr{A}}\sqrt{\pi}2\left(\left(n-m\right)/2\right)!\left(\left(n+m\right)/2\right)!\\
|
|
||||||
& \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}Y_{n}^{m}\left(\frac{\pi}{2},\phi_{\vect{\beta}_{pq}}\right)\sum_{j=0}^{n-\left|m\right|}\Delta_{npq}\left(\gamma_{pq}\right)^{2j-1}\sum_{s\overset{*}{=}j}^{\min(2j,n-\left|m\right|)}\frac{\left(-1\right)^{j}}{\left(2j-s\right)!\left(s-j\right)!}\frac{\left(-\kappa z\right)^{2j-s}\left(\beta_{pq}/k\right)^{n-s}}{\left(\frac{1}{2}\left(n-m-s\right)\right)!\left(\frac{1}{2}\left(n+m-s\right)\right)!}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Ewald long range integral
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Linton has (2.24):
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{2\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta}^{\infty\exp\left(i\pi/4\right)}e^{-\kappa^{2}\gamma_{m}^{2}\zeta^{2}/4}e^{-\left|\vect r_{\bot}\right|^{2}/\zeta^{2}}\zeta^{1-d_{c}}\ud\zeta
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try substitution
|
|
||||||
\begin_inset Formula $t=\zeta^{2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
: then
|
|
||||||
\begin_inset Formula $\ud t=2\zeta\,\ud\zeta$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(
|
|
||||||
\begin_inset Formula $\ud\zeta=\ud t/2t^{1/2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
) and
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\int_{1/\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\kappa^{2}\gamma_{m}^{2}t/4}e^{-\left|\vect r_{\bot}\right|^{2}/t}t^{\frac{-d_{c}}{2}}\ud t
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Try subst.
|
|
||||||
|
|
||||||
\begin_inset Formula $\tau=k^{2}\gamma_{m}^{2}/4$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
G_{\Lambda}^{\left(1\right)}\left(\vect r\right)=\frac{\pi^{-d_{c}/2}}{4\mathcal{A}}\sum_{\vect K_{m}\in\Lambda^{*}}e^{i\vect K_{m}\cdot\vect r}\left(\frac{\kappa\gamma_{m}}{2}\right)^{d_{c}}\int_{\kappa^{2}\gamma_{m}^{2}/4\eta^{2}}^{\infty\exp\left(i\pi/2\right)}e^{-\tau}e^{-\left|\vect r_{\bot}\right|^{2}\kappa^{2}\gamma_{m}^{2}/4\tau}\tau^{\frac{-d_{c}}{2}}\ud\tau
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -1,386 +0,0 @@
|
||||||
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
||||||
\lyxformat 584
|
|
||||||
\begin_document
|
|
||||||
\begin_header
|
|
||||||
\save_transient_properties true
|
|
||||||
\origin unavailable
|
|
||||||
\textclass article
|
|
||||||
\use_default_options true
|
|
||||||
\maintain_unincluded_children false
|
|
||||||
\language finnish
|
|
||||||
\language_package default
|
|
||||||
\inputencoding utf8
|
|
||||||
\fontencoding auto
|
|
||||||
\font_roman "default" "default"
|
|
||||||
\font_sans "default" "default"
|
|
||||||
\font_typewriter "default" "default"
|
|
||||||
\font_math "auto" "auto"
|
|
||||||
\font_default_family default
|
|
||||||
\use_non_tex_fonts false
|
|
||||||
\font_sc false
|
|
||||||
\font_roman_osf false
|
|
||||||
\font_sans_osf false
|
|
||||||
\font_typewriter_osf false
|
|
||||||
\font_sf_scale 100 100
|
|
||||||
\font_tt_scale 100 100
|
|
||||||
\use_microtype false
|
|
||||||
\use_dash_ligatures true
|
|
||||||
\graphics default
|
|
||||||
\default_output_format default
|
|
||||||
\output_sync 0
|
|
||||||
\bibtex_command default
|
|
||||||
\index_command default
|
|
||||||
\paperfontsize default
|
|
||||||
\use_hyperref false
|
|
||||||
\papersize default
|
|
||||||
\use_geometry false
|
|
||||||
\use_package amsmath 1
|
|
||||||
\use_package amssymb 1
|
|
||||||
\use_package cancel 1
|
|
||||||
\use_package esint 1
|
|
||||||
\use_package mathdots 1
|
|
||||||
\use_package mathtools 1
|
|
||||||
\use_package mhchem 1
|
|
||||||
\use_package stackrel 1
|
|
||||||
\use_package stmaryrd 1
|
|
||||||
\use_package undertilde 1
|
|
||||||
\cite_engine basic
|
|
||||||
\cite_engine_type default
|
|
||||||
\use_bibtopic false
|
|
||||||
\use_indices false
|
|
||||||
\paperorientation portrait
|
|
||||||
\suppress_date false
|
|
||||||
\justification true
|
|
||||||
\use_refstyle 1
|
|
||||||
\use_minted 0
|
|
||||||
\use_lineno 0
|
|
||||||
\index Index
|
|
||||||
\shortcut idx
|
|
||||||
\color #008000
|
|
||||||
\end_index
|
|
||||||
\secnumdepth 3
|
|
||||||
\tocdepth 3
|
|
||||||
\paragraph_separation indent
|
|
||||||
\paragraph_indentation default
|
|
||||||
\is_math_indent 0
|
|
||||||
\math_numbering_side default
|
|
||||||
\quotes_style english
|
|
||||||
\dynamic_quotes 0
|
|
||||||
\papercolumns 1
|
|
||||||
\papersides 1
|
|
||||||
\paperpagestyle default
|
|
||||||
\tablestyle default
|
|
||||||
\tracking_changes false
|
|
||||||
\output_changes false
|
|
||||||
\html_math_output 0
|
|
||||||
\html_css_as_file 0
|
|
||||||
\html_be_strict false
|
|
||||||
\end_header
|
|
||||||
|
|
||||||
\begin_body
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\vect}[1]{\mathbf{#1}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\lang finnish
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\Kambe}[1]{#1^{\mathrm{K}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset FormulaMacro
|
|
||||||
\newcommand{\Linton}[1]{#1^{\mathrm{L}}}
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
Here and in Kambe's papers,
|
|
||||||
\begin_inset Formula $\kappa$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is the wavenumber (
|
|
||||||
\begin_inset Formula $k$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
in Linton).
|
|
||||||
Here
|
|
||||||
\begin_inset Formula $\vect K_{p}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is a point of the reciprocal lattice (
|
|
||||||
\begin_inset Formula $\vect K_{p}=\Kambe{\vect K_{pt}}=\Linton{\vect{\beta}_{\mu}}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
\begin_inset Quotes eld
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Gammas
|
|
||||||
\begin_inset Quotes erd
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
For
|
|
||||||
\begin_inset Formula $\kappa$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
positive,
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Kambe{\Gamma_{p}}\equiv\begin{cases}
|
|
||||||
\sqrt{\kappa^{2}-\left|\vect K_{p}\right|^{2}} & \kappa^{2}-\left|\vect K_{p}\right|^{2}>0\\
|
|
||||||
i\sqrt{\left|\vect K_{p}\right|^{2}-\kappa^{2}} & \kappa^{2}-\left|\vect K_{p}\right|^{2}<0
|
|
||||||
\end{cases}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Linton{\gamma_{\mu}}\equiv\begin{cases}
|
|
||||||
\sqrt{\left(\frac{\vect K_{p}}{\kappa}\right)^{2}-1} & \kappa-\left|\vect K_{p}\right|\le0\\
|
|
||||||
-i\sqrt{1-\left(\frac{\vect K_{p}}{\kappa}\right)^{2}} & \kappa-\left|\vect K_{p}\right|>0
|
|
||||||
\end{cases}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
hence
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Kambe{\Gamma_{p}}=-i\kappa\Linton{\gamma_{\mu}},
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Linton{\gamma_{\mu}}=i\frac{\Kambe{\Gamma_{p}}}{\kappa}.
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
D vs sigma
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
In-plane sums [Linton 2009, (4.5)], replacing
|
|
||||||
\begin_inset Formula $n,m\rightarrow L,M$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $k\rightarrow\kappa$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{eqnarray*}
|
|
||||||
\sigma_{L}^{M(1)} & = & -\frac{i^{L+1}}{2\kappa^{2}\mathscr{A}}\left(-1\right)^{\left(L+M\right)/2}\sqrt{\left(2L+1\right)\left(L-M\right)!\left(L+M\right)!}\times\\
|
|
||||||
& & \times\sum_{\vect K_{pq}\in\Lambda^{*}}^{'}\sum_{j=0}^{\left[\left(L-\left|M\right|/2\right)\right]}\frac{\left(-1\right)^{j}\left(\beta_{pq}/2\kappa\right)^{L-2j}e^{iM\phi_{\vect{\beta}_{pq}}}\Gamma_{j,pq}}{j!\left(\frac{1}{2}\left(L-M\right)-j\right)!\left(\frac{1}{2}\left(L+M\right)-j\right)!}\left(\frac{\gamma_{pq}}{2}\right)^{2j-1}
|
|
||||||
\end{eqnarray*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
[Kambe II, (3.17)], replacing
|
|
||||||
\lang finnish
|
|
||||||
|
|
||||||
\begin_inset Formula $n\rightarrow j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
,
|
|
||||||
\lang finnish
|
|
||||||
|
|
||||||
\begin_inset Formula $A\rightarrow\mathscr{A}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $\vect K_{pt}\to\vect K_{p}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
,
|
|
||||||
\begin_inset Formula $\Gamma\left(\frac{1}{2}-j,e^{-i\pi}\Gamma_{p}^{2}\omega/2\right)\to\Gamma_{j,p}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and performing little typographic modifications
|
|
||||||
\lang english
|
|
||||||
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
D_{LM} & =-\frac{1}{\mathscr{A}\kappa}i^{\left|M\right|+1}2^{-L}\sqrt{\left(2L+1\right)\left(L+\left|M\right|\right)!\left(L-\left|M\right|\right)!}\times\\
|
|
||||||
& \quad\times\sum_{p}e^{i\vect K_{p}\cdot\vect c_{ijt}}e^{-iM\phi_{K_{p}}}\sum_{j=0}^{\left(L-\left|M\right|\right)/2}\frac{\left(\Gamma_{p}/\kappa\right)^{2j-1}\left(K_{p}/\kappa\right)^{L-2j}\Gamma_{j,p}}{j!\left(\frac{1}{2}\left(L-\left|M\right|\right)-j\right)!\left(\frac{1}{2}\left(L+\left|M\right|\right)-j\right)!}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
Using the relations between
|
|
||||||
\begin_inset Formula $\Kambe{\Gamma_{p}}=-i\kappa\Linton{\gamma_{\mu}}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, we have (also, we replace the
|
|
||||||
\begin_inset Formula $\mu$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
index with
|
|
||||||
\begin_inset Formula $p$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
)
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
D_{LM} & =-\frac{1}{\mathscr{A}\kappa}i^{\left|M\right|+1}2^{-L}\sqrt{\left(2L+1\right)\left(L+\left|M\right|\right)!\left(L-\left|M\right|\right)!}\times\\
|
|
||||||
& \quad\times\sum_{p}e^{i\vect K_{p}\cdot\vect c_{ijt}}e^{-iM\phi_{K_{p}}}\sum_{j=0}^{\left(L-\left|M\right|\right)/2}\frac{\left(-i\gamma_{p}\right)^{2j-1}\left(K_{p}/\kappa\right)^{L-2j}\Gamma_{j,p}}{j!\left(\frac{1}{2}\left(L-\left|M\right|\right)-j\right)!\left(\frac{1}{2}\left(L+\left|M\right|\right)-j\right)!}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
and now, trying to make the exponents look the same as in Linton,
|
|
||||||
\begin_inset Formula $2^{-1}2^{2j-L}2^{1-2j}=2^{-L}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(OK),
|
|
||||||
\begin_inset Formula $K_{p}^{L-2j}=K_{p}^{L-2j}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(OK),
|
|
||||||
\begin_inset Formula
|
|
||||||
\begin{align*}
|
|
||||||
D_{LM} & =-\frac{1}{2\kappa\mathscr{A}}i^{\left|M\right|+1}\sqrt{\left(2L+1\right)\left(L+\left|M\right|\right)!\left(L-\left|M\right|\right)!}\times\\
|
|
||||||
& \quad\times\sum_{p}e^{i\vect K_{p}\cdot\vect c_{ij}}e^{-iM\phi_{K_{p}}}\sum_{j=0}^{\left(L-\left|M\right|\right)/2}\frac{\left(-i\right)^{2j-1}\left(K_{p}/2\kappa\right)^{L-2j}\Gamma_{j,p}}{j!\left(\frac{1}{2}\left(L-\left|M\right|\right)-j\right)!\left(\frac{1}{2}\left(L+\left|M\right|\right)-j\right)!}\left(\frac{\gamma_{p}}{2}\right)^{2j-1}
|
|
||||||
\end{align*}
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
There are now these differences left:
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Itemize
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Additional
|
|
||||||
\begin_inset Formula $\kappa$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
factor in
|
|
||||||
\begin_inset Formula $D_{LM}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Itemize
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
\begin_inset Formula $i^{L+1}\left(-1\right)^{\left(L+M\right)/2}\left(-1\right)^{j}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
vs.
|
|
||||||
|
|
||||||
\begin_inset Formula $i^{\left|M\right|+1}\left(-i\right)^{2j-1}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Itemize
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Opposite phase in the angular part.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Itemize
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Plane wave factor in
|
|
||||||
\begin_inset Formula $D_{LM}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
|
|
||||||
\lang english
|
|
||||||
Let's look at the
|
|
||||||
\begin_inset Formula $i,-1$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
factors (note that
|
|
||||||
\begin_inset Formula $L+M$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
is odd):
|
|
||||||
\begin_inset Formula $\left(-i\right)^{2j}=\left(-1\right)^{j},$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
leaving
|
|
||||||
\begin_inset Formula $i^{L+1}\left(-1\right)^{\left(L+M\right)/2}$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
vs.
|
|
||||||
|
|
||||||
\begin_inset Formula $i^{\left|M\right|+1}i$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
.
|
|
||||||
So there is might be a phase difference due to different conventions, but
|
|
||||||
it does not depend on
|
|
||||||
\begin_inset Formula $j$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
, so one should be able to transplant the
|
|
||||||
\begin_inset Formula $z\ne0$
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
sum from Kambe without major problems.
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Section
|
|
||||||
Ewald parameter (integration limits)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\begin_layout Standard
|
|
||||||
\begin_inset Formula
|
|
||||||
\[
|
|
||||||
\Linton{\eta}=\sqrt{\frac{1}{2\Kambe{\omega}}}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\end_inset
|
|
||||||
|
|
||||||
(Based on comparison of some function arguments, not checked.)
|
|
||||||
\end_layout
|
|
||||||
|
|
||||||
\end_body
|
|
||||||
\end_document
|
|
|
@ -7,35 +7,25 @@ find_package(LAPACK REQUIRED)
|
||||||
# and other not very relevant warnings
|
# and other not very relevant warnings
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-in-bool-context -Wno-comment")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-in-bool-context -Wno-comment")
|
||||||
|
|
||||||
# version file
|
|
||||||
include(GetGitRevisionDescription)
|
|
||||||
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.c.in" "${CMAKE_CURRENT_BINARY_DIR}/version.c" @ONLY)
|
|
||||||
list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/version.c" version.h)
|
|
||||||
|
|
||||||
#includes
|
#includes
|
||||||
set (DIRS ${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS})
|
set (DIRS ${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS})
|
||||||
include_directories(${DIRS})
|
include_directories(${DIRS})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_library (qpms SHARED translations.c tmatrices.c vecprint.c vswf.c wigner.c ewald.c
|
add_library (qpms SHARED translations.c tmatrices.c vecprint.c vswf.c wigner.c ewald.c
|
||||||
ewaldsf.c pointgroups.c latticegens.c
|
ewaldsf.c pointgroups.c latticegens.c
|
||||||
lattices2d.c gaunt.c error.c legendre.c symmetries.c vecprint.c
|
lattices2d.c gaunt.c error.c legendre.c symmetries.c vecprint.c
|
||||||
bessel.c own_zgemm.c parsing.c scatsystem.c materials.c drudeparam_data.c
|
bessel.c own_zgemm.c parsing.c scatsystem.c materials.c drudeparam_data.c
|
||||||
lll.c beyn.c trivialgroup.c version.c
|
lll.c beyn.c scatsys_translation_booster.c
|
||||||
)
|
)
|
||||||
use_c99()
|
use_c99()
|
||||||
|
|
||||||
set(LIBS ${LIBS} ${GSL_LIBRARIES} ${GSLCBLAS_LIBRARIES})
|
set(LIBS ${LIBS} ${GSL_LIBRARIES} ${GSLCBLAS_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries (qpms
|
target_link_libraries (qpms
|
||||||
${GSL_LIBRARIES}
|
gsl
|
||||||
${LAPACK_LIBRARIES}
|
lapack
|
||||||
${BLAS_LIBRARIES}
|
blas
|
||||||
${QPMS_AMOSLIB}
|
amos
|
||||||
Faddeeva
|
|
||||||
)
|
)
|
||||||
target_include_directories (qpms PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories (qpms PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from pkg_resources import get_distribution
|
||||||
|
__version__ = get_distribution('qpms').version
|
||||||
|
|
||||||
import os as __os
|
import os as __os
|
||||||
from sys import platform as __platform
|
from sys import platform as __platform
|
||||||
|
@ -5,7 +7,7 @@ from sys import platform as __platform
|
||||||
import warnings as __warnings
|
import warnings as __warnings
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .qpms_c import PointGroup, FinitePointGroup, FinitePointGroupElement, Particle, scatsystem_set_nthreads, ScatteringSystem, ScatteringMatrix, pitau, set_gsl_pythonic_error_handling, pgsl_ignore_error, gamma_inc, lll_reduce, qpms_library_version
|
from .qpms_c import PointGroup, FinitePointGroup, FinitePointGroupElement, Particle, scatsystem_set_nthreads, ScatteringSystem, ScatteringMatrix, pitau, set_gsl_pythonic_error_handling, pgsl_ignore_error, gamma_inc, lll_reduce, ScatteringSystemCachingMode
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
if __platform == "linux" or __platform == "linux2":
|
if __platform == "linux" or __platform == "linux2":
|
||||||
if 'LD_LIBRARY_PATH' not in __os.environ.keys():
|
if 'LD_LIBRARY_PATH' not in __os.environ.keys():
|
||||||
|
@ -22,12 +24,7 @@ from .cymaterials import MaterialInterpolator, EpsMu, LorentzDrudeModel, lorentz
|
||||||
from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType, VSWFType
|
from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType, VSWFType
|
||||||
from .cywaves import vswf_single
|
from .cywaves import vswf_single
|
||||||
|
|
||||||
def __version__():
|
from .qpms_p import * # maybe don't import automatically in the future (adds around 0.5 s delay)
|
||||||
from pkg_resources import get_distribution
|
|
||||||
librev = qpms_library_version()
|
|
||||||
return get_distribution('qpms').version + (("lr:"+librev) if librev else "")
|
|
||||||
|
|
||||||
#from .qpms_p import * # don't import automatically (adds around 0.5 s delay and depends on scipy)
|
|
||||||
from .constants import *
|
from .constants import *
|
||||||
|
|
||||||
# legacy code which brutally slows down the whole package init:
|
# legacy code which brutally slows down the whole package init:
|
||||||
|
|
494
qpms/argproc.py
494
qpms/argproc.py
|
@ -1,17 +1,9 @@
|
||||||
'''
|
'''
|
||||||
Common snippets for argument processing in command line scripts.
|
Common snippets for argument processing in command line scripts; legacy scripts use scripts_common.py instead.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
|
|
||||||
def flatten(S):
|
|
||||||
if S == []:
|
|
||||||
return S
|
|
||||||
if isinstance(S[0], list):
|
|
||||||
return flatten(S[0]) + flatten(S[1:])
|
|
||||||
return S[:1] + flatten(S[1:])
|
|
||||||
|
|
||||||
def make_action_sharedlist(opname, listname):
|
def make_action_sharedlist(opname, listname):
|
||||||
class opAction(argparse.Action):
|
class opAction(argparse.Action):
|
||||||
|
@ -21,40 +13,6 @@ def make_action_sharedlist(opname, listname):
|
||||||
getattr(args, listname).append((opname, values))
|
getattr(args, listname).append((opname, values))
|
||||||
return opAction
|
return opAction
|
||||||
|
|
||||||
def make_dict_action(argtype=None, postaction='store', first_is_key=True):
|
|
||||||
class DictAction(argparse.Action):
|
|
||||||
#def __init__(self, option_strings, dest, nargs=None, **kwargs):
|
|
||||||
# if nargs is not None:
|
|
||||||
# raise ValueError("nargs not allowed")
|
|
||||||
# super(DictAction, self).__init__(option_strings, dest, **kwargs)
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
if first_is_key: # For the labeled versions
|
|
||||||
key = values[0]
|
|
||||||
vals = values[1:]
|
|
||||||
else: # For the default values
|
|
||||||
key = None
|
|
||||||
vals = values
|
|
||||||
if argtype is not None:
|
|
||||||
if (first_is_key and self.nargs == 2) or (not first_is_key and self.nargs == 1):
|
|
||||||
vals = argtype(vals[0]) # avoid having lists in this case
|
|
||||||
else:
|
|
||||||
vals = [argtype(val) for val in vals]
|
|
||||||
ledict = getattr(namespace, self.dest, {})
|
|
||||||
if ledict is None:
|
|
||||||
ledict = {}
|
|
||||||
if postaction=='store':
|
|
||||||
ledict[key] = vals
|
|
||||||
elif postaction=='append':
|
|
||||||
lelist = ledict.get(key, [])
|
|
||||||
lelist.append(vals)
|
|
||||||
ledict[key] = lelist
|
|
||||||
setattr(namespace, self.dest, ledict)
|
|
||||||
return DictAction
|
|
||||||
|
|
||||||
|
|
||||||
class ArgumentProcessingError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class AppendTupleAction(argparse.Action):
|
class AppendTupleAction(argparse.Action):
|
||||||
''' A variation on the 'append' builtin action from argparse, but uses tuples for the internal groupings instead of lists '''
|
''' A variation on the 'append' builtin action from argparse, but uses tuples for the internal groupings instead of lists '''
|
||||||
def __call__(self, parser, args, values, option_string=None):
|
def __call__(self, parser, args, values, option_string=None):
|
||||||
|
@ -62,299 +20,51 @@ class AppendTupleAction(argparse.Action):
|
||||||
setattr(args, self.dest, list())
|
setattr(args, self.dest, list())
|
||||||
getattr(args, self.dest).append(tuple(values))
|
getattr(args, self.dest).append(tuple(values))
|
||||||
|
|
||||||
def float_range(string):
|
|
||||||
"""Tries to parse a string either as one individual float value
|
|
||||||
or one of the following patterns:
|
|
||||||
|
|
||||||
first:last:increment
|
|
||||||
first:last|steps
|
|
||||||
first:last
|
|
||||||
|
|
||||||
(The last one is equivalent to first:last|50.)
|
|
||||||
Returns either float or numpy array.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
res = float(string)
|
|
||||||
return res
|
|
||||||
except ValueError:
|
|
||||||
import re
|
|
||||||
steps = None
|
|
||||||
match = re.match(r's?([^:]+):([^|]+)\|(.+)', string)
|
|
||||||
if match:
|
|
||||||
steps = int(match.group(3))
|
|
||||||
else:
|
|
||||||
match = re.match(r's?([^:]+):([^:]+):(.+)', string)
|
|
||||||
if match:
|
|
||||||
increment = float(match.group(3))
|
|
||||||
else:
|
|
||||||
match = re.match(r's?([^:]+):(.+)', string)
|
|
||||||
if match:
|
|
||||||
steps = 50
|
|
||||||
else:
|
|
||||||
argparse.ArgumentTypeError('Invalid float/sequence format: "%s"' % string)
|
|
||||||
first = float(match.group(1))
|
|
||||||
last = float(match.group(2))
|
|
||||||
import numpy as np
|
|
||||||
if steps is not None:
|
|
||||||
return np.linspace(first, last, num=steps)
|
|
||||||
else:
|
|
||||||
return np.arange(first, last, increment)
|
|
||||||
|
|
||||||
def int_or_None(string):
|
|
||||||
"""Tries to parse a string either as an int or None (if it contains only whitespaces)"""
|
|
||||||
try:
|
|
||||||
return int(string)
|
|
||||||
except ValueError as ve:
|
|
||||||
if string.strip() == '':
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
raise ve
|
|
||||||
|
|
||||||
def sslice(string):
|
|
||||||
"""Tries to parse a string either as one individual int value
|
|
||||||
or one of the following patterns:
|
|
||||||
|
|
||||||
first:last:increment
|
|
||||||
first:last
|
|
||||||
|
|
||||||
first, last and increment must be parseable as ints
|
|
||||||
or be empty (then
|
|
||||||
|
|
||||||
In each case, 's' letter can be prepended to the whole string to avoid
|
|
||||||
argparse interpreting this as a new option (if the argument contains
|
|
||||||
'-' or '+').
|
|
||||||
|
|
||||||
Returns either int or slice containing ints or Nones.
|
|
||||||
"""
|
|
||||||
if string[0] == 's':
|
|
||||||
string = string[1:]
|
|
||||||
try:
|
|
||||||
res = int(string)
|
|
||||||
return res
|
|
||||||
except ValueError:
|
|
||||||
import re
|
|
||||||
match = re.match(r'([^:]*):([^:]*):(.*)', string)
|
|
||||||
if match:
|
|
||||||
step = int_or_None(match.group(3))
|
|
||||||
else:
|
|
||||||
match = re.match(r'([^:]*):(.*)', string)
|
|
||||||
if match:
|
|
||||||
step = None
|
|
||||||
else:
|
|
||||||
argparse.ArgumentTypeError('Invalid int/slice format: "%s"' % string)
|
|
||||||
start = int_or_None(match.group(1))
|
|
||||||
stop = int_or_None(match.group(2))
|
|
||||||
return slice(start, stop, step)
|
|
||||||
|
|
||||||
def sfloat(string):
|
|
||||||
'''Tries to match a float, or a float with prepended 's'
|
|
||||||
|
|
||||||
Used as a workaraound for argparse's negative number matcher, which does not recognize
|
|
||||||
scientific notation.
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
res = float(string)
|
|
||||||
except ValueError as exc:
|
|
||||||
if string[0] == 's':
|
|
||||||
res = float(string[1:])
|
|
||||||
else: raise exc
|
|
||||||
return res
|
|
||||||
|
|
||||||
def sint(string):
|
|
||||||
'''Tries to match an int, or an int with prepended 's'
|
|
||||||
|
|
||||||
Used as a workaraound for argparse's negative number matcher if '+' is used as a
|
|
||||||
prefix
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
res = int(string)
|
|
||||||
except ValueError as exc:
|
|
||||||
if string[0] == 's':
|
|
||||||
res = int(string[1:])
|
|
||||||
else: raise exc
|
|
||||||
return res
|
|
||||||
|
|
||||||
def material_spec(string):
|
|
||||||
"""Tries to parse a string as a material specification, i.e. a
|
|
||||||
real or complex number or one of the string in built-in Lorentz-Drude models.
|
|
||||||
|
|
||||||
Tries to interpret the string as 1) float, 2) complex, 3) Lorentz-Drude key.
|
|
||||||
Raises argparse.ArgumentTypeError on failure.
|
|
||||||
"""
|
|
||||||
from .cymaterials import lorentz_drude
|
|
||||||
if string in lorentz_drude.keys():
|
|
||||||
return string
|
|
||||||
else:
|
|
||||||
try: lemat = float(string)
|
|
||||||
except ValueError:
|
|
||||||
try: lemat = complex(string)
|
|
||||||
except ValueError as ve:
|
|
||||||
raise argparse.ArgumentTypeError("Material specification must be a supported material name %s, or a number" % (str(lorentz_drude.keys()),)) from ve
|
|
||||||
return lemat
|
|
||||||
|
|
||||||
class ArgParser:
|
class ArgParser:
|
||||||
''' Common argument parsing engine for QPMS python CLI scripts. '''
|
''' Common argument parsing engine for QPMS python CLI scripts. '''
|
||||||
|
|
||||||
def __add_planewave_argparse_group(ap):
|
|
||||||
pwgrp = ap.add_argument_group('Incident wave specification', """
|
|
||||||
Incident wave direction is given in terms of ISO polar and azimuthal angles θ, φ,
|
|
||||||
which translate into cartesian coordinates as r̂ = (x, y, z) = (sin(θ) cos(φ), sin(θ) sin(φ), cos(θ)).
|
|
||||||
|
|
||||||
Wave polarisation is given in terms of parameters ψ, χ, where ψ is the angle between a polarisation
|
|
||||||
ellipse axis and meridian tangent θ̂, and tg χ determines axes ratio;
|
|
||||||
the electric field in the origin is then
|
|
||||||
|
|
||||||
E⃗ = cos(χ) (cos(ψ) θ̂ + sin(ψ) φ̂) + i sin(χ) (sin(ψ) θ̂ + cos(ψ) φ̂).
|
|
||||||
|
|
||||||
All the angles are given as multiples of π/2.
|
|
||||||
""" # TODO EXAMPLES
|
|
||||||
)
|
|
||||||
pwgrp.add_argument("-φ", "--phi", type=float, default=0,
|
|
||||||
help='Incident wave asimuth in multiples of π/2.')
|
|
||||||
pwgrp.add_argument("-θ", "--theta", type=float_range, default=0,
|
|
||||||
help='Incident wave polar angle in multiples of π/2. This might be a sequence in format FIRST:LAST:INCREMENT.')
|
|
||||||
pwgrp.add_argument("-ψ", "--psi", type=float, default=0,
|
|
||||||
help='Angle between polarisation ellipse axis and meridian tangent θ̂ in multiples of π/2.')
|
|
||||||
pwgrp.add_argument("-χ", "--chi", type=float, default=0,
|
|
||||||
help='Polarisation parameter χ in multiples of π/2. 0 for linear, 0.5 for circular pol.')
|
|
||||||
|
|
||||||
def __add_manyparticle_argparse_group(ap):
|
|
||||||
mpgrp = ap.add_argument_group('Many particle specification', "TODO DOC")
|
|
||||||
mpgrp.add_argument("-p", "--position", nargs='+', action=make_dict_action(argtype=sfloat, postaction='append',
|
|
||||||
first_is_key=False), help="Particle positions, cartesion coordinates (default particle properties)")
|
|
||||||
mpgrp.add_argument("+p", "++position", nargs='+', action=make_dict_action(argtype=sfloat, postaction='append',
|
|
||||||
first_is_key=True), help="Particle positions, cartesian coordinates (labeled)")
|
|
||||||
mpgrp.add_argument("-L", "--lMax", nargs=1, default={},
|
|
||||||
action=make_dict_action(argtype=int, postaction='store', first_is_key=False,),
|
|
||||||
help="Cutoff multipole degree (default)")
|
|
||||||
mpgrp.add_argument("+L", "++lMax", nargs=2,
|
|
||||||
action=make_dict_action(argtype=int, postaction='store', first_is_key=True,),
|
|
||||||
help="Cutoff multipole degree (labeled)")
|
|
||||||
mpgrp.add_argument("-m", "--material", nargs=1, default={},
|
|
||||||
action=make_dict_action(argtype=material_spec, postaction='store', first_is_key=False,),
|
|
||||||
help='particle material (Au, Ag, ... for Lorentz-Drude or number for constant refractive index) (default)')
|
|
||||||
mpgrp.add_argument("+m", "++material", nargs=2,
|
|
||||||
action=make_dict_action(argtype=material_spec, postaction='store', first_is_key=True,),
|
|
||||||
help='particle material (Au, Ag, ... for Lorentz-Drude or number for constant refractive index) (labeled)')
|
|
||||||
mpgrp.add_argument("-r", "--radius", nargs=1, default={},
|
|
||||||
action=make_dict_action(argtype=float, postaction='store', first_is_key=False,),
|
|
||||||
help='particle radius (sphere or cylinder; default)')
|
|
||||||
mpgrp.add_argument("+r", "++radius", nargs=2,
|
|
||||||
action=make_dict_action(argtype=float, postaction='store', first_is_key=True,),
|
|
||||||
help='particle radius (sphere or cylinder; labeled)')
|
|
||||||
mpgrp.add_argument("-H", "--height", nargs=1, default={},
|
|
||||||
action=make_dict_action(argtype=float, postaction='store', first_is_key=False,),
|
|
||||||
help='particle radius (cylinder; default)')
|
|
||||||
mpgrp.add_argument("+H", "++height", nargs=2,
|
|
||||||
action=make_dict_action(argtype=float, postaction='store', first_is_key=True,),
|
|
||||||
help='particle radius (cylinder; labeled)')
|
|
||||||
|
|
||||||
atomic_arguments = {
|
atomic_arguments = {
|
||||||
'rectlattice2d_periods': lambda ap: ap.add_argument("-p", "--period", type=float, nargs='+', required=True, help='square/rectangular lattice periods', metavar=('px','[py]')),
|
'rectlattice2d_periods': lambda ap: ap.add_argument("-p", "--period", type=float, nargs='+', required=True, help='square/rectangular lattice periods', metavar=('px','[py]')),
|
||||||
'rectlattice2d_counts': lambda ap: ap.add_argument("--size", type=int, nargs=2, required=True, help='rectangular array size (particle column, row count)', metavar=('NCOLS', 'NROWS')),
|
'rectlattice2d_counts': lambda ap: ap.add_argument("--size", type=int, nargs=2, required=True, help='rectangular array size (particle column, row count)', metavar=('NCOLS', 'NROWS')),
|
||||||
'single_frequency_eV': lambda ap: ap.add_argument("-f", "--eV", type=float, required=True, help='radiation angular frequency in eV'),
|
'single_frequency_eV': lambda ap: ap.add_argument("-f", "--eV", type=float, required=True, help='radiation angular frequency in eV'),
|
||||||
'multiple_frequency_eV_optional': lambda ap: ap.add_argument("-f", "--eV", type=float, nargs='*', help='radiation angular frequency in eV (additional)'),
|
'single_material': lambda ap: ap.add_argument("-m", "--material", help='particle material (Au, Ag, ... for Lorentz-Drude or number for constant refractive index)', default='Au', required=True),
|
||||||
'seq_frequency_eV': lambda ap: ap.add_argument("-F", "--eV-seq", type=float, nargs=3, required=True, help='uniform radiation angular frequency sequence in eV', metavar=('FIRST', 'INCREMENT', 'LAST')),
|
|
||||||
'real_frequencies_eV_ng': lambda ap: ap.add_argument("-f", "--eV", type=float_range, nargs=1, action='append', required=True, help='Angular frequency (or angular frequency range) in eV'), # nargs='+', action='extend' would be better, but action='extend' requires python>=3.8
|
|
||||||
'single_material': lambda ap: ap.add_argument("-m", "--material", help='particle material (Au, Ag, ... for Lorentz-Drude or number for constant refractive index)', type=material_spec, required=True),
|
|
||||||
'single_radius': lambda ap: ap.add_argument("-r", "--radius", type=float, required=True, help='particle radius (sphere or cylinder)'),
|
'single_radius': lambda ap: ap.add_argument("-r", "--radius", type=float, required=True, help='particle radius (sphere or cylinder)'),
|
||||||
'single_height': lambda ap: ap.add_argument("-H", "--height", type=float, help='cylindrical particle height; if not provided, particle is assumed to be spherical'),
|
'single_height': lambda ap: ap.add_argument("-H", "--height", type=float, help='cylindrical particle height; if not provided, particle is assumed to be spherical'),
|
||||||
'single_kvec2': lambda ap: ap.add_argument("-k", '--kx-lim', nargs=2, type=sfloat, required=True, help='k vector', metavar=('KX_MIN', 'KX_MAX')),
|
'single_kvec2': lambda ap: ap.add_argument("-k", '--kx-lim', nargs=2, type=float, required=True, help='k vector', metavar=('KX_MIN', 'KX_MAX')),
|
||||||
'kpi': lambda ap: 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)"),
|
'kpi': lambda ap: 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)"),
|
||||||
'bg_real_refractive_index': lambda ap: ap.add_argument("-n", "--refractive-index", type=float, default=1., help='background medium strictly real refractive index'),
|
'bg_refractive_index': lambda ap: ap.add_argument("-n", "--refractive-index", type=float, default=1.52, help='background medium refractive index'),
|
||||||
'bg_analytical': lambda ap: ap.add_argument("-B", "--background", type=material_spec, default=1., help="Background medium specification (constant real or complex refractive index, or supported material label)"),
|
|
||||||
'single_lMax': lambda ap: ap.add_argument("-L", "--lMax", type=int, required=True, default=3, help='multipole degree cutoff'),
|
'single_lMax': lambda ap: ap.add_argument("-L", "--lMax", type=int, required=True, default=3, help='multipole degree cutoff'),
|
||||||
'single_lMax_extend': lambda ap: ap.add_argument("--lMax-extend", type=int, required=False, default=6, help='multipole degree cutoff for T-matrix calculation (cylindrical particles only'),
|
'single_lMax_extend': lambda ap: ap.add_argument("--lMax-extend", type=int, required=False, default=6, help='multipole degree cutoff for T-matrix calculation (cylindrical particles only'),
|
||||||
'outfile': lambda ap: ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)'), # TODO consider type=argparse.FileType('w')
|
'outfile': lambda ap: ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)'), # TODO consider type=argparse.FileType('w')
|
||||||
'plot_out': lambda ap: ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)"),
|
'plot_out': lambda ap: ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)"),
|
||||||
'plot_do': lambda ap: ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path"),
|
'plot_do': lambda ap: ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path"),
|
||||||
'lattice2d_basis': lambda ap: ap.add_argument("-b", "--basis-vector", nargs='+', action=AppendTupleAction, help="basis vector in xy-cartesian coordinates (two required)", required=True, type=sfloat, dest='basis_vectors', metavar=('X', 'Y')),
|
'lattice2d_basis': lambda ap: ap.add_argument("-b", "--basis-vector", action=AppendTupleAction, help="basis vector in xy-cartesian coordinates (two required)", dest='basis_vectors', metavar=('X', 'Y')),
|
||||||
'planewave_pol_angles': __add_planewave_argparse_group,
|
|
||||||
'multi_particle': __add_manyparticle_argparse_group,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
feature_sets_available = { # name : (description, dependencies, atoms not in other dependencies, methods called after parsing, "virtual" features provided)
|
feature_sets_available = { # name : (description, dependencies, atoms not in other dependencies, methods called after parsing)
|
||||||
'const_real_background': ("Background medium with constant real refractive index", (), ('bg_real_refractive_index',), ('_eval_const_background_epsmu',), ('background', 'background_analytical')),
|
'background': ("Background medium definition (currently only constant epsilon supported)", (), ('bg_refractive_index',), ('_eval_background_epsmu',)),
|
||||||
'background' : ("Most general background medium specification currently supported", ('background_analytical',), (), (), ()),
|
'single_particle': ("Single particle definition (shape [currently spherical or cylindrical]) and materials, incl. background)", ('background',), ('single_material', 'single_radius', 'single_height', 'single_lMax_extend'), ('_eval_single_tmgen',)),
|
||||||
'background_analytical' : ("Background medium model holomorphic for 'reasonably large' complex frequency areas", (), ('bg_analytical',), ('_eval_analytical_background_epsmugen',), ('background',)),
|
'single_lMax': ("Single particle lMax definition", (), ('single_lMax',), ()),
|
||||||
'single_particle': ("Single particle definition (shape [currently spherical or cylindrical]) and materials, incl. background)", ('background',), ('single_material', 'single_radius', 'single_height', 'single_lMax_extend'), ('_eval_single_tmgen',), ()),
|
'single_omega': ("Single angular frequency", (), ('single_frequency_eV',), ('_eval_single_omega',)),
|
||||||
'multi_particle': ("One or more particle definition (shape [curently spherical or cylindrical]), materials, and positions)", ('background',), ('multi_particle',), ('_process_multi_particle',), ()),
|
'lattice2d': ("Specification of a generic 2d lattice (spanned by the x,y axes)", (), ('lattice2d_basis',), ('_eval_lattice2d',)),
|
||||||
'single_lMax': ("Single particle lMax definition", (), ('single_lMax',), (), ()),
|
'rectlattice2d': ("Specification of a rectangular 2d lattice; conflicts with lattice2d", (), ('rectlattice2d_periods',), ('_eval_rectlattice2d',)),
|
||||||
'single_omega': ("Single angular frequency", (), ('single_frequency_eV',), ('_eval_single_omega',), ()),
|
'rectlattice2d_finite': ("Specification of a rectangular 2d lattice; conflicts with lattice2d", ('rectlattice2d',), ('rectlattice2d_counts',), ()),
|
||||||
'omega_seq': ("Equidistant real frequency range with possibility of adding individual frequencies", (), ('seq_frequency_eV', 'multiple_frequency_eV_optional',), ('_eval_omega_seq',), ()),
|
|
||||||
'omega_seq_real_ng': ("Equidistant real frequency ranges or individual frequencies (new syntax)", (), ('real_frequencies_eV_ng',), ('_eval_omega_seq_real_ng',), ()),
|
|
||||||
'lattice2d': ("Specification of a generic 2d lattice (spanned by the x,y axes)", (), ('lattice2d_basis',), ('_eval_lattice2d',), ()),
|
|
||||||
'rectlattice2d': ("Specification of a rectangular 2d lattice; conflicts with lattice2d", (), ('rectlattice2d_periods',), ('_eval_rectlattice2d',), ()),
|
|
||||||
'rectlattice2d_finite': ("Specification of a rectangular 2d lattice; conflicts with lattice2d", ('rectlattice2d',), ('rectlattice2d_counts',), (), ()),
|
|
||||||
'planewave': ("Specification of a normalised plane wave (typically used for scattering) with a full polarisation state", (), ('planewave_pol_angles',), ("_process_planewave_angles",), ()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, features=[]):
|
def __init__(self, features=[]):
|
||||||
prefix_chars = '+-' if 'multi_particle' in features else '-'
|
self.ap = argparse.ArgumentParser()
|
||||||
self.ap = argparse.ArgumentParser(prefix_chars=prefix_chars)
|
|
||||||
self.features_enabled = set()
|
self.features_enabled = set()
|
||||||
self.call_at_parse_list = []
|
self.call_at_parse_list = []
|
||||||
self.parsed = False
|
self.parsed = False
|
||||||
for feat in features:
|
for feat in features:
|
||||||
self.add_feature(feat)
|
self.add_feature(feat)
|
||||||
self._emg_register = {} # EpsMuGenerator dictionary to avoid recreating equivalent instances; filled by _add_emg()
|
|
||||||
self._tmg_register = {} # TMatrixGenerator dictionary to avoid recreating equivalent instances; filled by _add_tmg()
|
|
||||||
self._bspec_register = {} # Dictionary of used BaseSpecs to keep the equivalent instances unique; filled by _add_bspec()
|
|
||||||
|
|
||||||
def _add_emg(self, emgspec):
|
|
||||||
"""Looks up whether if an EpsMuGenerator from given material_spec has been already registered, and if not, creates a new one"""
|
|
||||||
from .cymaterials import EpsMu, EpsMuGenerator, lorentz_drude
|
|
||||||
if emgspec in self._emg_register.keys():
|
|
||||||
return self._emg_register[emgspec]
|
|
||||||
else:
|
|
||||||
if isinstance(emgspec, (float, complex)):
|
|
||||||
emg = EpsMuGenerator(EpsMu(emgspec**2))
|
|
||||||
else:
|
|
||||||
emg = EpsMuGenerator(lorentz_drude[emgspec])
|
|
||||||
self._emg_register[emgspec] = emg
|
|
||||||
return emg
|
|
||||||
|
|
||||||
def _add_tmg(self, tmgspec):
|
|
||||||
"""Looks up whether if a T-matrix from given T-matrix specification tuple has been already registered, and if not, creates a new one
|
|
||||||
|
|
||||||
T-matrix specification shall be of the form
|
|
||||||
(bg_material_spec, fg_material_spec, shape_spec) where shape_spec is
|
|
||||||
(radius, height, lMax_extend)
|
|
||||||
"""
|
|
||||||
if tmgspec in self._tmg_register.keys():
|
|
||||||
return self._tmg_register[tmgspec]
|
|
||||||
else:
|
|
||||||
from .cytmatrices import TMatrixGenerator
|
|
||||||
bgspec, fgspec, (radius, height, lMax_extend) = tmgspec
|
|
||||||
bg = self._add_emg(bgspec)
|
|
||||||
fg = self._add_emg(fgspec)
|
|
||||||
if height is None:
|
|
||||||
tmgen = TMatrixGenerator.sphere(bg, fg, radius)
|
|
||||||
else:
|
|
||||||
tmgen = TMatrixGenerator.cylinder(bg, fg, radius, height, lMax_extend=lMax_extend)
|
|
||||||
self._tmg_register[tmgspec] = tmgen
|
|
||||||
return tmgen
|
|
||||||
|
|
||||||
def _add_bspec(self, key):
|
|
||||||
if key in self._bspec_register.keys():
|
|
||||||
return self._bspec_register[key]
|
|
||||||
else:
|
|
||||||
from .cybspec import BaseSpec
|
|
||||||
if isinstance(key, BaseSpec):
|
|
||||||
bspec = key
|
|
||||||
elif isinstance(key, int):
|
|
||||||
bspec = self._add_bspec(BaseSpec(lMax=key))
|
|
||||||
else: raise TypeError("Can't register this as a BaseSpec")
|
|
||||||
self._bspec_register[key] = bspec
|
|
||||||
return bspec
|
|
||||||
|
|
||||||
def add_feature(self, feat):
|
def add_feature(self, feat):
|
||||||
if feat not in self.features_enabled:
|
if feat not in self.features_enabled:
|
||||||
if feat not in ArgParser.feature_sets_available:
|
if feat not in ArgParser.feature_sets_available:
|
||||||
raise ValueError("Unknown ArgParser feature: %s" % feat)
|
raise ValueError("Unknown ArgParser feature: %s" % feat)
|
||||||
#resolve dependencies
|
#resolve dependencies
|
||||||
_, deps, atoms, atparse, provides_virtual = ArgParser.feature_sets_available[feat]
|
_, deps, atoms, atparse = ArgParser.feature_sets_available[feat]
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
self.add_feature(dep)
|
self.add_feature(dep)
|
||||||
for atom in atoms: # maybe check whether that atom has already been added sometimes in the future?
|
for atom in atoms: # maybe check whether that atom has already been added sometimes in the future?
|
||||||
|
@ -362,26 +72,16 @@ class ArgParser:
|
||||||
for methodname in atparse:
|
for methodname in atparse:
|
||||||
self.call_at_parse_list.append(methodname)
|
self.call_at_parse_list.append(methodname)
|
||||||
self.features_enabled.add(feat)
|
self.features_enabled.add(feat)
|
||||||
for feat_virt in provides_virtual:
|
|
||||||
self.features_enabled.add(feat_virt)
|
|
||||||
|
|
||||||
def add_argument(self, *args, **kwargs):
|
def add_argument(self, *args, **kwargs):
|
||||||
'''Add a custom argument directly to the standard library ArgParser object'''
|
'''Add a custom argument directly to the standard library ArgParser object'''
|
||||||
return self.ap.add_argument(*args, **kwargs)
|
self.ap.add_argument(*args, **kwargs)
|
||||||
|
|
||||||
def add_argument_group(self, *args, **kwargs):
|
|
||||||
'''Add a custom argument group directly to the standard library ArgParser object'''
|
|
||||||
return self.ap.add_argument_group(*args, **kwargs)
|
|
||||||
|
|
||||||
def parse_args(self, process_data = True, *args, **kwargs):
|
def parse_args(self, process_data = True, *args, **kwargs):
|
||||||
self.args = self.ap.parse_args(*args, **kwargs)
|
self.args = self.ap.parse_args(*args, **kwargs)
|
||||||
if process_data:
|
if process_data:
|
||||||
for method in self.call_at_parse_list:
|
for method in self.call_at_parse_list:
|
||||||
try:
|
getattr(self, method)()
|
||||||
getattr(self, method)()
|
|
||||||
except ArgumentProcessingError:
|
|
||||||
err = sys.exc_info()[1]
|
|
||||||
self.ap.error(str(err))
|
|
||||||
return self.args
|
return self.args
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
@ -390,67 +90,42 @@ class ArgParser:
|
||||||
|
|
||||||
# Methods to initialise the related data structures:
|
# Methods to initialise the related data structures:
|
||||||
|
|
||||||
def _eval_const_background_epsmu(self): # feature: const_real_background
|
def _eval_background_epsmu(self): # feature: background
|
||||||
self.args.background = self.args.refractive_index
|
|
||||||
self._eval_analytical_background_epsmugen()
|
|
||||||
|
|
||||||
def _eval_analytical_background_epsmugen(self): # feature: background_analytical
|
|
||||||
a = self.args
|
|
||||||
from .cymaterials import EpsMu
|
from .cymaterials import EpsMu
|
||||||
if isinstance(a.background, (float, complex)):
|
self.background_epsmu = EpsMu(self.args.refractive_index**2)
|
||||||
self.background_epsmu = EpsMu(a.background**2)
|
|
||||||
self.background_emg = self._add_emg(a.background)
|
|
||||||
|
|
||||||
def _eval_single_tmgen(self): # feature: single_particle
|
def _eval_single_tmgen(self): # feature: single_particle
|
||||||
a = self.args
|
a = self.args
|
||||||
from .cymaterials import EpsMuGenerator, lorentz_drude
|
from .cymaterials import EpsMuGenerator, lorentz_drude
|
||||||
from .cytmatrices import TMatrixGenerator
|
from .cytmatrices import TMatrixGenerator
|
||||||
self.foreground_emg = self._add_emg(a.material)
|
if a.material in lorentz_drude.keys():
|
||||||
self.tmgen = self._add_tmg((a.background, a.material, (a.radius, a.height, a.lMax_extend)))
|
self.foreground_emg = EpsMuGenerator(lorentz_drude[a.material])
|
||||||
self.bspec = self._add_bspec(a.lMax)
|
else:
|
||||||
|
try: lemat = float(a.material)
|
||||||
|
except ValueError:
|
||||||
|
try: lemat = complex(a.material)
|
||||||
|
except ValueError as ve:
|
||||||
|
raise ValueError("--material must be either a label such as 'Ag', 'Au', or a number") from ve
|
||||||
|
a.material = lemat
|
||||||
|
self.foreground_emg = EpsMuGenerator(EpsMu(a.material**2))
|
||||||
|
|
||||||
|
if a.height is None:
|
||||||
|
self.tmgen = TMatrixGenerator.sphere(self.background_epsmu, self.foreground_emg, a.radius)
|
||||||
|
else:
|
||||||
|
self.tmgen = TMatrixGenerator.cylinder(self.background_epsmu, self.foreground_emg, a.radius, a.height, lMax_extend = a.lMax_extend)
|
||||||
|
|
||||||
def _eval_single_omega(self): # feature: single_omega
|
def _eval_single_omega(self): # feature: single_omega
|
||||||
from .constants import eV, hbar
|
from .constants import eV, hbar
|
||||||
self.omega = self.args.eV * eV / hbar
|
self.omega = self.args.eV * eV / hbar
|
||||||
|
|
||||||
def _eval_omega_seq(self): # feature: omega_seq
|
|
||||||
import numpy as np
|
|
||||||
from .constants import eV, hbar
|
|
||||||
start, step, stop = self.args.eV_seq
|
|
||||||
self.omegas = np.arange(start, stop, step)
|
|
||||||
if self.args.eV:
|
|
||||||
self.omegas = np.concatenate((self.omegas, np.array(self.args.eV)))
|
|
||||||
self.omegas.sort()
|
|
||||||
self.omegas *= eV/hbar
|
|
||||||
|
|
||||||
def _eval_omega_seq_real_ng(self): # feature: omega_seq_real_ng
|
|
||||||
import numpy as np
|
|
||||||
from .constants import eV, hbar
|
|
||||||
eh = eV / hbar
|
|
||||||
self.omegas = [omega_eV * eh for omega_eV in flatten(self.args.eV)]
|
|
||||||
self.omega_max = max(om if isinstance(om, float) else max(om) for om in self.omegas)
|
|
||||||
self.omega_min = min(om if isinstance(om, float) else min(om) for om in self.omegas)
|
|
||||||
self.omega_singles = [om for om in self.omegas if isinstance(om, float)]
|
|
||||||
self.omega_ranges = [om for om in self.omegas if not isinstance(om, float)]
|
|
||||||
self.omega_descr = ("%geV" % (self.omega_max / eh)) if (self.omega_max == self.omega_min) else (
|
|
||||||
"%g–%geV" % (self.omega_min / eh, self.omega_max / eh))
|
|
||||||
self.allomegas = []
|
|
||||||
for om in self.omegas:
|
|
||||||
if isinstance(om, float):
|
|
||||||
self.allomegas.append(om)
|
|
||||||
else:
|
|
||||||
self.allomegas.extend(om)
|
|
||||||
self.allomegas = np.unique(self.allomegas)
|
|
||||||
|
|
||||||
|
|
||||||
def _eval_lattice2d(self): # feature: lattice2d
|
def _eval_lattice2d(self): # feature: lattice2d
|
||||||
l = len(self.args.basis_vectors)
|
l = len(self.args.basis_vectors)
|
||||||
if l != 2: raise ValueError('Two basis vectors must be specified (have %d)' % l)
|
if l != 2: raise ValueError('Two basis vectors must be specified (have %d)' % l)
|
||||||
from .qpms_c import lll_reduce
|
from .qpms_c import lll_reduce
|
||||||
self.direct_basis = lll_reduce(self.args.basis_vectors, delta=1.)
|
self.direct_basis = lll_reduce(self.args.basis_vector, delta=1.)
|
||||||
import numpy as np
|
# import numpy as np
|
||||||
self.reciprocal_basis1 = np.linalg.inv(self.direct_basis.T)
|
# self.reciprocal_basis1 = np.linalg.inv(self.direct_basis)
|
||||||
self.reciprocal_basis2pi = 2 * np.pi * self.reciprocal_basis1
|
# self.reciprocal_basis2pi = 2 * np.pi * self.reciprocal_basis1
|
||||||
|
|
||||||
def _eval_rectlattice2d(self): # feature: rectlattice2d
|
def _eval_rectlattice2d(self): # feature: rectlattice2d
|
||||||
a = self.args
|
a = self.args
|
||||||
|
@ -465,97 +140,4 @@ class ArgParser:
|
||||||
import numpy as np
|
import numpy as np
|
||||||
a.basis_vectors = [(a.period[0], 0.), (0., a.period[1])]
|
a.basis_vectors = [(a.period[0], 0.), (0., a.period[1])]
|
||||||
self.direct_basis = np.array(a.basis_vectors)
|
self.direct_basis = np.array(a.basis_vectors)
|
||||||
self.reciprocal_basis1 = np.linalg.inv(self.direct_basis.T)
|
|
||||||
self.reciprocal_basis2pi = 2 * np.pi * self.reciprocal_basis1
|
|
||||||
|
|
||||||
def _process_planewave_angles(self): #feature: planewave
|
|
||||||
import math
|
|
||||||
pi2 = math.pi/2
|
|
||||||
a = self.args
|
|
||||||
a.chi = a.chi * pi2
|
|
||||||
a.psi = a.psi * pi2
|
|
||||||
a.theta = a.theta * pi2
|
|
||||||
a.phi = a.phi * pi2
|
|
||||||
|
|
||||||
def _process_multi_particle(self): # feature: multi_particle
|
|
||||||
a = self.args
|
|
||||||
self.tmspecs = {}
|
|
||||||
self.tmgens = {}
|
|
||||||
self.bspecs = {}
|
|
||||||
self.positions = {}
|
|
||||||
pos13, pos23, pos33 = False, False, False # used to
|
|
||||||
if len(a.position.keys()) == 0:
|
|
||||||
warnings.warn("No particle position (-p or +p) specified, assuming single particle in the origin / single particle per unit cell!")
|
|
||||||
a.position[None] = [(0.,0.,0.)]
|
|
||||||
for poslabel in a.position.keys():
|
|
||||||
try:
|
|
||||||
lMax = a.lMax.get(poslabel, False) or a.lMax[None]
|
|
||||||
radius = a.radius.get(poslabel, False) or a.radius[None]
|
|
||||||
# Height is "inherited" only together with radius
|
|
||||||
height = a.height.get(poslabel, None) if poslabel in a.radius.keys() else a.height.get(None, None)
|
|
||||||
if hasattr(a, 'lMax_extend'):
|
|
||||||
lMax_extend = a.lMax_extend.get(poslabel, False) or a.lMax_extend.get(None, False) or None
|
|
||||||
else:
|
|
||||||
lMax_extend = None
|
|
||||||
material = a.material.get(poslabel, False) or a.material[None]
|
|
||||||
except (TypeError, KeyError) as exc:
|
|
||||||
if poslabel is None:
|
|
||||||
raise ArgumentProcessingError("Unlabeled particles' positions (-p) specified, but some default particle properties are missing (--lMax, --radius, and --material have to be specified)") from exc
|
|
||||||
else:
|
|
||||||
raise ArgumentProcessingError(("Incomplete specification of '%s'-labeled particles: you must"
|
|
||||||
"provide at least ++lMax, ++radius, ++material arguments with the label, or the fallback arguments"
|
|
||||||
"--lMax, --radius, --material.")%(str(poslabel),)) from exc
|
|
||||||
tmspec = (a.background, material, (radius, height, lMax_extend))
|
|
||||||
self.tmspecs[poslabel] = tmspec
|
|
||||||
self.tmgens[poslabel] = self._add_tmg(tmspec)
|
|
||||||
self.bspecs[poslabel] = self._add_bspec(lMax)
|
|
||||||
poslist_cured = []
|
|
||||||
for pos in a.position[poslabel]:
|
|
||||||
if len(pos) == 1:
|
|
||||||
pos_cured = (0., 0., pos[0])
|
|
||||||
pos13 = True
|
|
||||||
elif len(pos) == 2:
|
|
||||||
pos_cured = (pos[0], pos[1], 0.)
|
|
||||||
pos23 = True
|
|
||||||
elif len(pos) == 3:
|
|
||||||
pos_cured = pos
|
|
||||||
pos33 = True
|
|
||||||
else:
|
|
||||||
raise argparse.ArgumentTypeError("Each -p / +p argument requires 1 to 3 cartesian coordinates")
|
|
||||||
poslist_cured.append(pos_cured)
|
|
||||||
self.positions[poslabel] = poslist_cured
|
|
||||||
if pos13 and pos23:
|
|
||||||
warnings.warn("Both 1D and 2D position specifications used. The former are interpreted as z coordinates while the latter as x, y coordinates")
|
|
||||||
|
|
||||||
def get_particles(self):
|
|
||||||
"""Creates a list of Particle instances that can be directly used in ScatteringSystem.create().
|
|
||||||
|
|
||||||
Assumes that self._process_multi_particle() has been already called.
|
|
||||||
"""
|
|
||||||
from .qpms_c import Particle
|
|
||||||
plist = []
|
|
||||||
for poslabel, poss in self.positions.items():
|
|
||||||
t = self.tmgens[poslabel]
|
|
||||||
bspec = self.bspecs[poslabel]
|
|
||||||
plist.extend([Particle(pos, t, bspec=bspec) for pos in poss])
|
|
||||||
return plist
|
|
||||||
|
|
||||||
#TODO perhaps move into another module
|
|
||||||
def annotate_pdf_metadata(pdfPages, scriptname=None, keywords=None, author=None, title=None, subject=None, **kwargs):
|
|
||||||
"""Adds QPMS version-related metadata to a matplotlib PdfPages object
|
|
||||||
|
|
||||||
Use before closing the PDF file.
|
|
||||||
"""
|
|
||||||
from .qpms_c import qpms_library_version
|
|
||||||
d = pdfPages.infodict()
|
|
||||||
d['Creator'] = "QPMS%s (lib rev. %s), https://qpms.necada.org" % (
|
|
||||||
"" if scriptname is None else (" "+scriptname), qpms_library_version())
|
|
||||||
if author is not None:
|
|
||||||
d['Author'] = author
|
|
||||||
if title is not None:
|
|
||||||
d['Title'] = title
|
|
||||||
if subject is not None:
|
|
||||||
d['Subject'] = subject
|
|
||||||
if keywords is not None:
|
|
||||||
d['Keywords'] = ' '.join(keywords)
|
|
||||||
d.update(kwargs)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <gsl/gsl_sf_bessel.h>
|
#include <gsl/gsl_sf_bessel.h>
|
||||||
#include <complex.h>
|
#include <complex.h>
|
||||||
#include "qpms_error.h"
|
#include "qpms_error.h"
|
||||||
#include <camos.h>
|
#include <amos.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifndef M_LN2
|
#ifndef M_LN2
|
||||||
|
@ -52,11 +52,6 @@ static inline complex double spherical_yn(qpms_l_t l, complex double z) {
|
||||||
qpms_errno_t qpms_sph_bessel_realx_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, complex double *result_array) {
|
qpms_errno_t qpms_sph_bessel_realx_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, complex double *result_array) {
|
||||||
int retval;
|
int retval;
|
||||||
double tmparr[lmax+1];
|
double tmparr[lmax+1];
|
||||||
if (typ != QPMS_BESSEL_REGULAR && x == 0) {
|
|
||||||
for (int l = 0; l <= lmax; ++l) result_array[l] = NAN + I*NAN;
|
|
||||||
QPMS_WARN("Evaluating singular Bessel functions at zero!");
|
|
||||||
return QPMS_SUCCESS; // Really?
|
|
||||||
}
|
|
||||||
switch(typ) {
|
switch(typ) {
|
||||||
case QPMS_BESSEL_REGULAR:
|
case QPMS_BESSEL_REGULAR:
|
||||||
retval = gsl_sf_bessel_jl_steed_array(lmax, x, tmparr);
|
retval = gsl_sf_bessel_jl_steed_array(lmax, x, tmparr);
|
||||||
|
@ -89,8 +84,7 @@ qpms_errno_t qpms_sph_bessel_realx_fill(qpms_bessel_t typ, qpms_l_t lmax, double
|
||||||
|
|
||||||
// TODO DOC
|
// TODO DOC
|
||||||
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, complex double x, complex double *res) {
|
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, complex double x, complex double *res) {
|
||||||
if(!cimag(x) &&
|
if(!cimag(x))
|
||||||
creal(x) < 10000) // For large arguments (around 30000 or more), gsl_sf_bessel_jl_steed_array fails
|
|
||||||
return qpms_sph_bessel_realx_fill(typ, lmax, creal(x), res);
|
return qpms_sph_bessel_realx_fill(typ, lmax, creal(x), res);
|
||||||
else if (isnan(creal(x)) || isnan(cimag(x)))
|
else if (isnan(creal(x)) || isnan(cimag(x)))
|
||||||
for(qpms_l_t l = 0; l <= lmax; ++l) res[l] = NAN + I*NAN;
|
for(qpms_l_t l = 0; l <= lmax; ++l) res[l] = NAN + I*NAN;
|
||||||
|
@ -98,32 +92,30 @@ qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, complex doub
|
||||||
else if (fpclassify(creal(x)) == FP_INFINITE)
|
else if (fpclassify(creal(x)) == FP_INFINITE)
|
||||||
for(qpms_l_t l = 0; l <= lmax; ++l) res[l] = INFINITY + I * INFINITY;
|
for(qpms_l_t l = 0; l <= lmax; ++l) res[l] = INFINITY + I * INFINITY;
|
||||||
else {
|
else {
|
||||||
try_again: ;
|
const DOUBLE_PRECISION_t zr = creal(x), zi = cimag(x), fnu = 0.5;
|
||||||
int retry_counter = 0;
|
const INTEGER_t n = lmax + 1, kode = 1 /* No exponential scaling */;
|
||||||
const double zr = creal(x), zi = cimag(x), fnu = 0.5;
|
DOUBLE_PRECISION_t cyr[n], cyi[n];
|
||||||
const int n = lmax + 1, kode = 1 /* No exponential scaling */;
|
INTEGER_t ierr, nz;
|
||||||
double cyr[n], cyi[n];
|
|
||||||
int ierr, nz;
|
|
||||||
unsigned int kindchar; // Only for error output
|
unsigned int kindchar; // Only for error output
|
||||||
const complex double prefac = csqrt(M_PI_2/x);
|
const complex double prefac = csqrt(M_PI_2/x);
|
||||||
switch(typ) {
|
switch(typ) {
|
||||||
case QPMS_BESSEL_REGULAR:
|
case QPMS_BESSEL_REGULAR:
|
||||||
kindchar = 'j';
|
kindchar = 'j';
|
||||||
ierr = camos_zbesj(zr, zi, fnu, kode, n, cyr, cyi, &nz);
|
amos_zbesj(&zr, &zi, &fnu, &kode, &n, cyr, cyi, &nz, &ierr);
|
||||||
break;
|
break;
|
||||||
case QPMS_BESSEL_SINGULAR:
|
case QPMS_BESSEL_SINGULAR:
|
||||||
kindchar = 'y';
|
kindchar = 'y';
|
||||||
{
|
{
|
||||||
double cwrkr[lmax + 1], cwrki[lmax + 1];
|
DOUBLE_PRECISION_t cwrkr[lmax + 1], cwrki[lmax + 1];
|
||||||
ierr = camos_zbesy(zr, zi, fnu, kode, n, cyr, cyi, &nz, cwrkr, cwrki);
|
amos_zbesy(&zr, &zi, &fnu, &kode, &n, cyr, cyi, &nz, cwrkr, cwrki, &ierr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QPMS_HANKEL_PLUS:
|
case QPMS_HANKEL_PLUS:
|
||||||
case QPMS_HANKEL_MINUS:
|
case QPMS_HANKEL_MINUS:
|
||||||
kindchar = 'h';
|
kindchar = 'h';
|
||||||
{
|
{
|
||||||
const int m = (typ == QPMS_HANKEL_PLUS) ? 1 : 2;
|
const INTEGER_t m = (typ == QPMS_HANKEL_PLUS) ? 1 : 2;
|
||||||
ierr = camos_zbesh(zr, zi, fnu, kode, m, n, cyr, cyi, &nz);
|
amos_zbesh(&zr, &zi, &fnu, &kode, &m, &n, cyr, cyi, &nz, &ierr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -134,28 +126,14 @@ try_again: ;
|
||||||
for (qpms_l_t l = 0; l <= lmax; ++l)
|
for (qpms_l_t l = 0; l <= lmax; ++l)
|
||||||
res[l] = prefac * (cyr[l] + I * cyi[l]);
|
res[l] = prefac * (cyr[l] + I * cyi[l]);
|
||||||
if (ierr == 3)
|
if (ierr == 3)
|
||||||
if (creal(x) >= 10000) {
|
QPMS_WARN("Amos's zbes%c computation done but losses of significance "
|
||||||
QPMS_WARN_ONCE("Due to large argument, "
|
"by argument reduction produce less than half of machine accuracy.",
|
||||||
"Amos's zbes%c computation done but losses of significance "
|
kindchar);
|
||||||
"by argument reduction produce less than half of machine accuracy. "
|
|
||||||
"This warning is shown only once.",
|
|
||||||
kindchar);
|
|
||||||
} else {
|
|
||||||
QPMS_WARN("Amos's zbes%c computation done but losses of significance "
|
|
||||||
"by argument reduction produce less than half of machine accuracy.",
|
|
||||||
kindchar);
|
|
||||||
}
|
|
||||||
return QPMS_SUCCESS; //TODO maybe something else if ierr == 3
|
return QPMS_SUCCESS; //TODO maybe something else if ierr == 3
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (retry_counter < 5) {
|
QPMS_PR_ERROR("Amos's zbes%c failed with ierr == %d.",
|
||||||
QPMS_WARN("Amos's zbes%c failed with ierr == %d (lMax = %d, x = %+.16g%+.16gi). Retrying.\n",
|
kindchar, (int) ierr);
|
||||||
kindchar, (int) ierr, lmax, creal(x), cimag(x));
|
|
||||||
++retry_counter;
|
|
||||||
goto try_again;
|
|
||||||
} else QPMS_PR_ERROR("Amos's zbes%c failed with ierr == %d (lMax = %d, x = %+.16g%+.16gi).",
|
|
||||||
kindchar, (int) ierr, lmax, creal(x), cimag(x));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return QPMS_SUCCESS;
|
return QPMS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "bessels.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const double ln2 = 0.693147180559945309417;
|
||||||
|
|
||||||
|
|
||||||
|
// general; gives an array of size xxx with TODODESC
|
||||||
|
complex double * hankelcoefftable_init(size_t maxn) {
|
||||||
|
complex double *hct = malloc((maxn+1)*(maxn+2)/2 * sizeof(complex double));
|
||||||
|
for(size_t n = 0; n <= maxn; ++n) {
|
||||||
|
complex double *hcs = hankelcoeffs_get(hct,n);
|
||||||
|
for (size_t k = 0; k <= n; ++k) {
|
||||||
|
double lcoeff = lgamma(n+k+1) - lgamma(n-k+1) - lgamma(k+1) - k*ln2;
|
||||||
|
// for some reason, casting k-n to double does not work,so
|
||||||
|
// cpow (I, k-n-1) cannot be used...
|
||||||
|
complex double ifactor;
|
||||||
|
switch ((n+1-k) % 4) {
|
||||||
|
case 0:
|
||||||
|
ifactor = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ifactor = -I;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ifactor = -1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ifactor = I;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// the result should be integer, so round to remove inaccuracies
|
||||||
|
hcs[k] = round(exp(lcoeff)) * ifactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hct;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hankelparts_fill(complex double *lrt, complex double *srt, size_t maxn,
|
||||||
|
size_t lrk_cutoff, complex double const * const hct,
|
||||||
|
unsigned kappa, double c, double x) {
|
||||||
|
if (lrt) memset(lrt, 0, (maxn+1)*sizeof(complex double));
|
||||||
|
memset(srt, 0, (maxn+1)*sizeof(complex double));
|
||||||
|
double regularisator = pow(1. - exp(-c * x), (double) kappa);
|
||||||
|
double antiregularisator = 1. - regularisator;
|
||||||
|
double xfrac = 1.; // x ** (-1-k)
|
||||||
|
for (size_t k = 0; k <= maxn; ++k) {
|
||||||
|
xfrac /= x;
|
||||||
|
for(size_t n = k; n <= maxn; ++n) // TODO Kahan sums here
|
||||||
|
srt[n] += ((k<lrk_cutoff) ? antiregularisator : 1)
|
||||||
|
* xfrac * hankelcoeffs_get(hct,n)[k];
|
||||||
|
if (lrt && k < lrk_cutoff) for (size_t n = k; n <= maxn; ++n)
|
||||||
|
lrt[n] += regularisator * xfrac * hankelcoeffs_get(hct,n)[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
complex double expix = cexp(I * x);
|
||||||
|
for(size_t n = 0; n <= maxn; ++n)
|
||||||
|
srt[n] *= expix;
|
||||||
|
if (lrt) for(size_t n = 0; n <= maxn; ++n)
|
||||||
|
srt[n] *= expix;
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef BESSELS_H
|
||||||
|
#define BESSELS_H
|
||||||
|
/* Short- and long-range parts of spherical Hankel functions
|
||||||
|
* and (cylindrical) Hankel transforms of the long-range parts.
|
||||||
|
* Currently, the implementation lies in bessels.c and
|
||||||
|
* lrhankel_recspace_dirty.c. The latter contains the implementation
|
||||||
|
* of the Hankel transforms, but currenty only for a pretty limited
|
||||||
|
* set of parameters. The general implementation is a BIG TODO here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <complex.h>
|
||||||
|
|
||||||
|
complex double *hankelcoefftable_init(size_t maxn);
|
||||||
|
|
||||||
|
|
||||||
|
// For navigating in the coefficients, maybe not for public use
|
||||||
|
static inline complex double *
|
||||||
|
trindex_cd(complex double const * const arr, size_t n){
|
||||||
|
return (complex double *)(arr + n*(n+1)/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// general, gives the offset such that result[ql] is
|
||||||
|
// the coefficient corresponding to the e**(I * x) * x**(-ql-1)
|
||||||
|
// term of the n-th Hankel function; no boundary checks!
|
||||||
|
static inline complex double *
|
||||||
|
hankelcoeffs_get(complex double const * const hankelcoefftable, size_t n){
|
||||||
|
return trindex_cd(hankelcoefftable, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the untransformed long- (optional) and short-range parts of spherical Hankel functions */
|
||||||
|
// general; target_longrange and target_shortrange are of size (maxn+1)
|
||||||
|
// if target_longrange is NULL, only the short-range part is calculated
|
||||||
|
void hankelparts_fill(complex double *target_longrange, /* Not needed for the actual calculations
|
||||||
|
(only for testing and error estimates)
|
||||||
|
as summed in the reciprocal space:
|
||||||
|
pass NULL to omit */
|
||||||
|
complex double *target_shortrange,
|
||||||
|
size_t maxn, size_t longrange_order_cutoff, /* terms e**(I x)/x**(k+1),
|
||||||
|
k>= longrange_order_cutoff go
|
||||||
|
completely to short-range part */
|
||||||
|
complex double const * const hankelcoefftable,
|
||||||
|
unsigned kappa, double c, /* regularisation "slope", dimensionless */
|
||||||
|
double x); // dimensionless x = k0 * r
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Hankel transforms of the long-range parts of the spherical Hankel functions */
|
||||||
|
// this declaration is general; however, the implementation
|
||||||
|
// is so far only for kappa == 5, maxp <= 5, longrange_order_cutoff <= 1
|
||||||
|
void lrhankel_recpart_fill(complex double *target_longrange_kspace /*Must be of size maxn*(maxn+1)/2*/,
|
||||||
|
size_t maxp /* Max. order of the Hankel transform */,
|
||||||
|
size_t longrange_order_cutoff /* terms e**(I x)/x**(k+1), k>= longrange_order_cutoff go
|
||||||
|
completely to the shortrange part
|
||||||
|
index with hankelcoeffs_get(target,p)l[delta_m] */,
|
||||||
|
complex double const * const hankelcoefftable,
|
||||||
|
unsigned kappa,
|
||||||
|
// These are dimensionFUL (inverse lengths):
|
||||||
|
double cv, double k0, double k);
|
||||||
|
|
||||||
|
#endif //BESSELS_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue