Symmetrisation of tmdata.
Former-commit-id: 504457d0259578a8eaa8db720c0f1995c5bbc6cc
This commit is contained in:
parent
d5652b126e
commit
d2f124ab12
|
@ -11,6 +11,7 @@
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "wigner.h"
|
#include "wigner.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "qpms_error.h"
|
||||||
|
|
||||||
|
|
||||||
#define QPMS_SCATSYS_LEN_RTOL 1e-13
|
#define QPMS_SCATSYS_LEN_RTOL 1e-13
|
||||||
|
@ -86,6 +87,71 @@ qpms_tmatrix_t *qpms_tmatrix_apply_symop(
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qpms_errno_t qpms_symmetrise_tmdata_irot3arr(
|
||||||
|
complex double *tmdata, const size_t tmcount,
|
||||||
|
const qpms_vswf_set_spec_t *bspec,
|
||||||
|
const size_t n_symops, const qpms_irot3_t *symops) {
|
||||||
|
const size_t n = bspec->n;
|
||||||
|
qpms_tmatrix_t *tmcopy = qpms_tmatrix_init(bspec);
|
||||||
|
complex double *symop_matrices = malloc(n*n*sizeof(complex double) * n_symops);
|
||||||
|
if(!symop_matrices) qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
|
||||||
|
"malloc() failed.");
|
||||||
|
for (size_t i = 0; i < n_symops; ++i)
|
||||||
|
qpms_irot3_uvswfi_dense(symop_matrices + i*n*n, bspec, symops[i]);
|
||||||
|
complex double tmp[n][n];
|
||||||
|
const complex double one = 1, zero = 0;
|
||||||
|
for (size_t tmi = 0; tmi < tmcount; ++tmi) {
|
||||||
|
// Move the data in tmcopy; we will then write the sum directly into tmdata.
|
||||||
|
memcpy(tmcopy->m, tmdata+n*n*tmi, n*n*sizeof(complex double));
|
||||||
|
memset(tmdata+n*n*tmi, 0, n*n*sizeof(complex double));
|
||||||
|
for (size_t i = 0; i < n_symops; ++i) {
|
||||||
|
const complex double *const M = symop_matrices + i*n*n;
|
||||||
|
// tmp = M T
|
||||||
|
cblas_zgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
|
||||||
|
n, n, n, &one, M, n, tmcopy->m, n, &zero, tmp, n);
|
||||||
|
// tmdata[...] += tmp M* = M T M*
|
||||||
|
cblas_zgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans,
|
||||||
|
n, n, n, &one, tmp, n, M, n, &one, tmdata + tmi*n*n, n);
|
||||||
|
}
|
||||||
|
for (size_t ii = 0; ii < n*n; ++ii)
|
||||||
|
tmdata[n*n*tmi+ii] /= n_symops;
|
||||||
|
}
|
||||||
|
free(symop_matrices);
|
||||||
|
qpms_tmatrix_free(tmcopy);
|
||||||
|
return QPMS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
qpms_errno_t qpms_symmetrise_tmdata_finite_group(
|
||||||
|
complex double *tmdata, const size_t tmcount,
|
||||||
|
const qpms_vswf_set_spec_t *bspec,
|
||||||
|
const qpms_finite_group_t *pointgroup) {
|
||||||
|
if (!(pointgroup->rep3d)) qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
|
||||||
|
"This function requires pointgroup->rep3d to be set correctly!");
|
||||||
|
return qpms_symmetrise_tmdata_irot3arr(tmdata, tmcount, bspec,
|
||||||
|
pointgroup->order, pointgroup->rep3d);
|
||||||
|
}
|
||||||
|
|
||||||
|
qpms_tmatrix_t *qpms_tmatrix_symmetrise_irot3arr_inplace(
|
||||||
|
qpms_tmatrix_t *T,
|
||||||
|
size_t n_symops,
|
||||||
|
const qpms_irot3_t *symops
|
||||||
|
) {
|
||||||
|
if(qpms_symmetrise_tmdata_irot3arr(T->m, 1,
|
||||||
|
T->spec, n_symops, symops) != QPMS_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
else return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
qpms_tmatrix_t *qpms_tmatrix_symmetrise_finite_group_inplace(
|
||||||
|
qpms_tmatrix_t *T,
|
||||||
|
const qpms_finite_group_t *pointgroup
|
||||||
|
) {
|
||||||
|
if(qpms_symmetrise_tmdata_finite_group(T->m, 1,
|
||||||
|
T->spec, pointgroup) != QPMS_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
else return T;
|
||||||
|
}
|
||||||
|
|
||||||
qpms_tmatrix_t *qpms_tmatrix_symmetrise_involution_inplace(
|
qpms_tmatrix_t *qpms_tmatrix_symmetrise_involution_inplace(
|
||||||
qpms_tmatrix_t *T,
|
qpms_tmatrix_t *T,
|
||||||
const complex double *M
|
const complex double *M
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
/*! \file scatsystem.h
|
/*! \file scatsystem.h
|
||||||
* \brief Modern interface for finite lattice calculations, including symmetries.
|
* \brief Modern interface for finite lattice calculations, including symmetries.
|
||||||
|
*
|
||||||
|
* N.B. Only "reasonably normalised" waves are supported now in most of the
|
||||||
|
* functions defined here, i.e. those that can be rotated by the usual
|
||||||
|
* Wigner matrices, i.e. the "power" or "spharm" -normalised ones.
|
||||||
|
*
|
||||||
|
* TODO FIXME check whether Condon-Shortley phase can have some nasty influence
|
||||||
|
* here; I fear that yes.
|
||||||
*/
|
*/
|
||||||
#ifndef QPMS_SCATSYSTEM_H
|
#ifndef QPMS_SCATSYSTEM_H
|
||||||
#define QPMS_SCATSYSTEM_H
|
#define QPMS_SCATSYSTEM_H
|
||||||
|
@ -27,6 +34,9 @@ typedef struct qpms_tmatrix_t {
|
||||||
bool owns_m; ///< Information wheter m shall be deallocated with qpms_tmatrix_free()
|
bool owns_m; ///< Information wheter m shall be deallocated with qpms_tmatrix_free()
|
||||||
} qpms_tmatrix_t;
|
} qpms_tmatrix_t;
|
||||||
|
|
||||||
|
struct qpms_finite_group_t;
|
||||||
|
typedef struct qpms_finite_group_t qpms_finite_group_t;
|
||||||
|
|
||||||
/// Returns a pointer to the beginning of the T-matrix row \a rowno.
|
/// Returns a pointer to the beginning of the T-matrix row \a rowno.
|
||||||
static inline complex double *qpms_tmatrix_row(qpms_tmatrix_t *t, size_t rowno){
|
static inline complex double *qpms_tmatrix_row(qpms_tmatrix_t *t, size_t rowno){
|
||||||
return t->m + (t->spec->n * rowno);
|
return t->m + (t->spec->n * rowno);
|
||||||
|
@ -162,7 +172,6 @@ qpms_errno_t qpms_load_scuff_tmatrix(
|
||||||
qpms_tmatrix_t **tmatrices_array,
|
qpms_tmatrix_t **tmatrices_array,
|
||||||
complex double **tmdata ///< The T-matrices raw contents
|
complex double **tmdata ///< The T-matrices raw contents
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Loads a scuff-tmatrix generated file.
|
/// Loads a scuff-tmatrix generated file.
|
||||||
/** A simple wrapper over qpms_read_scuff_tmatrix() that needs a
|
/** A simple wrapper over qpms_read_scuff_tmatrix() that needs a
|
||||||
* path instead of open FILE.
|
* path instead of open FILE.
|
||||||
|
@ -185,20 +194,53 @@ qpms_errno_t qpms_read_scuff_tmatrix(
|
||||||
complex double ** tmdata
|
complex double ** tmdata
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Loads scuff-tmatrix generated files.
|
/// In-place application of point group elements on raw T-matrix data.
|
||||||
/**
|
/** \a tmdata can be e.g. obtained by qpms_load_scuff_tmatrix().
|
||||||
* freqs, freqs_su, tmatrices_array and tmdata arrays are allocated by this function
|
* The \a symops array should always contain all elements of a finite
|
||||||
* and have to be freed by the caller after use.
|
* point (sub)group, including the identity operation.
|
||||||
* The contents of tmatrices_array is NOT supposed to be freed element per element.
|
*
|
||||||
|
* TODO more doc.
|
||||||
*/
|
*/
|
||||||
qpms_errno_t qpms_load_scuff_tmatrix(
|
qpms_errno_t qpms_symmetrise_tmdata_irot3arr(
|
||||||
const char *path, ///< Path to the TMatrix file
|
complex double *tmdata, const size_t tmcount,
|
||||||
const qpms_vswf_set_spec_t *bspec, ///< VSWF set spec
|
const qpms_vswf_set_spec_t *bspec,
|
||||||
size_t *n, ///< Number of successfully loaded t-matrices
|
size_t n_symops,
|
||||||
double **freqs, ///< Frequencies in SI units
|
const qpms_irot3_t *symops
|
||||||
double **freqs_su, ///< Frequencies in SCUFF units (optional)
|
);
|
||||||
qpms_tmatrix_t **tmatrices_array, ///< The resulting T-matrices.
|
|
||||||
complex double **tmdata ///< The t-matrices raw contents
|
/// In-place application of a point group on raw T-matrix data.
|
||||||
|
/** This does the same as qpms_symmetrise_tmdata_irot3arr(),
|
||||||
|
* but takes a valid finite point group as an argument.
|
||||||
|
*
|
||||||
|
* TODO more doc.
|
||||||
|
*/
|
||||||
|
qpms_errno_t qpms_symmetrise_tmdata_finite_group(
|
||||||
|
complex double *tmdata, const size_t tmcount,
|
||||||
|
const qpms_vswf_set_spec_t *bspec,
|
||||||
|
const qpms_finite_group_t *pointgroup
|
||||||
|
);
|
||||||
|
|
||||||
|
/// In-place application of point group elements on a T-matrix.
|
||||||
|
/** The \a symops array should always contain all elements of a finite
|
||||||
|
* point (sub)group, including the identity operation.
|
||||||
|
*
|
||||||
|
* TODO more doc.
|
||||||
|
*/
|
||||||
|
qpms_tmatrix_t *qpms_tmatrix_symmetrise_irot3arr_inplace(
|
||||||
|
qpms_tmatrix_t *T,
|
||||||
|
size_t n_symops,
|
||||||
|
const qpms_irot3_t *symops
|
||||||
|
);
|
||||||
|
|
||||||
|
/// In-place application of point group elements on a T-matrix.
|
||||||
|
/** This does the same as qpms_tmatrix_symmetrise_irot3arr(),
|
||||||
|
* but takes a valid finite point group as an argument.
|
||||||
|
*
|
||||||
|
* TODO more doc.
|
||||||
|
*/
|
||||||
|
qpms_tmatrix_t *qpms_tmatrix_symmetrise_finite_group_inplace(
|
||||||
|
qpms_tmatrix_t *T,
|
||||||
|
const qpms_finite_group_t *pointgroup
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Fuck this, include the whole <gsl/gsl_spline.h>
|
/* Fuck this, include the whole <gsl/gsl_spline.h>
|
||||||
|
@ -244,7 +286,6 @@ typedef struct qpms_particle_tid_t {
|
||||||
qpms_ss_tmi_t tmatrix_id; ///< T-matrix index
|
qpms_ss_tmi_t tmatrix_id; ///< T-matrix index
|
||||||
} qpms_particle_tid_t;
|
} qpms_particle_tid_t;
|
||||||
|
|
||||||
struct qpms_finite_group_t;
|
|
||||||
|
|
||||||
typedef qpms_gmi_t qpms_ss_orbit_pi_t; ///< Auxilliary type used in qpms_ss_orbit_type_t for labeling particles inside orbits.
|
typedef qpms_gmi_t qpms_ss_orbit_pi_t; ///< Auxilliary type used in qpms_ss_orbit_type_t for labeling particles inside orbits.
|
||||||
typedef qpms_ss_tmi_t qpms_ss_oti_t; ///< Auxilliary type used for labeling orbit types.
|
typedef qpms_ss_tmi_t qpms_ss_oti_t; ///< Auxilliary type used for labeling orbit types.
|
||||||
|
|
|
@ -29,6 +29,10 @@ qpms_errno_t qpms_read_scuff_tmatrix(
|
||||||
if (!(freqs && n && tmdata))
|
if (!(freqs && n && tmdata))
|
||||||
qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
|
qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
|
||||||
"freqs, n, and tmdata are mandatory arguments and must not be NULL.");
|
"freqs, n, and tmdata are mandatory arguments and must not be NULL.");
|
||||||
|
if (bs->norm != QPMS_NORMALISATION_POWER_CS) // CHECKME CORRECT?
|
||||||
|
qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
|
||||||
|
"Not implemented; only QPMS_NORMALISATION_POWER_CS (CHECKME)"
|
||||||
|
" norm supported right now.");
|
||||||
int n_alloc = 128; // First chunk to allocate
|
int n_alloc = 128; // First chunk to allocate
|
||||||
*n = 0;
|
*n = 0;
|
||||||
*freqs = malloc(n_alloc * sizeof(double));
|
*freqs = malloc(n_alloc * sizeof(double));
|
||||||
|
|
Loading…
Reference in New Issue