Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
arpack=*=mpi_openmpi*
gfortran
openmpi=4
doxygen

# - name: Set up Python ${{ matrix.python-version }}
# # if: matrix.host-os != 'macos-latest'
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ docs/source/generated/
docs/source/auto_examples/
docs/source/sg_execution_times.rst

# Doxygen output
docs/doxygen/

# pytest
.pytest_cache/

Expand Down
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,14 @@ if (EDRIXS_PY_INTERFACE)
endif()

add_subdirectory(src)

# Optional Doxygen target: cmake --build . --target docs
find_package(Doxygen OPTIONAL_COMPONENTS dot)
if(DOXYGEN_FOUND)
add_custom_target(docs
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Generating Fortran API docs with Doxygen"
VERBATIM
)
endif()
62 changes: 62 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Doxyfile for EDRIXS Fortran source documentation
# Run: doxygen Doxyfile (output goes to docs/doxygen/html/index.html)

#---------------------------------------------------------------------------
# Project
#---------------------------------------------------------------------------
PROJECT_NAME = "EDRIXS"
PROJECT_BRIEF = "An open source toolkit for simulating RIXS spectra"
PROJECT_NUMBER =
OUTPUT_DIRECTORY = docs/doxygen

#---------------------------------------------------------------------------
# Input
#---------------------------------------------------------------------------
INPUT = src
FILE_PATTERNS = *.f90 *.F90 *.f *.F
RECURSIVE = NO
EXCLUDE = src/arpack.f90

#---------------------------------------------------------------------------
# Fortran optimisation
#---------------------------------------------------------------------------
OPTIMIZE_FOR_FORTRAN = YES
EXTENSION_MAPPING = f90=FortranFree F90=FortranFree

# Doxygen treats !> and !! as documentation comments in Fortran
JAVADOC_AUTOBRIEF = YES

#---------------------------------------------------------------------------
# Output formats
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_TIMESTAMP = NO

GENERATE_LATEX = NO

# XML output is consumed by Breathe to embed docs in Sphinx
GENERATE_XML = YES
XML_OUTPUT = xml

#---------------------------------------------------------------------------
# Extraction settings
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES

#---------------------------------------------------------------------------
# Source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES

#---------------------------------------------------------------------------
# Graphs (requires graphviz dot — optional, gracefully skipped if absent)
#---------------------------------------------------------------------------
HAVE_DOT = NO
CALL_GRAPH = NO
CALLER_GRAPH = NO
10 changes: 9 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ SPHINXBUILD = sphinx-build
SPHINXPROJ = edrixs
SOURCEDIR = source
BUILDDIR = build
DOXYFILE = ../Doxyfile

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile
.PHONY: help Makefile html doxygen

# Run Doxygen before building HTML so Breathe has fresh XML input.
html: doxygen
@$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

doxygen:
cd .. && doxygen Doxyfile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
4 changes: 4 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@
'numpydoc',
'sphinx_copybutton',
'sphinx_gallery.gen_gallery',
'breathe',
]

breathe_projects = {"edrixs": "../../docs/doxygen/xml"}
breathe_default_project = "edrixs"

# Configuration options for plot_directive. See:
# https://github.com/matplotlib/matplotlib/blob/f3ed922d935751e08494e5fb5311d3050a3b637b/lib/matplotlib/sphinxext/plot_directive.py#L81
plot_html_show_source_link = True
Expand Down
239 changes: 239 additions & 0 deletions docs/source/fortran_api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
.. _fortran_api:

###########
Fortran API
###########

Documentation for the EDRIXS Fortran back-end, extracted from source comments
via Doxygen and rendered here by Breathe.

Overview of XAS and RIXS calculations
======================================

EDRIXS models spectroscopy on correlated electron systems using exact
diagonalisation (ED) of a many-body Hamiltonian written in a Fock-state basis.
Three distinct Hilbert spaces are involved, each with its own Hamiltonian and
Fock basis:

* **Initial space** (*i*): no core hole, described by hopping and Coulomb
integrals read from ``hopping_i.in`` and ``coulomb_i.in``.
* **Intermediate space** (*n*): one core hole and one extra valence electron
created by X-ray absorption (same total electron count as the initial space),
described by ``hopping_n.in`` and ``coulomb_n.in``.
* **Final space** (*f*): used in RIXS only; no core hole, same total electron
count as the initial space. After the core hole is filled by an emitted
photon the system is left in a (generally excited) valence configuration.
The Hamiltonian has the same form as :math:`H_i`.

Step 1 — Exact diagonalisation (``ed.x`` / ``ed_driver``)
----------------------------------------------------------

The initial-state Hamiltonian :math:`H_i` is built in distributed CSR format
and diagonalised to find the lowest few eigenstates
:math:`|\psi_k\rangle` with energies :math:`E_k`. Three solvers are
available (controlled by ``ed_solver``): full LAPACK ``ZHEEV`` for small
systems, a parallel Lanczos algorithm, or ARPACK. The eigenvectors are
written to ``eigvec.k`` for use by the spectroscopy drivers.

Step 2 — Absorption transition operator
----------------------------------------

The dipole (or multipole) transition operator :math:`T` couples the initial
and intermediate spaces. Its matrix elements are computed in
``build_transop_i`` by iterating over pairs of Fock states: for each
initial state the operator creates a core hole in one of the ``num_core_orbs``
core orbitals, searches the intermediate Fock basis for the resulting state
(with Jordan–Wigner sign), and stores the amplitude as a CSR entry. The
result is a rectangular CSR matrix with ``ndim_n`` rows and ``ndim_i``
columns.

XAS (``xas.x`` / ``xas_driver``)
----------------------------------

The X-ray absorption spectrum is the imaginary part of the one-particle
Green's function

.. math::

A(\omega) = -\frac{1}{\pi}\,\mathrm{Im}\,
\langle\phi|({\omega - H_n + i\gamma})^{-1}|\phi\rangle,

where :math:`|\phi\rangle = T|\psi_k\rangle` is the intermediate state
produced by applying the transition operator to ground state :math:`k`, and
:math:`\gamma` is the core-hole lifetime broadening.

Rather than inverting :math:`\omega - H_n` explicitly, EDRIXS evaluates
:math:`A(\omega)` via the **Lanczos continued-fraction method**
(``build_krylov_mp``):

1. Run the Lanczos recurrence starting from the normalised vector
:math:`|\phi\rangle / \||\phi\rangle\|` for ``nkryl`` steps, producing
diagonal coefficients :math:`\alpha_j` and off-diagonal coefficients
:math:`\beta_j`.
2. The Green's function is then expressed exactly as the continued fraction

.. math::

G(z) = \frac{\||\phi\rangle\|^2}
{z - \alpha_1 - \dfrac{\beta_1^2}
{z - \alpha_2 - \dfrac{\beta_2^2}{\ddots}}}

which ``build_spectrum`` evaluates on a dense frequency mesh
:math:`z = \omega + E_k + i\gamma` with no further matrix operations.

The Krylov data (:math:`\alpha`, :math:`\beta`, norm, :math:`E_k`) are saved
to ``xas_poles.k`` so that the spectrum can be regenerated at any resolution
without re-running the expensive Lanczos iteration.

RIXS (``rixs.x`` / ``rixs_driver``)
--------------------------------------

The RIXS cross-section is proportional to

.. math::

I(\omega_\text{in}, \omega_\text{loss}) \propto
\sum_f \bigl|\langle f|T_f
(\omega_\text{in} - H_n + E_k + i\gamma_\text{in})^{-1}
T_i|k\rangle\bigr|^2
\,\delta(\omega_\text{loss} - E_f + E_k),

which requires the resolvent :math:`(H_n - \omega)^{-1}|\phi\rangle` at a
single complex energy :math:`\omega = \omega_\text{in} + E_k + i\gamma_\text{in}`.
This is obtained by solving the **complex-symmetric linear system**

.. math::

(H_n - \omega)\,x = |\phi\rangle

with the parallel MINRES solver (``pminres_csr``). The shifted Hamiltonian
stored in ``ham_csr`` already absorbs the sign convention used by MINRES.

Once :math:`x = (H_n - \omega)^{-1}|\phi\rangle` is known, the emission
transition operator :math:`T_f` (built by ``build_transop_f``) maps it into
the final-state space:

.. math::

|\phi_f\rangle = T_f\,x.

The RIXS spectrum is then the XAS problem again: run ``build_krylov_mp``
on :math:`H_f` (same form as :math:`H_i`) starting from :math:`|\phi_f\rangle`,
write the poles to ``rixs_poles.k``, and evaluate the continued fraction
with ``build_spectrum`` for the desired energy-loss mesh.

MPI parallelism
----------------

All three spaces can be large (millions of basis states). The Hamiltonian and
transition-operator matrices are distributed across MPI ranks in **row blocks**:
each rank owns a contiguous slice of rows and the diagonal column block.
Off-diagonal column blocks needed for the sparse matrix–vector product
(``pspmv_csr``) are communicated via non-blocking ``MPI_ISEND`` / ``MPI_RECV``
while the local diagonal multiply proceeds, overlapping communication and
computation. Dot products and norms are reduced with ``MPI_ALLREDUCE``.

.. note::

For the full Doxygen HTML output (including derived-type definitions from
``m_types`` and cross-referenced source browsing) run ``doxygen Doxyfile``
from the repository root and open ``docs/doxygen/html/index.html``.

Modules
=======

m_constants
-----------

.. doxygennamespace:: m_constants
:project: edrixs

m_control
---------

.. doxygennamespace:: m_control
:project: edrixs

m_global
--------

.. doxygennamespace:: m_global
:project: edrixs

m_lanczos
---------

.. doxygennamespace:: m_lanczos
:project: edrixs

Source files
============

fock.f90
--------

.. doxygenfile:: fock.f90
:project: edrixs

ham.f90
-------

.. doxygenfile:: ham.f90
:project: edrixs

utils.f90
---------

.. doxygenfile:: utils.f90
:project: edrixs

spmv.f90
--------

.. doxygenfile:: spmv.f90
:project: edrixs

full_diag.f90
-------------

.. doxygenfile:: full_diag.f90
:project: edrixs

linsys.f90
----------

.. doxygenfile:: linsys.f90
:project: edrixs

io.f90
------

.. doxygenfile:: io.f90
:project: edrixs

Solver drivers
==============

ed_driver.f90
-------------

.. doxygenfile:: ed_driver.f90
:project: edrixs

xas_driver.f90
--------------

.. doxygenfile:: xas_driver.f90
:project: edrixs

rixs_driver.f90
---------------

.. doxygenfile:: rixs_driver.f90
:project: edrixs

opavg_driver.f90
----------------

.. doxygenfile:: opavg_driver.f90
:project: edrixs
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ edrixs Documentation
user/index
auto_examples/index
reference/index
fortran_api
release-history
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ Pillow
sphinx-copybutton
sphinx_rtd_theme
sphinx-gallery
breathe
Loading
Loading