Science Score: 67.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 3 DOI reference(s) in README -
✓Academic publication links
Links to: zenodo.org -
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (8.5%) to scientific vocabulary
Repository
Backend for SsTC
Basic Info
- Host: GitHub
- Owner: irukoa
- License: gpl-3.0
- Language: Fortran
- Default Branch: main
- Size: 3.75 MB
Statistics
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
- Releases: 4
Metadata Files
README.md
SsTC Driver
Solid state task constructor driver
This is a modern Fortran library sister to WannInt. This library is meant to provide a backend for automation of sampling and integration workflows of functions defined on the Brillouin zone (BZ) of a crystal.
Working principle
Many quantities in solid state physics (Berry curvature, optical responses, transport properties...) are expressed as a function, or as the integral of a function, defined in reciprocal space. The most general form of such function is
$$ C^{\alpha}(\textbf{k}; \beta), $$
where $\textbf{k}$ is a vector in the BZ, $\alpha$ denotes a set of "integer indices", which take only integer values and $\beta$ denotes a set of "continuous variables", which take only real values. The idea behind the library is to automate the task of sampling a generic function $C$ in the BZ and provide the necessary utilities for a user to express the particular function $C$ he/she wishes to sample.
To abstract the idea of integer and continuous indices, MAC is used.
API
The derived type
fortran
type, public :: task_specifier
is defined.
type(task_specifier) :: tsk
Constructor.
A task is created by calling
fortran
call tsk%construct(name, [&
int_ind, &
cont_data_start, &
cont_data_end, &
cont_data_steps, &
exponent, ]&
calculator)
where
character(len=*), intent(in) :: nameis the name of the task.integer, optional, intent(in) :: int_ind(:)is the dimension specifier of the integer indices $\alpha$ in $C^{\alpha}(\textbf{k}; \beta)$. That is, the size of the array is the number of integer indices, and the value of each element is the number of values that index can take. Ifint_indis not present, $C^{\alpha}(\textbf{k}; \beta)$ does not depend on $\alpha$.integer, optional, intent(in) :: cont_data_steps(:)is the dimension specifier of the continuous indices $\beta$ in $C^{\alpha}(\textbf{k}; \beta)$. That is, the size of the array is the number of continuous variables, and the value of each element is the number of steps that the variable has been discretized into. Ifcont_data_stepsis not present, $C^{\alpha}(\textbf{k}; \beta)$ does not depend on $\beta$.real(dp), optional, intent(in) :: cont_data_start(:)is a real array where each array element specifies the starting sampling point for each of the continuous variables.real(dp), optional, intent(in) :: cont_data_end(:)is a real array where each array element specifies the ending sampling point for each of the continuous variables.real(dp), optional, intent(in) :: exponentis a real number $e$, which if not present, will sample the variable $\betai$ according to $\betai(j)=$cont_data_start(i) + (cont_data_end(i) - cont_data_start(i))$\times (j-1)/$(cont_data_steps(i) - 1), and if present as $\betai(j) \rightarrow e^{\betai(j)}$. Ifcont_data_steps(i) = 1, then $\betai(j)=$ `contdata_start(i)`.procedure(cs), pass(self) :: calculatoris a function with interfacecswhich corresponds the implementation of $C^{\alpha}(\textbf{k}; \beta)$. See interface.
Component type(container_specifier) :: tsk%idims
Is a MAC container specifier initialized to the dimension specifier given by int_ind.
Component type(container_specifier) :: tsk%cdims
Is a MAC container specifier initialized to the dimension specifier given by cont_data_steps.
Name handle
Is called as,
fortran
name = tsk%name()
where character(len=120) :: name.
Initialization query
Is called as,
fortran
initialized = tsk%initialized()
where logical :: initialized is .true. if the task has been initialized and .false. otherwise.
Continuous variable retriever
This utility serves to retrieve the value of $\beta_i(j)$. It is called as,
fortran
beta = tsk%cdt(var, step)
where real(dp) :: beta has the value $\beta_i(j)$ when var=$i$, step=$j$.
Interface cs
The interface ```fortran use MAC, only: containerspecifier, container use WannInt, only: crystal abstract interface function cs(self, crys, k, other) import dp, taskspecifier, crystal class(task_specifier), intent(in) :: self class(crystal), intent(in) :: crys real(dp), intent(in) :: k(3) class(*), optional, intent(in) :: other
complex(dp) :: cs(self%idims%size(), self%cdims%size())
end function cs
end interface
``
describes the shape of any calculator. The input values for these types of functions are always an object of classtask_specifier, a [WannInt](https://github.com/irukoa/WannInt/) crystal class objectcrys, areal(dp), dimension(3)variablekrepresenting a vector in the BZ of the crystal and an optional unlimited polymorphic objectother. The output value is acomplex(dp)` rank-2 array which holds, in each dimension, the memory layout index corresponding to a particular permutation of the integer and continuous variables, respectively.
Best practices
- If you need to pass further external information to the calculator (a value for a Dirac delta function smearing for integration tasks, an exception, or an error case...), it is best to extend either
task_specifierorcrystal, depending on what information needs to be passed. - It is a clever idea to traverse the whole output array with the aid of MAC's indexing when defining calculators.
fortran do r = 1, tsk%cdims%size() r_arr = tsk%cdims%ind(r) cv1 = tsk%cdt(var = 1, step = r_arr(1)) !external variable 1, cv2 = tsk%cdt(var = 2, step = r_arr(2)) !external variable 2, ![...] do i = 1, tsk%idims%size() i_arr = tsk%idims%ind(i) iv1 = i_arr(1) !integer variable 1, iv2 = i_arr(2) !integer variable 2, cs(i, r) = ... !your implementation in terms of iv1, cv1... ![...] enddo enddo - Most of the times (implementing optical responses, transport properties...), the number of integer and continuous values is known. In these cases it is a clever idea to loop though the variables in a transparent way and then indexing.
fortran cvshape = tsk%cdims%shape() ivshape = tsk%idims%shape() do w1 = 1, cvshape(1) !external variable 1, cv1 = tsk%cdt(var = 1, step = w1) do w2 = 1, cvshape(2) !external variable 2, cv2 = tsk%cdt(var = 2, step = w2) ![...] r_arr = [w1, w2, ...] do i1 = 1, ivshape(1) !integer variable 1, do i2 = 1, ivshape(2) !integer variable 2, ![...] i_arr = [i1, i2, ...] !your implementation in terms of i1, cv1... cs(tsk%idims%ind(i_arr), tsk%rdims%ind(r_arr)) = ... enddo enddo ![...] enddo enddo
Sampler
An initialized task is sampled by calling (1st way),
fortran
call tsk%sample(crys, kpart, store_at [, parallelization, other])
where
class(crystal), intent(in) :: crysis a WannInt crystal.integer, intent(in) :: kpart(3)is a integer array where each component specifies the number of points to partition each dimension of the BZ into. Each componentkpart(i)discretizes the reciprocal lattice vector $\mathbf{b}_i$.complex(dp), allocatable, intent(out) :: store_at(:, :, :)/store_at(:, :)is a rank-3 or rank-2 array. If rank-3:- The first dimension specifies the memory layout representation of $\textbf{k}$ in the order that will be laid out by a MAC container specifier with
dimension_specifier = kpart. - The second dimension is the memory layout representation of a particular permutation of integer indices $\alpha$ in the order laid out by
tsk%idims. - The third dimension is the memory layout representation of a particular permutation of continuous variables $\beta$ in the order laid out by
tsk%cdims.
- The first dimension specifies the memory layout representation of $\textbf{k}$ in the order that will be laid out by a MAC container specifier with
- If rank-2:
- The first dimension is the memory layout representation of a particular permutation of integer indices $\alpha$ in the order laid out by
tsk%idims. - The second dimension is the memory layout representation of a particular permutation of continuous variables $\beta$ in the order laid out by
tsk%cdims. store_atholds an unnormalized sum over all theproduct(kpart)points given as input.
- The first dimension is the memory layout representation of a particular permutation of integer indices $\alpha$ in the order laid out by
character(len=*), optional, intent(in) :: parallelizationis an specification of the parallelization method to employ to distribute the sampling. Options areMPI+OMP,MPI,OMP,none. Default isOMP.class(*), optional, intent(in) :: otheris an unlimited polymorphic object to be passed to the calculator during sampling. See interface.
Or by calling (2nd way),
An initialized task is sampled by calling (1st way),
fortran
call tsk%sample(crys, klist, store_at [, parallelization, other])
where all present parameters are the same as described in the previous calling way except for
- real(dp), intent(in) :: klist(3, nk), which is a list of nk points where each klist(:, j) represents a BZ point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).
Utilities
The library defines the utilities kpath, kslice. These utilities are of use to create a list of $\textbf{k}$-points of the form klist(3, nk) which traverse a path and a slice of the BZ, respectively.
Kpath
The utility is used as
fortran
path = kpath(vecs, nkpts)
where,
real(dp), intent(in) :: vecs(nv, 3)are the coordinates ofnkpoints where eachvecs(:, j)represents a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).integer, intent(in) :: nkpts(nv - 1)each elementnkpts(i)is the number of points in a straight line to consider between pointsvecs(i, :),vecs(i + 1, :).real(dp), allocatable :: path(:, :)is the return value. On output, the shape is[3, nk], wherenk = sum(nkpts) - (nvec - 2). Each elementpath(:, j)represents a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, along the ordered path, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).
Kslice
The utility is used as
fortran
slice = kslice(corner, vec_a, vec_b, part)
where,
real(dp), intent(in) :: corner(3)are the coordinates of a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates). This parameter represents the bottom-left point of the slice.real(dp), intent(in) :: vec_a(3), vec_b(3)are the coordinates of vectors $\textbf{k}^1$ and $\textbf{k}^2$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}i$ (crystal coordinates), representing two vectors defining the slice.integer, intent(in) :: part(2)is a integer array where each component specifies the number of points to partition each dimension of the BZ into. Each componentpart(i)discretizes the reciprocal lattice vector $\mathbf{b}_i$.real(dp), allocatable :: slice(:, :)is the return value. On output, the shape is[3, nk], wherenk = product(part). Each elementslice(:, j)represents a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}i$ (crystal coordinates). The ordering if $\textbf{k}$ points is given by the order that will be laid out by a MAC container specifier with `dimensionspecifier = part`.
Crystal to cartesian coordinates in k-space
The utility is used as
fortran
k_cart = crys_to_cart(k_crys, crys)
where,
real(dp), intent(in) :: k_crys(3)are the coordinates of a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).class(crystal), intent(in) :: crysis a WannInt crystal.real(dp), intent(in) :: k_cart(3)is the return value. On output, the components are the coordinates of a point $\textbf{k}^j=(k^jx, k^jy, k^jz)$, where each $k^ji$ is the component, in $\text{A}^{-1}$, relative to the cartesian frame used to define the real lattice basis of the crystalcrys.
Cartesian to crystal coordinates in k-space
The utility is used as
fortran
k_crys = cart_to_crys(k_cart, crys)
where,
real(dp), intent(in) :: k_cart(3)are the coordinates of a point $\textbf{k}^j=(k^jx, k^jy, k^jz)$, where each $k^ji$ is the component, in $\text{A}^{-1}$, relative to the cartesian frame used to define the real lattice basis of the crystalcrys.class(crystal), intent(in) :: crysis a WannInt crystal.real(dp), intent(in) :: k_crys(3)is the return value. On output, the components are the coordinates of a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).
Path lenght utility
The utility is used as
fortran
path_length = kpath_length(vecs, nkpts, crys)
where,
real(dp), intent(in) :: vecs(nv, 3)are the coordinates ofnkpoints where eachvecs(:, j)represents a point $\textbf{k}^j=(k^j1, k^j2, k^j3)$, where each $k^ji$ is given in coordinates relative to the reciprocal lattice vectors $\mathbf{b}_i$ (crystal coordinates).integer, intent(in) :: nkpts(nv - 1)each elementnkpts(i)is the number of points in a straight line to consider between pointsvecs(i, :),vecs(i + 1, :).class(crystal), intent(in) :: crysis a WannInt crystal.real(dp), allocatable :: path_length(:)is the return value. If the arraypathhas been constructed by using thekpathutility, theikth element of thepath_lengtharray contains the distance traversed along the kpath, in $\text{A}^{-1}$, up until arriving to the pointpath(:, ik).
Build
An automated build is available for Fortran Package Manager users. This is the recommended way to build and use WannInt in your projects. You can add WannInt to your project dependencies by including
[dependencies]
SsTC_driver = { git="https://github.com/irukoa/SsTC_driver.git" }
in the fpm.toml file.
MAC's objects
fortran
type, public :: container_specifier
type, extends(container_specifier), public :: container
and WannInt's objects and utilities
fortran
type, public :: crystal
public :: diagonalize
public :: dirac_delta
public :: deg_list
public :: schur
public :: SVD
public :: expsh
public :: logu
are made public by SsTC_driver.
Limitations
The mayor limitation lies in memory management when sampling with parallelization. The array store_at needs to be dynamically allocated. Its size is given by $($ nk $) \times$ product(int_ind) $\times$ product(cont_data_steps). Before making any calculation it is suggested to check the value of its size and choose a parallelization scheme accordingly. It is recommended to use none or OMP parallelization in PCs and MPI or MPI+OMP in multinode clusters. If the size of store_at is too big, segmentation faults may occur. We recommend using only store_at in its rank-3 version in sampling calls if keeping the index of $\textbf{k}$ points is important (for plotting or for special integration schemes).
We recommend the compilers in the Intel oneAPI toolkit ifort/mpiifort and ifx/mpiifx or the GNU compilers gfortran/mpifort. If possible, we recommend using the --heap-arrays flag for Intel compilers and the -fmax-stack-var-size=n flag for GNU compilers.
Owner
- Name: Álvaro R. Puente-Uriona
- Login: irukoa
- Kind: user
- Location: Donostia
- Company: CFM/MPC-UPV/EHU
- Website: https://cfm.ehu.es/team/56452/
- Repositories: 2
- Profile: https://github.com/irukoa
PhD Student in Solid State Physics, check my CV at https://irukoa.github.io/
Citation (CITATION.cff)
cff-version: 1.2.0
title: SsTC Driver
message: Solid-state Task Constructor Driver (SsTC_driver)
type: software
authors:
- given-names: Álvaro
family-names: R. Puente-Uriona
email: alvaro.ruiz@ehu.eus
affiliation: UPV/EHU
orcid: 'https://orcid.org/0000-0003-1915-8804'
identifiers:
- type: doi
value: 10.5281/zenodo.10672177
description: Zenodo
repository-code: 'https://github.com/irukoa/SsTC_driver'
url: 'https://github.com/irukoa/SsTC_driver'
abstract: >-
Solid-state Task Constructor Driver.
A backend for automation of sampling and
integration workflows of functions
defined on the Brillouin zone of a
crystal.
keywords:
- Fortran
- Wannier Interpolation
- Parallel programming
- Generic programming
license: GPL-3.0
GitHub Events
Total
Last Year
Dependencies
- actions/checkout v2 composite
- fortran-lang/setup-fpm v5 composite