From 4f5ead92a9e6d39ce725559cac3119b3afdf5769 Mon Sep 17 00:00:00 2001 From: Giovanni La Mura <giovanni.lamura@inaf.it> Date: Wed, 8 Nov 2023 14:58:34 +0100 Subject: [PATCH] Introduce data structures for the cluster case --- src/include/Commons.h | 175 ++++++++++++++++++++++++++++++++++++- src/libnptm/Commons.cpp | 185 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 345 insertions(+), 15 deletions(-) diff --git a/src/include/Commons.h b/src/include/Commons.h index 088dcc74..eef2cdaa 100644 --- a/src/include/Commons.h +++ b/src/include/Commons.h @@ -7,15 +7,15 @@ * the data blocks in the code, therefore implying the necessity to modify * the code to adapt it to the input and to recompile before running. C++, * on the contrary, offers the possibility to represent the necessary data - * structures as classes that can dinamically instantiate the shared information + * structures as classes that can dynamically instantiate the shared information * in the most convenient format for the current configuration. This approach * adds an abstraction layer that lifts the need to modify and recompile the * code depending on the input. * */ -#ifndef SRC_INCLUDE_COMMONS_ -#define SRC_INCLUDE_COMMONS_ +#ifndef INCLUDE_COMMONS_ +#define INCLUDE_COMMONS_ #include <complex> @@ -89,7 +89,7 @@ public: * \param ns: `int` Number of spheres. * \param l_max: `int` Maximum order of field expansion. */ - C1(int ns, int l_max); + C1(int ns, int l_max, int *nshl, int *iog); //! \brief C1 instance destroyer. ~C1(); @@ -128,4 +128,171 @@ public: ~C2(); }; +/*! \brief Representation of the FORTRAN C3 blocks. + */ +class C3 { +public: + //! \brief QUESTION: definition? + std::complex<double> tfsas; + //! \brief QUESTION: definition? + std::complex<double> **tsas; + //! \brief QUESTION: definition? + double gcs; + //! \brief QUESTION: definition? + double scs; + //! \brief QUESTION: definition? + double ecs; + //! \brief QUESTION: definition? + double acs; + + /*! \brief C3 instance constructor. + */ + C3(); + + /*! \brief C3 instance destroyer. + */ + ~C3(); +}; + +/*! \brief Representation of the FORTRAN C4 blocks. + */ +struct C4 { + //! \brief QUESTION: definition? + int litpo; + //! \brief QUESTION: definition? + int litpos; + //! \brief QUESTION: definition? + int lmpo; + //! \brief QUESTION: definition? + int lmtpo; + //! \brief QUESTION: definition? + int lmtpos; + //! \brief QUESTION: definition? + int li; + //! \brief QUESTION: definition? + int nlim; + //! \brief QUESTION: definition? + int le; + //! \brief QUESTION: definition? + int nlem; + //! \brief Maximum field expansion order. QUESTION: correct? + int lm; + //! \brief Number of spheres. + int nsph; +}; + +/*! \brief Vectors and matrices that are specific to cluster C1 blocks. + * + */ +class C1_AddOns { +protected: + //! \brief Number of spheres. + int nsph; + //! \brief QUESTION: definition? + int nlemt; + //! \brief QUESTION: definition? + int lmpo; + + void allocate_vectors(C4 *c4); +public: + //! \brief QUESTION: definition? + std::complex<double> *vh; + //! \brief QUESTION: definition? + std::complex<double> *vj; + //! \brief QUESTION: definition? + std::complex<double> *vyhj; + //! \brief QUESTION: definition? + std::complex<double> *vyj0; + //! \brief QUESTION: definition? + std::complex<double> **am0m; + //! \brief QUESTION: definition? + std::complex<double> *vint; + //! \brief QUESTION: definition? + std::complex<double> *vintm; + //! \brief QUESTION: definition? + std::complex<double> *vintt; + //! \brief QUESTION: definition? + std::complex<double> **fsac; + //! \brief QUESTION: definition? + std::complex<double> **sac; + //! \brief QUESTION: definition? + std::complex<double> **fsacm; + //! \brief QUESTION: definition? + std::complex<double> *scscp; + //! \brief QUESTION: definition? + std::complex<double> *ecscp; + //! \brief QUESTION: definition? + std::complex<double> *scscpm; + //! \brief QUESTION: definition? + std::complex<double> *ecscpm; + //! \brief QUESTION: definition? + double *v3j0; + //! \brief QUESTION: definition? + double *sscs; + //! \brief QUESTION: definition? + int **ind3j; + + /*! \brief C1_AddOns instance constructor. + * + * \param ns: `int` Number of spheres. + * \param nc: `int` + * \param litpo: `int` + * \param lmtpo: `int` + * \param nv3j: `int` + * \param lmpo: `int` + * \param li: `int` + * \param le: `int` + * \param lm: `int` + */ + C1_AddOns(C4 *c4); + + //! \brief C1_AddOns instance destroyer. + ~C1_AddOns(); +}; + +/*! \brief Representation of the FORTRAN C6 blocks. + */ +class C6 { +public: + //! \brief QUESTION: definition? + double *rac3j; + + /*! \brief C6 instance constructor. + * + * \param lmtpo: `int` QUESTION: definition? + */ + C6(int lmtpo); + + /*! \brief C6 instance destroyer. + */ + ~C6(); +}; + +/*! \brief Representation of the FORTRAN C9 blocks. + */ +class C9 { +protected: + int gis_size_0; + int sam_size_0; +public: + //! \brief QUESTION: definition? + std::complex<double> **gis; + //! \brief QUESTION: definition? + std::complex<double> **gls; + //! \brief QUESTION: definition? + std::complex<double> **sam; + + /*! \brief C9 instance constructor. + * + * \param ndi: `int` QUESTION: definition? + * \param nlem: `int` QUESTION: definition? + * \param ndit: `int` QUESTION: definition? + * \param nlemt: `int` QUESTION: definition? + */ + C9(int ndi, int nlem, int ndit, int nlemt); + + /*! \brief C9 instance destroyer. + */ + ~C9(); +}; #endif diff --git a/src/libnptm/Commons.cpp b/src/libnptm/Commons.cpp index 809337ea..2140c69a 100644 --- a/src/libnptm/Commons.cpp +++ b/src/libnptm/Commons.cpp @@ -1,12 +1,23 @@ /*! \file Commons.cpp * + * DEVELOPMENT NOTE: + * The construction of common blocks requires some information + * that is stored in configuration objects and is needed to compute + * the allocation size of vectors and matrices. Currently, this + * information is passed as arguments to the constructors of the + * common blocks. A simpler and more logical way to operate is + * to design the constructors to take as arguments only pointers + * to the configuration objects. These, on their turn, need to + * expose methods to access the relevant data in read-only mode. */ +#ifndef INCLUDE_COMMONS_H #include "../include/Commons.h" +#endif using namespace std; -C1::C1(int ns, int l_max) { +C1::C1(int ns, int l_max, int *_nshl, int *_iog) { nlmmt = 2 * (l_max * (l_max + 2)); nsph = ns; lm = l_max; @@ -21,9 +32,13 @@ C1::C1(int ns, int l_max) { for (int wi = 0; wi < nlmmt; wi++) w[wi] = new complex<double>[4]; vints = new complex<double>*[nsph]; rc = new double*[nsph]; + nshl = new int[nsph]; + iog = new int[nsph]; for (int vi = 0; vi < nsph; vi++) { - rc[vi] = new double[lm]; + rc[vi] = new double[_nshl[vi]]; vints[vi] = new complex<double>[16]; + nshl[vi] = _nshl[vi]; + iog[vi] = _iog[vi]; } fsas = new complex<double>[nsph]; sscs = new double[nsph]; @@ -37,8 +52,6 @@ C1::C1(int ns, int l_max) { ryy = new double[nsph]; rzz = new double[nsph]; ros = new double[nsph]; - iog = new int[nsph]; - nshl = new int[nsph]; sas = new complex<double>**[nsph]; for (int si = 0; si < nsph; si++) { @@ -51,15 +64,19 @@ C1::C1(int ns, int l_max) { C1::~C1() { delete[] rmi; delete[] rei; - for (int wi = 1; wi <= nlmmt; wi++) delete[] w[wi]; - for (int vi = 1; vi <= nsph; vi++) { - delete[] rc[nsph - vi]; - delete[] vints[nsph - vi]; + for (int wi = nlmmt - 1; wi > -1; wi--) delete[] w[wi]; + for (int vi = nsph - 1; vi > - 1; vi--) { + delete[] rc[vi]; + delete[] vints[vi]; } - for (int si = 1; si <= nsph; si++) { - delete[] sas[nsph - si][1]; - delete[] sas[nsph - si][0]; + delete[] rc; + delete[] vints; + for (int si = nsph - 1; si > -1; si--) { + delete[] sas[si][1]; + delete[] sas[si][0]; + delete[] sas[si]; } + delete[] sas; delete[] fsas; delete[] sscs; delete[] sexs; @@ -76,6 +93,103 @@ C1::~C1() { delete[] nshl; } +C1_AddOns::C1_AddOns(C4 *c4) { + nsph = c4->nsph; + lmpo = c4->lmpo; + nlemt = 2 * c4->nlem; + vh = new complex<double>[(nsph * nsph - 1) * c4->litpo]; + vj = new complex<double>[nsph * c4->lmtpo]; + vyhj = new complex<double>[nsph * (nsph - 1) * c4->litpo]; + vyj0 = new complex<double>[nsph * c4->lmtpo]; + am0m = new complex<double>*[nlemt]; + for (int ai = 0; ai < nlemt; ai++) { + am0m[ai] = new complex<double>[nlemt]; + } + vint = new complex<double>[16]; + vintm = new complex<double>[16]; + vintt = new complex<double>[16]; + fsac = new complex<double>*[2]; + sac = new complex<double>*[2]; + fsacm = new complex<double>*[2]; + for (int fi = 0; fi < 2; fi++) { + fsac[fi] = new complex<double>[2]; + sac[fi] = new complex<double>[2]; + fsacm[fi] = new complex<double>[2]; + } + scscp = new complex<double>[2]; + ecscp = new complex<double>[2]; + scscpm = new complex<double>[2]; + ecscpm = new complex<double>[2]; + allocate_vectors(c4); + sscs = new double[nsph]; +} + +C1_AddOns::~C1_AddOns() { + delete[] sscs; + delete[] vyj0; + delete[] vyhj; + for (int ii = lmpo - 1; ii > -1; ii--) delete[] ind3j[ii]; + delete[] ind3j; + delete[] v3j0; + delete[] vh; + delete[] vj; + for (int ai = nlemt - 1; ai > -1; ai--) { + delete[] am0m[ai]; + } + delete am0m; + delete[] vint; + delete[] vintm; + delete[] vintt; + for (int fi = 1; fi > -1; fi--) { + delete[] fsac[fi]; + delete[] sac[fi]; + delete[] fsacm[fi]; + } + delete[] fsac; + delete[] sac; + delete[] fsacm; + delete[] scscp; + delete[] ecscp; + delete[] scscpm; + delete[] ecscpm; +} + +void C1_AddOns::allocate_vectors(C4 *c4) { + int i = 0; + int l1po_max = 0, l2_max = 0; + int i_max = 0; + // This loop calculates NV3J, the required size of v3j0 + for (int l1po = 1; l1po <= c4->lmpo; l1po++) { + int l1 = l1po - 1; + for (int l2 = 1; l2 <= c4->lm; l2++) { + if (l1po > l1po_max) l1po_max = l1po; + if (l2 > l2_max) l2_max = l2; + int iabs = l2 - l1; + if (iabs < 0) iabs *= -1; + int lmnpo = iabs + 1; + int lmxpo = l2 + l1 + 1; + int il = 0; + int lpo = lmnpo; + while (lpo <= lmxpo) { + i++; + il++; + if (i > i_max) i_max = i; + lpo += 2; + } + } + } // l1po loop + v3j0 = new double[i_max]; + ind3j = new int*[lmpo]; + for (int ii = 0; ii < lmpo; ii++) ind3j[ii] = new int[c4->lm]; + // This calculates the size of vyhj + int nsphmo = c4->nsph - 1; + int ivy = nsphmo * nsph * c4->litpos; + vyhj = new complex<double>[ivy]; + // This calculates the size of vyj0 + ivy = c4->lmtpos * c4->nsph; + vyj0 = new complex<double>[ivy]; +} + C2::C2(int ns, int nl, int npnt, int npntts) { nsph = ns; int max_n = (npnt > npntts) ? npnt : npntts; @@ -94,3 +208,52 @@ C2::~C2() { delete[] dc0; delete[] vsz; } + +C3::C3() { + tsas = new complex<double>*[2]; + tsas[0] = new complex<double>[2]; + tsas[1] = new complex<double>[2]; + tfsas = complex<double>(0.0, 0.0); + gcs = 0.0; + scs = 0.0; + ecs = 0.0; + acs = 0.0; +} + +C3::~C3() { + delete[] tsas[1]; + delete[] tsas[0]; + delete[] tsas; +} + +C6::C6(int lmtpo) { + rac3j = new double[lmtpo]; +} + +C6::~C6() { + delete[] rac3j; +} + +C9::C9(int ndi, int nlem, int ndit, int nlemt) { + gis = new complex<double>*[ndi]; + gls = new complex<double>*[ndi]; + for (int gi = 0; gi < ndi; gi++) { + gis[gi] = new complex<double>[nlem]; + gls[gi] = new complex<double>[nlem]; + } + sam = new complex<double>*[ndit]; + for (int si = 0; si < ndit; si++) sam[si] = new complex<double>[nlemt]; + gis_size_0 = ndi; + sam_size_0 = ndit; +} + +C9::~C9() { + for (int gi = gis_size_0 - 1; gi > -1; gi--) { + delete[] gis[gi]; + delete[] gls[gi]; + } + delete[] gis; + delete[] gls; + for (int si = sam_size_0 - 1; si > -1; si--) delete[] sam[si]; + delete[] sam; +} -- GitLab