diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..f6101d1801630bbe293df6ead7f521e9acdd2dd8 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,103 @@ +# CI pipeline configuration + +default: + image: gcc + +# Switch from branch pipelines to merge request pipelines when a merge request is created +workflow: + rules: + # Ensures next rules do not block triggered pipelines + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + # always run for merge requests + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + # never run a branch pipeline if there is an open merge request for that branch + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never + # the only allowed branch pipeline is that on the default branch + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + +stages: + - build + - run + - test + +building_stage: + stage: build + allow_failure: false + #artifacts: + # paths: + # - build/cluster/* + # - build/sphere/* + # - build/trapping/* + # exclude: + # - ".git*" + # - ".git/**/*" + # expire_in: 2 hours + script: + # bash commands to be executed + - pwd + - hostname + - echo $CI_COMMIT_SHA + - echo $CI_COMMIT_BRANCH + - cd src + - echo "Running make (ONLY C++ CODE)" + #- make conly + +running_stage: + stage: run + allow_failure: false + needs: + - job: building_stage + #artifacts: + # paths: + # - build/cluster/* + # - build/sphere/* + # - build/trapping/* + # exclude: + # - ".git*" + # - ".git/**/*" + # expire_in: 2 hours + script: + # bash commands to be executed + - pwd + - hostname + - echo $CI_COMMIT_SHA + - echo $CI_COMMIT_BRANCH + - cd build/sphere + - echo "Running np_sphere" + #- chmod +x np_sphere + #- ./np_sphere + - cd ../cluster + - echo "Running np_cluster" + #- chmod +x np_cluster + #- ./np_cluster + +testing_stage: + stage: test + allow_failure: true + needs: + - job: running_stage + #artifacts: + # paths: + # - build/cluster/pycompare.html + # - build/sphere/pycompare.html + # exclude: + # - ".git*" + # - ".git/**/*" + # expire_in: 2 hours + script: + # bash commands to be executed + - pwd + - hostname + - echo $CI_COMMIT_SHA + - echo $CI_COMMIT_BRANCH + - cd build/sphere + #- cp ../../test_data/sphere/OSPH . + - echo "Comparing output of SPHERE" + #- python3 ../../src/scripts/pycompare.py --ffile=OSPH --cfile=c_OSPH --html + - cd ../cluster + - echo "Comparing output of CLUSTER" + #- cp ../../test_data/cluster/OCLU . + #- python3 ../../src/scripts/pycompare.py --ffile=OCLU --cfile=c_OCLU --html + diff --git a/README.md b/README.md index 14ea5b2a486b109b3a52139f7ab5c80405e8d9ab..15766ce3810b67aaa98dd64ac920233c06b0e1ee 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ The aim of the project, funded by PNRR-CNS, is to refactor the original, very ol The current implementation offers a set of elementary tests to check that the original FORTRAN code can be compiled and executed on a limited set of pre-defined input data. The functionality of this initial stage can be verified by cloning the gitLab repository on a local machine and building the binaries from the `src` folder. -*NOTE:* The building process requires a working installation of the GNU Compiler Collection (GCC), of the GNU FORTRAN compiler (gfortran) and of the GNU make builder. +*NOTE:* The building process requires a working installation of the GNU Compiler Collection (`gcc`), of the GNU FORTRAN compiler (`gfortran`) and of the GNU `make` builder. diff --git a/src/cluster/cluster.cpp b/src/cluster/cluster.cpp index 4c08ba9e21ff7cdb82e15175d06a9eaf97fbabf6..ba2c38a4d3d01f47dadc5656ddc230db74729fc4 100644 --- a/src/cluster/cluster.cpp +++ b/src/cluster/cluster.cpp @@ -24,10 +24,25 @@ using namespace std; */ void cluster(string config_file, string data_file, string output_path) { printf("INFO: making legacy configuration..."); - ScattererConfiguration *sconf = ScattererConfiguration::from_dedfb(config_file); - sconf->write_formatted(output_path + "/c_OEDFB_clu"); - sconf->write_binary(output_path + "/c_TEDF_clu"); - GeometryConfiguration *gconf = GeometryConfiguration::from_legacy(data_file); + ScattererConfiguration *sconf = NULL; + try { + sconf = ScattererConfiguration::from_dedfb(config_file); + } catch(const OpenConfigurationFileException &ex) { + printf("\nERROR: failed to open scatterer configuration file.\n"); + printf("FILE: %s\n", ex.what()); + exit(1); + } + sconf->write_formatted(output_path + "/c_OEDFB"); + sconf->write_binary(output_path + "/c_TEDF"); + GeometryConfiguration *gconf = NULL; + try { + gconf = GeometryConfiguration::from_legacy(data_file); + } catch (const OpenConfigurationFileException &ex) { + printf("\nERROR: failed to open geometry configuration file.\n"); + printf("FILE: %s\n", ex.what()); + if (sconf) delete sconf; + exit(1); + } printf(" done.\n"); if (sconf->number_of_spheres == gconf->number_of_spheres) { // Shortcuts to variables stored in configuration objects diff --git a/src/include/Configuration.h b/src/include/Configuration.h index e784fa38bf0bd7b2f681102f0cbba5bbb7628028..c23ac6924cf3595fef13f4e72f76c5e85aaddd87 100644 --- a/src/include/Configuration.h +++ b/src/include/Configuration.h @@ -13,24 +13,23 @@ */ class OpenConfigurationFileException: public std::exception { protected: - //! \brief Name of the file that was accessed. - std::string file_name; + //! \brief Name of the file that was accessed. + std::string file_name; public: - /** - * \brief Exception instance constructor. - * - * \param name: `string` Name of the file that was accessed. - */ - OpenConfigurationFileException(std::string name) { file_name = name; } + /** + * \brief Exception instance constructor. + * + * \param name: `string` Name of the file that was accessed. + */ + OpenConfigurationFileException(std::string name) { file_name = name; } - /** - * \brief Exception message. - */ - virtual const char* what() const throw() { - std::string message = "Error opening configuration file: " + file_name; - return message.c_str(); - } + /** + * \brief Exception message. + */ + virtual const char* what() const throw() { + return file_name.c_str(); + } }; /** @@ -38,21 +37,21 @@ public: */ class UnrecognizedConfigurationException: public std::exception { protected: - //! Description of the problem. - std::string message; + //! Description of the problem. + std::string message; public: - /** - * \brief Exception instance constructor. - * - * \param problem: `string` Description of the problem that occurred. - */ - UnrecognizedConfigurationException(std::string problem) { message = problem; } - /** - * \brief Exception message. - */ - virtual const char* what() const throw() { - return message.c_str(); - } + /** + * \brief Exception instance constructor. + * + * \param problem: `string` Description of the problem that occurred. + */ + UnrecognizedConfigurationException(std::string problem) { message = problem; } + /** + * \brief Exception message. + */ + virtual const char* what() const throw() { + return message.c_str(); + } }; /** @@ -64,97 +63,97 @@ public: * fields and their polarization properties. */ class GeometryConfiguration { - //! Temporary work-around to allow cluster() and sphere() peeking in. - friend void cluster(std::string, std::string, std::string); - friend void sphere(std::string, std::string, std::string); + //! Temporary work-around to allow cluster() and sphere() peeking in. + friend void cluster(std::string, std::string, std::string); + friend void sphere(std::string, std::string, std::string); protected: - //! \brief Number of spherical components. - int number_of_spheres; - //! \brief Maximum expansion order of angular momentum. - int l_max; - //! \brief QUESTION: definition? - int li; - //! \brief QUESTION: definition? - int le; - //! \brief QUESTION: definition? - int mxndm; - //! \brief QUESTION: definition? - int iavm; - //! \brief Incident field polarization status (0 - linear, 1 - circular). - int in_pol; - //! \brief Number of transition points. QUESTION: correct? - int npnt; - //! \brief Transition smoothness. QUESTION: correct? - int npntts; - //! \brief Type of meridional plane definition. - int meridional_type; - //! \brief Transition matrix layer ID. QUESTION: correct? - int jwtm; - //! \brief Incident field initial azimuth. - double in_theta_start; - //! \brief Incident field azimuth step. - double in_theta_step; - //! \brief Incident field final azimuth. - double in_theta_end; - //! \brief Scattered field initial azimuth. - double sc_theta_start; - //! \brief Scattered field azimuth step. - double sc_theta_step; - //! \brief Scattered field final azimuth. - double sc_theta_end; - //! \brief Incident field initial elevation. - double in_phi_start; - //! \brief Incident field elevation step. - double in_phi_step; - //! \brief Incident field final elevation. - double in_phi_end; - //! \brief Scattered field initial elevation. - double sc_phi_start; - //! \brief Scattered field elevation step. - double sc_phi_step; - //! \brief Scattered field final elevation. - double sc_phi_end; - //! \brief Vector of spherical components X coordinates. - double *sph_x; - //! \brief Vector of spherical components Y coordinates. - double *sph_y; - //! \brief Vector of spherical components Z coordinates. - double *sph_z; + //! \brief Number of spherical components. + int number_of_spheres; + //! \brief Maximum expansion order of angular momentum. + int l_max; + //! \brief QUESTION: definition? + int li; + //! \brief QUESTION: definition? + int le; + //! \brief QUESTION: definition? + int mxndm; + //! \brief QUESTION: definition? + int iavm; + //! \brief Incident field polarization status (0 - linear, 1 - circular). + int in_pol; + //! \brief Number of transition points. QUESTION: correct? + int npnt; + //! \brief Transition smoothness. QUESTION: correct? + int npntts; + //! \brief Type of meridional plane definition. + int meridional_type; + //! \brief Transition matrix layer ID. QUESTION: correct? + int jwtm; + //! \brief Incident field initial azimuth. + double in_theta_start; + //! \brief Incident field azimuth step. + double in_theta_step; + //! \brief Incident field final azimuth. + double in_theta_end; + //! \brief Scattered field initial azimuth. + double sc_theta_start; + //! \brief Scattered field azimuth step. + double sc_theta_step; + //! \brief Scattered field final azimuth. + double sc_theta_end; + //! \brief Incident field initial elevation. + double in_phi_start; + //! \brief Incident field elevation step. + double in_phi_step; + //! \brief Incident field final elevation. + double in_phi_end; + //! \brief Scattered field initial elevation. + double sc_phi_start; + //! \brief Scattered field elevation step. + double sc_phi_step; + //! \brief Scattered field final elevation. + double sc_phi_end; + //! \brief Vector of spherical components X coordinates. + double *sph_x; + //! \brief Vector of spherical components Y coordinates. + double *sph_y; + //! \brief Vector of spherical components Z coordinates. + double *sph_z; public: - /*! \brief Build a scattering geometry configuration structure. - * - * \param nsph: `int` Number of spheres to be used in calculation. - * \param lm: `int` Maximum field angular momentum expansion order. - * \param in_pol: `int` Incident field polarization status - * \param npnt: `int` Number of transition points. QUESTION: correct? - * \param npntts: `int` Transition smoothness. QUESTION: correct? - * \param meridional_type: `int` Type of meridional plane definition (<0 - * for incident angles, 0 if determined by incidence and observation, =1 - * accross z-axis for incidence and observation, >1 across z-axis as a - * function of incidence angles for fixed scattering). - * \param li: `int` - * \param le: `int` - * \param mxndm: `int` - * \param iavm: `int` - * \param x: `double*` Vector of spherical components X coordinates. - * \param y: `double*` Vector of spherical components Y coordinates. - * \param z: `double*` Vector of spherical components Z coordinates. - * \param in_th_start: `double` Incident field starting azimuth angle. - * \param in_th_step: `double` Incident field azimuth angle step. - * \param in_th_end: `double` Incident field final azimuth angle. - * \param sc_th_start: `double` Scattered field starting azimuth angle. - * \param sc_th_step: `double` Scattered field azimuth angle step. - * \param sc_th_end: `double` Scattered field final azimuth angle. - * \param in_ph_start: `double` Incident field starting elevation angle. - * \param in_ph_step: `double` Incident field elevation angle step. - * \param in_ph_end: `double` Incident field final elevation angle. - * \param sc_ph_start: `double` Scattered field starting elevation angle. - * \param sc_ph_step: `double` Scattered field elevation angle step. - * \param sc_ph_end: `double` Scattered field final elevation angle. - * \param jwtm: `int` Transition Matrix layer ID. QUESTION: correct? - */ - GeometryConfiguration( + /*! \brief Build a scattering geometry configuration structure. + * + * \param nsph: `int` Number of spheres to be used in calculation. + * \param lm: `int` Maximum field angular momentum expansion order. + * \param in_pol: `int` Incident field polarization status + * \param npnt: `int` Number of transition points. QUESTION: correct? + * \param npntts: `int` Transition smoothness. QUESTION: correct? + * \param meridional_type: `int` Type of meridional plane definition (<0 + * for incident angles, 0 if determined by incidence and observation, =1 + * accross z-axis for incidence and observation, >1 across z-axis as a + * function of incidence angles for fixed scattering). + * \param li: `int` + * \param le: `int` + * \param mxndm: `int` + * \param iavm: `int` + * \param x: `double*` Vector of spherical components X coordinates. + * \param y: `double*` Vector of spherical components Y coordinates. + * \param z: `double*` Vector of spherical components Z coordinates. + * \param in_th_start: `double` Incident field starting azimuth angle. + * \param in_th_step: `double` Incident field azimuth angle step. + * \param in_th_end: `double` Incident field final azimuth angle. + * \param sc_th_start: `double` Scattered field starting azimuth angle. + * \param sc_th_step: `double` Scattered field azimuth angle step. + * \param sc_th_end: `double` Scattered field final azimuth angle. + * \param in_ph_start: `double` Incident field starting elevation angle. + * \param in_ph_step: `double` Incident field elevation angle step. + * \param in_ph_end: `double` Incident field final elevation angle. + * \param sc_ph_start: `double` Scattered field starting elevation angle. + * \param sc_ph_step: `double` Scattered field elevation angle step. + * \param sc_ph_end: `double` Scattered field final elevation angle. + * \param jwtm: `int` Transition Matrix layer ID. QUESTION: correct? + */ + GeometryConfiguration( int nsph, int lm, int in_pol, int npnt, int npntts, int meridional_type, int li, int le, int mxndm, int iavm, double *x, double *y, double *z, @@ -163,24 +162,24 @@ public: double in_ph_start, double in_ph_step, double in_ph_end, double sc_ph_start, double sc_ph_step, double sc_ph_end, int jwtm - ); + ); - /*! \brief Destroy a GeometryConfiguration instance. - */ - ~GeometryConfiguration(); + /*! \brief Destroy a GeometryConfiguration instance. + */ + ~GeometryConfiguration(); - /*! \brief Build geometry configuration from legacy configuration input file. - * - * To allow for consistency tests and backward compatibility, geometry - * configurations can be built from legacy configuration files. This function - * replicates the approach implemented by the FORTRAN SPH and CLU codes, but - * using a C++ oriented work-flow. - * - * \param file_name: `string` Name of the legacy configuration data file. - * \return config: `GeometryConfiguration*` Pointer to object containing the - * configuration data. - */ - static GeometryConfiguration *from_legacy(std::string file_name); + /*! \brief Build geometry configuration from legacy configuration input file. + * + * To allow for consistency tests and backward compatibility, geometry + * configurations can be built from legacy configuration files. This function + * replicates the approach implemented by the FORTRAN SPH and CLU codes, but + * using a C++ oriented work-flow. + * + * \param file_name: `string` Name of the legacy configuration data file. + * \return config: `GeometryConfiguration*` Pointer to object containing the + * configuration data. + */ + static GeometryConfiguration *from_legacy(std::string file_name); }; /** @@ -190,147 +189,147 @@ public: * data to describe the scatterer properties. */ class ScattererConfiguration { - //! Temporary work-around to allow cluster() and sphere() peeking in. - friend void cluster(std::string, std::string, std::string); - friend void sphere(std::string, std::string, std::string); + //! Temporary work-around to allow cluster() and sphere() peeking in. + friend void cluster(std::string, std::string, std::string); + friend void sphere(std::string, std::string, std::string); protected: - //! \brief Matrix of dielectric parameters with size [NON_TRANS_LAYERS x N_SPHERES x LAYERS]. - std::complex<double> ***dc0_matrix; - //! \brief Vector of sphere radii expressed in m, with size [N_SPHERES]. - double *radii_of_spheres; - //! \brief Matrix of fractional transition radii with size [N_SPHERES x LAYERS]. - double **rcf; - //! \brief Vector of sphere ID numbers, with size [N_SPHERES]. - int *iog_vec; - //! \brief Vector of layer numbers for every sphere, with size [N_SPHERES]. - int *nshl_vec; - //! \brief Vector of scale parameters, with size [N_SCALES]. - double *scale_vec; - //! \brief Name of the reference variable type (one of XIV, WNS, WLS, PUS, EVS). - std::string reference_variable_name; - //! \brief Number of spherical components. - int number_of_spheres; - //! \brief Number of scales to use in calculation. - int number_of_scales; - //! \brief Type of dielectric functions (<0 at XIP, =0 as function of XI, >0 contants). - int idfc; - //! \brief External medium dielectric constant. QUESTION: correct? - double exdc; - //! \brief WP. QUESTION: better definition? - double wp; - //! \brief Peak XI. QUESTION: correct? - double xip; - //! \brief Flag to control whether to add an external layer. - bool use_external_sphere; + //! \brief Matrix of dielectric parameters with size [NON_TRANS_LAYERS x N_SPHERES x LAYERS]. + std::complex<double> ***dc0_matrix; + //! \brief Vector of sphere radii expressed in m, with size [N_SPHERES]. + double *radii_of_spheres; + //! \brief Matrix of fractional transition radii with size [N_SPHERES x LAYERS]. + double **rcf; + //! \brief Vector of sphere ID numbers, with size [N_SPHERES]. + int *iog_vec; + //! \brief Vector of layer numbers for every sphere, with size [N_SPHERES]. + int *nshl_vec; + //! \brief Vector of scale parameters, with size [N_SCALES]. + double *scale_vec; + //! \brief Name of the reference variable type (one of XIV, WNS, WLS, PUS, EVS). + std::string reference_variable_name; + //! \brief Number of spherical components. + int number_of_spheres; + //! \brief Number of scales to use in calculation. + int number_of_scales; + //! \brief Type of dielectric functions (<0 at XIP, =0 as function of XI, >0 contants). + int idfc; + //! \brief External medium dielectric constant. QUESTION: correct? + double exdc; + //! \brief WP. QUESTION: better definition? + double wp; + //! \brief Peak XI. QUESTION: correct? + double xip; + //! \brief Flag to control whether to add an external layer. + bool use_external_sphere; public: - /*! \brief Build a scatterer configuration structure. - * - * Prepare a default configuration structure by allocating the necessary - * memory structures. - * - * \param nsph: `int` The number of spheres in the simulation. - * \param scale_vector: `double*` The radiation-particle scale vector. - * \param nxi: `int` The number of radiation-particle scalings. - * \param variable_name: `string` The name of the radiation-particle scaling type. - * \param iog_vector: `int*` Array of sphere identification numbers. QUESTION: correct? - * \param ros_vector: `double*` Sphere radius array. - * \param nshl_vector: `int*` Array of layer numbers. - * \param rcf_vector: `double**` Array of fractional break radii. QUESTION: correct? - * \param dielectric_func_type: `int` Type of dielectric function definition (=0 for constant, - * \>0 as function of scale parameter, <0 for functions at XIP value and XI is scale factor - * for dimensions). - * \param dc_matrix: Matrix of reference dielectric constants. - * \param has_external: `bool` Flag to set whether to add an external spherical layer. - * \param exdc: `double` EXDC - * \param wp: `double` wp - * \param xip: `double` xip - */ - ScattererConfiguration( - int nsph, - double *scale_vector, - int nxi, - std::string variable_name, - int *iog_vector, - double *ros_vector, - int *nshl_vector, - double **rcf_vector, - int dielectric_func_type, - std::complex<double> ***dc_matrix, - bool has_external, - double exdc, - double wp, - double xip - ); + /*! \brief Build a scatterer configuration structure. + * + * Prepare a default configuration structure by allocating the necessary + * memory structures. + * + * \param nsph: `int` The number of spheres in the simulation. + * \param scale_vector: `double*` The radiation-particle scale vector. + * \param nxi: `int` The number of radiation-particle scalings. + * \param variable_name: `string` The name of the radiation-particle scaling type. + * \param iog_vector: `int*` Array of sphere identification numbers. QUESTION: correct? + * \param ros_vector: `double*` Sphere radius array. + * \param nshl_vector: `int*` Array of layer numbers. + * \param rcf_vector: `double**` Array of fractional break radii. QUESTION: correct? + * \param dielectric_func_type: `int` Type of dielectric function definition (=0 for constant, + * \>0 as function of scale parameter, <0 for functions at XIP value and XI is scale factor + * for dimensions). + * \param dc_matrix: Matrix of reference dielectric constants. + * \param has_external: `bool` Flag to set whether to add an external spherical layer. + * \param exdc: `double` EXDC + * \param wp: `double` wp + * \param xip: `double` xip + */ + ScattererConfiguration( + int nsph, + double *scale_vector, + int nxi, + std::string variable_name, + int *iog_vector, + double *ros_vector, + int *nshl_vector, + double **rcf_vector, + int dielectric_func_type, + std::complex<double> ***dc_matrix, + bool has_external, + double exdc, + double wp, + double xip + ); - /*! \brief Destroy a scatterer configuration instance. - */ - ~ScattererConfiguration(); + /*! \brief Destroy a scatterer configuration instance. + */ + ~ScattererConfiguration(); - /*! \brief Build configuration from binary configuration input file. - * - * The configuration step can save configuration data as a binary file. The original - * FORTRAN code used this possibility to manage communication between the configuring - * code and the calculation program. This possibility is maintained, in case the - * configuration step needs to be separated from the calculation execution. In this - * case, `from_binary()` is the class method that restores a ScattererConfiguration - * object from a previously saved binary file. - * - * \param file_name: `string` Name of the binary configuration data file. - * \param mode: `string` Binary encoding. Can be one of "LEGACY", ... . Optional - * (default is "LEGACY"). - * \return config: `ScattererConfiguration*` Pointer to object containing the - * scatterer configuration data. - */ - static ScattererConfiguration* from_binary(std::string file_name, std::string mode = "LEGACY"); + /*! \brief Build configuration from binary configuration input file. + * + * The configuration step can save configuration data as a binary file. The original + * FORTRAN code used this possibility to manage communication between the configuring + * code and the calculation program. This possibility is maintained, in case the + * configuration step needs to be separated from the calculation execution. In this + * case, `from_binary()` is the class method that restores a ScattererConfiguration + * object from a previously saved binary file. + * + * \param file_name: `string` Name of the binary configuration data file. + * \param mode: `string` Binary encoding. Can be one of "LEGACY", ... . Optional + * (default is "LEGACY"). + * \return config: `ScattererConfiguration*` Pointer to object containing the + * scatterer configuration data. + */ + static ScattererConfiguration* from_binary(std::string file_name, std::string mode = "LEGACY"); - /*! \brief Build scatterer configuration from legacy configuration input file. - * - * To allow for consistency tests and backward compatibility, ScattererConfiguration - * objects can be built from legacy configuration files. This function replicates - * the approach implemented by the FORTRAN EDFB code, but using a C++ oriented - * work-flow. - * - * \param file_name: `string` Name of the legacy configuration data file. - * \return config: `ScattererConfiguration*` Pointer to object containing the - * scatterer configuration data. - */ - static ScattererConfiguration* from_dedfb(std::string file_name); + /*! \brief Build scatterer configuration from legacy configuration input file. + * + * To allow for consistency tests and backward compatibility, ScattererConfiguration + * objects can be built from legacy configuration files. This function replicates + * the approach implemented by the FORTRAN EDFB code, but using a C++ oriented + * work-flow. + * + * \param file_name: `string` Name of the legacy configuration data file. + * \return config: `ScattererConfiguration*` Pointer to object containing the + * scatterer configuration data. + */ + static ScattererConfiguration* from_dedfb(std::string file_name); - /*! \brief Print the contents of the configuration object to terminal. - * - * In case of quick debug testing, `ScattererConfiguration.print()` allows printing - * a formatted summary of the configuration data to terminal. - */ - void print(); + /*! \brief Print the contents of the configuration object to terminal. + * + * In case of quick debug testing, `ScattererConfiguration.print()` allows printing + * a formatted summary of the configuration data to terminal. + */ + void print(); - /*! \brief Write the scatterer configuration data to binary output. - * - * The execution work-flow may be split in a configuration step and one or more - * calculation steps. In case the calculation is not being run all-in-one, it can - * be useful to save the configuration data. `ScattererConfiguration.write_binary()` - * performs the operation of saving the configuration in binary format. This function - * can work in legacy mode, to write backward compatible configuration files, as well - * as by wrapping the data into common scientific formats (NB: this last option still - * needs to be implemented). - * - * \param file_name: `string` Name of the file to be written. - * \param mode: `string` Binary encoding. Can be one of "LEGACY", ... . Optional - * (default is "LEGACY"). - */ - void write_binary(std::string file_name, std::string mode = "LEGACY"); + /*! \brief Write the scatterer configuration data to binary output. + * + * The execution work-flow may be split in a configuration step and one or more + * calculation steps. In case the calculation is not being run all-in-one, it can + * be useful to save the configuration data. `ScattererConfiguration.write_binary()` + * performs the operation of saving the configuration in binary format. This function + * can work in legacy mode, to write backward compatible configuration files, as well + * as by wrapping the data into common scientific formats (NB: this last option still + * needs to be implemented). + * + * \param file_name: `string` Name of the file to be written. + * \param mode: `string` Binary encoding. Can be one of "LEGACY", ... . Optional + * (default is "LEGACY"). + */ + void write_binary(std::string file_name, std::string mode = "LEGACY"); - /*! \brief Write the scatterer configuration data to formatted text output. - * - * Writing configuration to formatted text is an optional operation, which may turn - * out to be useful for consistency checks. As a matter of fact, formatted configuration - * output is not read back by the FORTRAN code work-flow and it can be safely omitted, - * unless there is a specific interest in assessing that the legacy code and the - * updated one are doing the same thing. - * - * \param file_name: `string` Name of the file to be written. - */ - void write_formatted(std::string file_name); + /*! \brief Write the scatterer configuration data to formatted text output. + * + * Writing configuration to formatted text is an optional operation, which may turn + * out to be useful for consistency checks. As a matter of fact, formatted configuration + * output is not read back by the FORTRAN code work-flow and it can be safely omitted, + * unless there is a specific interest in assessing that the legacy code and the + * updated one are doing the same thing. + * + * \param file_name: `string` Name of the file to be written. + */ + void write_formatted(std::string file_name); }; #endif diff --git a/src/include/clu_subs.h b/src/include/clu_subs.h index ab8fff17f926789b629f1bd82f06044e97532798..9e13b5267940c34b75059b578a497f93372b9408 100644 --- a/src/include/clu_subs.h +++ b/src/include/clu_subs.h @@ -27,36 +27,36 @@ extern double cg1(int lmpml, int mu, int l, int m); extern void dme( int li, int i, int npnt, int npntts, double vk, double exdc, double exri, C1 *c1, C2 *c2, int &jer, int &lcalc, std::complex<double> &arg -); + ); extern void rabas( - int inpol, int li, int nsph, C1 *c1, double **tqse, std::complex<double> **tqspe, - double **tqss, std::complex<double> **tqsps -); + int inpol, int li, int nsph, C1 *c1, double **tqse, std::complex<double> **tqspe, + double **tqss, std::complex<double> **tqsps + ); extern void rbf(int n, double x, int &nm, double sj[]); extern void rnf(int n, double x, int &nm, double sy[]); extern void mmulc(std::complex<double> *vint, double **cmullr, double **cmul); extern void sphar(double cth, double sth, double cph, double sph, int lm, std::complex<double> *ylm); extern void thdps(int lm, double ****zpv); extern void upvmp( - double thd, double phd, int icspnv, double &cost, double &sint, - double &cosp, double &sinp, double *u, double *up, double *un -); + double thd, double phd, int icspnv, double &cost, double &sint, + double &cosp, double &sinp, double *u, double *up, double *un + ); extern void upvsp( - double *u, double *upmp, double *unmp, double *us, double *upsmp, double *unsmp, - double *up, double *un, double *ups, double *uns, double *duk, int &isq, - int &ibf, double &scand, double &cfmp, double &sfmp, double &cfsp, double &sfsp -); + double *u, double *upmp, double *unmp, double *us, double *upsmp, double *unsmp, + double *up, double *un, double *ups, double *uns, double *duk, int &isq, + int &ibf, double &scand, double &cfmp, double &sfmp, double &cfsp, double &sfsp + ); extern void wmamp( - int iis, double cost, double sint, double cosp, double sinp, int inpol, - int lm, int idot, int nsph, double *arg, double *u, double *up, - double *un, C1 *c1 -); + int iis, double cost, double sint, double cosp, double sinp, int inpol, + int lm, int idot, int nsph, double *arg, double *u, double *up, + double *un, C1 *c1 + ); extern void wmasp( - double cost, double sint, double cosp, double sinp, double costs, double sints, - double cosps, double sinps, double *u, double *up, double *un, double *us, - double *ups, double *uns, int isq, int ibf, int inpol, int lm, int idot, - int nsph, double *argi, double *args, C1 *c1 -); + double cost, double sint, double cosp, double sinp, double costs, double sints, + double cosps, double sinps, double *u, double *up, double *un, double *us, + double *ups, double *uns, int isq, int ibf, int inpol, int lm, int idot, + int nsph, double *argi, double *args, C1 *c1 + ); // >>> END OF SPH_SUBS DECLARATION <<< /*! \brief C++ porting of CDTP @@ -69,21 +69,21 @@ extern void wmasp( * \param nj: `int` */ std::complex<double> cdtp( - std::complex<double> z, std::complex<double> **am, int i, int jf, - int k, int nj -) { - /* NOTE: the original FORTRAN code treats the AM matrix as a - * vector. This is not directly allowed in C++ and it requires - * accounting for the different dimensions. - */ - std::complex<double> result = z; - if (nj > 0) { - int jl = jf + nj - 1; - for (int j = jf; j <= jl; j++) { - result += (am[i - 1][j - 1] * am[j - 1][k - 1]); - } - } - return result; + std::complex<double> z, std::complex<double> **am, int i, int jf, + int k, int nj + ) { + /* NOTE: the original FORTRAN code treats the AM matrix as a + * vector. This is not directly allowed in C++ and it requires + * accounting for the different dimensions. + */ + std::complex<double> result = z; + if (nj > 0) { + int jl = jf + nj - 1; + for (int j = jf; j <= jl; j++) { + result += (am[i - 1][j - 1] * am[j - 1][k - 1]); + } + } + return result; } /*! \brief C++ porting of CGEV @@ -95,37 +95,37 @@ std::complex<double> cdtp( * \return result: `double` */ double cgev(int ipamo, int mu, int l, int m) { - double result = 0.0; - double xd = 0.0, xn = 0.0; - if (ipamo == 0) { - if (m != 0 || mu != 0) { // label 10 - if (mu != 0) { - xd = 2.0 * l * (l + 1); - if (mu <= 0) { - xn = 1.0 * (l + m) * (l - m + 1); - result = sqrt(xn / xd); - } else { // label 15 - xn = 1.0 * (l - m) * (l + m + 1); - result = -sqrt(xn / xd); - } - } else { // label 20 - xd = 1.0 * (l + 1) * l; - xn = -1.0 * m; - result = xn / sqrt(xd); - } - } - } else { // label 30 - xd = 2.0 * l * (l * 2 - 1); - if (mu < 0) { // label 35 - xn = 1.0 * (l - 1 + m) * (l + m); - } else if (mu == 0) { // label 40 - xn = 2.0 * (l - m) * (l + m); - } else { // mu > 0, label 45 - xn = 1.0 * (l - 1 - m) * (l - m); - } - result = sqrt(xn / xd); + double result = 0.0; + double xd = 0.0, xn = 0.0; + if (ipamo == 0) { + if (m != 0 || mu != 0) { // label 10 + if (mu != 0) { + xd = 2.0 * l * (l + 1); + if (mu <= 0) { + xn = 1.0 * (l + m) * (l - m + 1); + result = sqrt(xn / xd); + } else { // label 15 + xn = 1.0 * (l - m) * (l + m + 1); + result = -sqrt(xn / xd); } - return result; + } else { // label 20 + xd = 1.0 * (l + 1) * l; + xn = -1.0 * m; + result = xn / sqrt(xd); + } + } + } else { // label 30 + xd = 2.0 * l * (l * 2 - 1); + if (mu < 0) { // label 35 + xn = 1.0 * (l - 1 + m) * (l + m); + } else if (mu == 0) { // label 40 + xn = 2.0 * (l - m) * (l + m); + } else { // mu > 0, label 45 + xn = 1.0 * (l - 1 - m) * (l - m); + } + result = sqrt(xn / xd); + } + return result; } /*! \brief C++ porting of R3JJR @@ -137,123 +137,123 @@ double cgev(int ipamo, int mu, int l, int m) { * \param c6: `C6 *` */ void r3jjr(int j2, int j3, int m2, int m3, C6 *c6) { - int jmx = j3 + j2; - int jdf = j3 - j2; - int m1 = -m2 - m3; - int abs_jdf = (jdf >= 0) ? jdf : -jdf; - int abs_m1 = (m1 >= 0) ? m1 : -m1; - int jmn = (abs_jdf > abs_m1) ? abs_jdf : abs_m1; - int njmo = jmx - jmn; - int jf = jmx + jmx + 1; - int isn = 1; - if ((jdf + m1) % 2 != 0) isn = -1; - if (njmo <= 0) { - double sj = 1.0 * jf; - double cnr = (1.0 / sqrt(sj)) * isn; - c6->rac3j[0] = cnr; - } else { // label 15 - double sjt = 1.0; - double sjr = 1.0 * jf; - int jsmpos = (jmx + 1) * (jmx + 1); - int jdfs = jdf * jdf; - int m1s = m1 * m1; - int mdf = m3 - m2; - int idjc = m1 * (j3 * (j3 + 1) - j2 * (j2 +1)); - int j1 = jmx; - int j1s = j1 * j1; - int j1po = j1 + 1; - double ccj = 1.0 * (j1s - jdfs) * (j1s - m1s); - double cj = sqrt(ccj * (jsmpos - j1s)); - double dj = 1.0 * jf * (j1 * j1po * mdf + idjc); - // In old version, CJP was defined here. Did not work. - // double cjp = 0.0 - if (njmo <= 1) { - c6->rac3j[0] = -dj / (cj * j1po); - double sj = sjr + (c6->rac3j[0] * c6->rac3j[0]) * (jf - 2); - double cnr = (1.0 / sqrt(sj)) * isn; - c6->rac3j[1] = cnr; - c6->rac3j[0] *= cnr; - } else { // label 20 - double cjp = 0.0; - int nj = njmo + 1; - int nmat = (nj + 1) / 2; - c6->rac3j[nj - 1] = 1.0; - c6->rac3j[njmo - 1] = -dj / (cj * j1po); - if (nmat != njmo) { - int nbr = njmo - nmat; - for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { - int irr = nj - ibr45; - jf -= 2; - j1--; - j1s = j1 * j1; - j1po = j1 + 1; - cjp = cj; - ccj = 1.0 * (j1s - jdfs) * (j1s - m1s); - cj = sqrt(ccj * (jsmpos - j1s)); - sjt = c6->rac3j[irr - 1] * c6->rac3j[irr - 1]; - dj = 1.0 * jf * (j1 * j1po * mdf + idjc); - c6->rac3j[irr - 2] = -(c6->rac3j[irr - 1] * dj - + c6->rac3j[irr] * cjp * j1) / (cj * j1po); - sjr += (sjt * jf); - } // ibr45 loop - } - // label 50 - double osjt = sjt; - sjt = c6->rac3j[nmat - 1] * c6->rac3j[nmat - 1]; - if (sjt >= osjt) { - sjr += (sjt * (jf - 2)); - } else { // label 55 - nmat++; - } - // label 60 - double racmat = c6->rac3j[nmat - 1]; - c6->rac3j[0] = 1.0; - jf = jmn + jmn + 1; - double sjl = 1.0 * jf; - j1 = jmn; - if (j1 != 0) { - j1po = j1 + 1; - int j1pos = j1po * j1po; - double ccjp = 1.0 * (j1pos - jdfs) * (j1pos - m1s); - cjp = sqrt(ccjp * (jsmpos - j1pos)); - dj = 1.0 * jf * (j1 * j1po * mdf + idjc); - c6->rac3j[1] = - dj / (cjp * j1); - } else { // label 62 - cjp = sqrt(1.0 * (jsmpos - 1)); - dj = 1.0 * mdf; - c6->rac3j[1] = -dj / cjp; - } - // label 63 - int nmatmo = nmat - 1; - if (nmatmo >= 2) { - for (int irl70 = 2; irl70 <= nmatmo; irl70++) { - jf += 2; - j1++; - j1po = j1 + 1; - int j1pos = j1po * j1po; - cj = cjp; - double ccjp = 1.0 * (j1pos - jdfs) * (j1pos - m1s); - cjp = sqrt(ccjp * (jsmpos - j1pos)); - sjt = c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]; - dj = 1.0 * jf * (j1 * j1po * mdf + idjc); - c6->rac3j[irl70] = -( - c6->rac3j[irl70 - 1] * dj - + c6->rac3j[irl70 - 2] * cj * j1po - ) / (cjp * j1); - sjl += (sjt * jf); - } - } - // label 75 - double ratrac = racmat / c6->rac3j[nmat - 1]; - double rats = ratrac * ratrac; - double sj = sjr + sjl * rats; - c6->rac3j[nmat - 1] = racmat; - double cnr = (1.0 / sqrt(sj)) * isn; - for (int irr80 = nmat; irr80 <= nj; irr80++) c6->rac3j[irr80 - 1] *= cnr; - double cnl = cnr * ratrac; - for (int irl85 = 1; irl85 <= nmatmo; irl85++) c6->rac3j[irl85 - 1] *= cnl; - } + int jmx = j3 + j2; + int jdf = j3 - j2; + int m1 = -m2 - m3; + int abs_jdf = (jdf >= 0) ? jdf : -jdf; + int abs_m1 = (m1 >= 0) ? m1 : -m1; + int jmn = (abs_jdf > abs_m1) ? abs_jdf : abs_m1; + int njmo = jmx - jmn; + int jf = jmx + jmx + 1; + int isn = 1; + if ((jdf + m1) % 2 != 0) isn = -1; + if (njmo <= 0) { + double sj = 1.0 * jf; + double cnr = (1.0 / sqrt(sj)) * isn; + c6->rac3j[0] = cnr; + } else { // label 15 + double sjt = 1.0; + double sjr = 1.0 * jf; + int jsmpos = (jmx + 1) * (jmx + 1); + int jdfs = jdf * jdf; + int m1s = m1 * m1; + int mdf = m3 - m2; + int idjc = m1 * (j3 * (j3 + 1) - j2 * (j2 +1)); + int j1 = jmx; + int j1s = j1 * j1; + int j1po = j1 + 1; + double ccj = 1.0 * (j1s - jdfs) * (j1s - m1s); + double cj = sqrt(ccj * (jsmpos - j1s)); + double dj = 1.0 * jf * (j1 * j1po * mdf + idjc); + // In old version, CJP was defined here. Did not work. + // double cjp = 0.0 + if (njmo <= 1) { + c6->rac3j[0] = -dj / (cj * j1po); + double sj = sjr + (c6->rac3j[0] * c6->rac3j[0]) * (jf - 2); + double cnr = (1.0 / sqrt(sj)) * isn; + c6->rac3j[1] = cnr; + c6->rac3j[0] *= cnr; + } else { // label 20 + double cjp = 0.0; + int nj = njmo + 1; + int nmat = (nj + 1) / 2; + c6->rac3j[nj - 1] = 1.0; + c6->rac3j[njmo - 1] = -dj / (cj * j1po); + if (nmat != njmo) { + int nbr = njmo - nmat; + for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { + int irr = nj - ibr45; + jf -= 2; + j1--; + j1s = j1 * j1; + j1po = j1 + 1; + cjp = cj; + ccj = 1.0 * (j1s - jdfs) * (j1s - m1s); + cj = sqrt(ccj * (jsmpos - j1s)); + sjt = c6->rac3j[irr - 1] * c6->rac3j[irr - 1]; + dj = 1.0 * jf * (j1 * j1po * mdf + idjc); + c6->rac3j[irr - 2] = -(c6->rac3j[irr - 1] * dj + + c6->rac3j[irr] * cjp * j1) / (cj * j1po); + sjr += (sjt * jf); + } // ibr45 loop + } + // label 50 + double osjt = sjt; + sjt = c6->rac3j[nmat - 1] * c6->rac3j[nmat - 1]; + if (sjt >= osjt) { + sjr += (sjt * (jf - 2)); + } else { // label 55 + nmat++; + } + // label 60 + double racmat = c6->rac3j[nmat - 1]; + c6->rac3j[0] = 1.0; + jf = jmn + jmn + 1; + double sjl = 1.0 * jf; + j1 = jmn; + if (j1 != 0) { + j1po = j1 + 1; + int j1pos = j1po * j1po; + double ccjp = 1.0 * (j1pos - jdfs) * (j1pos - m1s); + cjp = sqrt(ccjp * (jsmpos - j1pos)); + dj = 1.0 * jf * (j1 * j1po * mdf + idjc); + c6->rac3j[1] = - dj / (cjp * j1); + } else { // label 62 + cjp = sqrt(1.0 * (jsmpos - 1)); + dj = 1.0 * mdf; + c6->rac3j[1] = -dj / cjp; + } + // label 63 + int nmatmo = nmat - 1; + if (nmatmo >= 2) { + for (int irl70 = 2; irl70 <= nmatmo; irl70++) { + jf += 2; + j1++; + j1po = j1 + 1; + int j1pos = j1po * j1po; + cj = cjp; + double ccjp = 1.0 * (j1pos - jdfs) * (j1pos - m1s); + cjp = sqrt(ccjp * (jsmpos - j1pos)); + sjt = c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]; + dj = 1.0 * jf * (j1 * j1po * mdf + idjc); + c6->rac3j[irl70] = -( + c6->rac3j[irl70 - 1] * dj + + c6->rac3j[irl70 - 2] * cj * j1po + ) / (cjp * j1); + sjl += (sjt * jf); } + } + // label 75 + double ratrac = racmat / c6->rac3j[nmat - 1]; + double rats = ratrac * ratrac; + double sj = sjr + sjl * rats; + c6->rac3j[nmat - 1] = racmat; + double cnr = (1.0 / sqrt(sj)) * isn; + for (int irr80 = nmat; irr80 <= nj; irr80++) c6->rac3j[irr80 - 1] *= cnr; + double cnl = cnr * ratrac; + for (int irl85 = 1; irl85 <= nmatmo; irl85++) c6->rac3j[irl85 - 1] *= cnl; + } + } } /*! \brief C++ porting of R3JMR @@ -265,98 +265,98 @@ void r3jjr(int j2, int j3, int m2, int m3, C6 *c6) { * \param c6: `C6 *` */ void r3jmr(int j1, int j2, int j3, int m1, C6 *c6) { - int mmx = (j2 < j3 - m1) ? j2 : j3 - m1; - int mmn = (-j2 > -(j3 + m1)) ? -j2 : -(j3 + m1); - int nmmo = mmx - mmn; - int j1po = j1 + 1; - int j1tpo = j1po + j1; - int isn = 1; - if ((j2 - j3 - m1) % 2 != 0) isn = -1; - if (nmmo <= 0) { - double sj = 1.0 * j1tpo; - double cnr = (1.0 / sqrt(sj)) * isn; - c6->rac3j[0] = cnr; - // returns - } else { // label 15 - int j1s = j1 * j1po; - int j2po = j2 + 1; - int j2s = j2 * j2po; - int j3po = j3 + 1; - int j3s = j3 * j3po; - int id = j1s - j2s - j3s; - int m2 = mmx; - int m3 = m1 + m2; - double cm = sqrt(1.0 * (j2po - m2) * (j2 + m2) * (j3po - m3) * (j3 + m3)); - double dm = 1.0 * (id + m2 * m3 * 2); - if (nmmo <= 1) { - c6->rac3j[0] = dm / cm; - double sj = (1.0 + c6->rac3j[0] * c6->rac3j[0]) * j1tpo; - double cnr = 1.0 / sqrt(sj) * isn; - c6->rac3j[1] = cnr; - c6->rac3j[0] *= cnr; - // returns - } else { // label 20 - int nm = nmmo + 1; - int nmat = (nm + 1) / 2; - c6->rac3j[nm - 1] = 1.0; - c6->rac3j[nmmo - 1] = dm / cm; - double sjt = 1.0; - double sjr = 1.0; - if (nmat != nmmo) { - int nbr = nmmo - nmat; - for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { - int irr = nm - ibr45; - m2--; - m3 = m1 + m2; - double cmp = cm; - cm = sqrt(1.0 * (j2po - m2) * (j2 + m2) * (j3po - m3) * (j3 + m3)); - sjt = c6->rac3j[irr - 1] * c6->rac3j[irr - 1]; - dm = 1.0 * (id + m2 * m3 * 2); - c6->rac3j[irr - 1] *= ((dm - c6->rac3j[irr] * cmp) / cm); - sjr += sjt; - } // ibr45 loop - } - // label 50 - double osjt = sjt; - sjt = c6->rac3j[nmat - 1] * c6->rac3j[nmat - 1]; - if (sjt >= osjt) { - sjr += sjt; - } else { // label 55 - nmat++; - } - // label 60 - double racmat = c6->rac3j[nmat - 1]; - c6->rac3j[0] = 1.0; - m2 = mmn; - m3 = m1 + m2; - double cmp = sqrt(1.0 * (j2 - m2) * (j2po + m2) * (j3 - m3) * (j3po + m3)); - dm = 1.0 * (id + m2 * m3 * 2); - c6->rac3j[1] = dm / cmp; - double sjl = 1.0; - int nmatmo = nmat - 1; - if (nmatmo > 1) { - for (int irl70 = 2; irl70 <= nmatmo; irl70++) { - m2++; - m3 = m1 + m2; - cm = cmp; - cmp = sqrt(1.0 * (j2 - m2) * (j2po + m2) * (j3 - m3) * (j3po + m3)); - sjt = c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]; - dm = 1.0 * (id + m2 * m3 * 2); - c6->rac3j[irl70] = (c6->rac3j[irl70 - 1] * dm - c6->rac3j[irl70 - 2] * cm) / cmp; - sjl += sjt; - } - }// label 75 - double ratrac = racmat / c6->rac3j[nmat - 1]; - double rats = ratrac * ratrac; - double sj = (sjr + sjl * rats) * j1tpo; - c6->rac3j[nmat - 1] = racmat; - double cnr = 1.0 / sqrt(sj) * isn; - for (int irr80 = nmat; irr80 <= nm; irr80++) c6->rac3j[irr80 - 1] *= cnr; - double cnl = cnr * ratrac; - for (int irl85 = 1; irl85 <= nmatmo; irl85++) c6->rac3j[irl85 - 1] *= cnl; - // returns - } + int mmx = (j2 < j3 - m1) ? j2 : j3 - m1; + int mmn = (-j2 > -(j3 + m1)) ? -j2 : -(j3 + m1); + int nmmo = mmx - mmn; + int j1po = j1 + 1; + int j1tpo = j1po + j1; + int isn = 1; + if ((j2 - j3 - m1) % 2 != 0) isn = -1; + if (nmmo <= 0) { + double sj = 1.0 * j1tpo; + double cnr = (1.0 / sqrt(sj)) * isn; + c6->rac3j[0] = cnr; + // returns + } else { // label 15 + int j1s = j1 * j1po; + int j2po = j2 + 1; + int j2s = j2 * j2po; + int j3po = j3 + 1; + int j3s = j3 * j3po; + int id = j1s - j2s - j3s; + int m2 = mmx; + int m3 = m1 + m2; + double cm = sqrt(1.0 * (j2po - m2) * (j2 + m2) * (j3po - m3) * (j3 + m3)); + double dm = 1.0 * (id + m2 * m3 * 2); + if (nmmo <= 1) { + c6->rac3j[0] = dm / cm; + double sj = (1.0 + c6->rac3j[0] * c6->rac3j[0]) * j1tpo; + double cnr = 1.0 / sqrt(sj) * isn; + c6->rac3j[1] = cnr; + c6->rac3j[0] *= cnr; + // returns + } else { // label 20 + int nm = nmmo + 1; + int nmat = (nm + 1) / 2; + c6->rac3j[nm - 1] = 1.0; + c6->rac3j[nmmo - 1] = dm / cm; + double sjt = 1.0; + double sjr = 1.0; + if (nmat != nmmo) { + int nbr = nmmo - nmat; + for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { + int irr = nm - ibr45; + m2--; + m3 = m1 + m2; + double cmp = cm; + cm = sqrt(1.0 * (j2po - m2) * (j2 + m2) * (j3po - m3) * (j3 + m3)); + sjt = c6->rac3j[irr - 1] * c6->rac3j[irr - 1]; + dm = 1.0 * (id + m2 * m3 * 2); + c6->rac3j[irr - 1] *= ((dm - c6->rac3j[irr] * cmp) / cm); + sjr += sjt; + } // ibr45 loop + } + // label 50 + double osjt = sjt; + sjt = c6->rac3j[nmat - 1] * c6->rac3j[nmat - 1]; + if (sjt >= osjt) { + sjr += sjt; + } else { // label 55 + nmat++; + } + // label 60 + double racmat = c6->rac3j[nmat - 1]; + c6->rac3j[0] = 1.0; + m2 = mmn; + m3 = m1 + m2; + double cmp = sqrt(1.0 * (j2 - m2) * (j2po + m2) * (j3 - m3) * (j3po + m3)); + dm = 1.0 * (id + m2 * m3 * 2); + c6->rac3j[1] = dm / cmp; + double sjl = 1.0; + int nmatmo = nmat - 1; + if (nmatmo > 1) { + for (int irl70 = 2; irl70 <= nmatmo; irl70++) { + m2++; + m3 = m1 + m2; + cm = cmp; + cmp = sqrt(1.0 * (j2 - m2) * (j2po + m2) * (j3 - m3) * (j3po + m3)); + sjt = c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]; + dm = 1.0 * (id + m2 * m3 * 2); + c6->rac3j[irl70] = (c6->rac3j[irl70 - 1] * dm - c6->rac3j[irl70 - 2] * cm) / cmp; + sjl += sjt; } + }// label 75 + double ratrac = racmat / c6->rac3j[nmat - 1]; + double rats = ratrac * ratrac; + double sj = (sjr + sjl * rats) * j1tpo; + c6->rac3j[nmat - 1] = racmat; + double cnr = 1.0 / sqrt(sj) * isn; + for (int irr80 = nmat; irr80 <= nm; irr80++) c6->rac3j[irr80 - 1] *= cnr; + double cnl = cnr * ratrac; + for (int irl85 = 1; irl85 <= nmatmo; irl85++) c6->rac3j[irl85 - 1] *= cnl; + // returns + } + } } /*! \brief C++ porting of GHIT @@ -374,216 +374,216 @@ void r3jmr(int j1, int j2, int j3, int m1, C6 *c6) { * \param c6: `C6 *` */ std::complex<double> ghit( - int ihi, int ipamo, int nbl, int l1, int m1, int l2, int m2, C1 *c1, - C1_AddOns *c1ao, C4 *c4, C6 *c6 -) { - /* NBL identifies transfer vector going from N2 to N1; - * IHI=0 for Hankel, IHI=1 for Bessel, IHI=2 for Bessel from origin; - * depending on IHI, IPAM=0 gives H or I, IPAM= 1 gives K or L. */ - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - std::complex<double> csum(0.0, 0.0), cfun(0.0, 0.0); - std::complex<double> result = cc0; + int ihi, int ipamo, int nbl, int l1, int m1, int l2, int m2, C1 *c1, + C1_AddOns *c1ao, C4 *c4, C6 *c6 + ) { + /* NBL identifies transfer vector going from N2 to N1; + * IHI=0 for Hankel, IHI=1 for Bessel, IHI=2 for Bessel from origin; + * depending on IHI, IPAM=0 gives H or I, IPAM= 1 gives K or L. */ + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + std::complex<double> csum(0.0, 0.0), cfun(0.0, 0.0); + std::complex<double> result = cc0; - if (ihi == 2) { - if (c1->rxx[nbl - 1] == 0.0 && c1->ryy[nbl - 1] == 0.0 && c1->rzz[nbl - 1] == 0.0) { - if (ipamo == 0) { - if (l1 == l2 && m1 == m2) result = std::complex(1.0, 0.0); - } - return result; - } + if (ihi == 2) { + if (c1->rxx[nbl - 1] == 0.0 && c1->ryy[nbl - 1] == 0.0 && c1->rzz[nbl - 1] == 0.0) { + if (ipamo == 0) { + if (l1 == l2 && m1 == m2) result = std::complex(1.0, 0.0); + } + return result; + } + } + // label 10 + int l1mp = l1 - ipamo; + int l1po = l1 + 1; + int m1mm2 = m1 - m2; + int m1mm2m = (m1mm2 > 0) ? m1mm2 + 1 : 1 - m1mm2; + int lminpo = (l2 - l1mp > 0) ? l2 - l1mp + 1 : l1mp - l2 + 1; + int lmaxpo = l2 + l1mp + 1; + int i3j0in = c1ao->ind3j[l1mp][l2 - 1]; + int ilin = -1; + if (m1mm2m > lminpo && (m1mm2m - lminpo) % 2 != 0) ilin = 0; + int isn = 1; + if (m1 % 2 != 0) isn *= -1; + if (lminpo % 2 == 0) { + isn *= -1; + if (l2 > l1mp) isn *= -1; + } + // label 12 + int nblmo = nbl - 1; + if (ihi != 2) { + int nbhj = nblmo * c4->litpo; + int nby = nblmo * c4->litpos; + if (ihi != 1) { + for (int jm24 = 1; jm24 <= 3; jm24++) { + csum = cc0; + int mu = jm24 - 2; + int mupm1 = mu + m1; + int mupm2 = mu + m2; + if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { + int jsn = -isn; + if (mu == 0) jsn = isn; + double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); + int i3j0 = i3j0in; + if (mupm1 == 0 && mupm2 == 0) { + int lt14 = lminpo; + while (lt14 <= lmaxpo) { + i3j0++; + int l3 = lt14 - 1; + int ny = l3 * l3 + lt14; + double aors = 1.0 * (l3 + lt14); + double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + cfun = (c1ao->vh[nbhj + lt14 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; + csum += cfun; + jsn *= -1; + lt14 += 2; + } + // goes to 22 + } else { // label 16 + r3jjr(l1mp, l2, -mupm1, mupm2, c6); + int il = ilin; + int lt20 = lminpo; + while (lt20 <= lmaxpo) { + i3j0++; + if (m1mm2m <= lt20) { + il += 2; + int l3 = lt20 - 1; + int ny = l3 * l3 + lt20 + m1mm2; + double aors = 1.0 * (l3 + lt20); + double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + //printf("DEBUG: VH( %d ) = (%lE, %lE)\n", (nbhj + lt20), c1ao->vh[nbhj + lt20 - 1].real(), c1ao->vh[nbhj + lt20 - 1].imag()); + //printf("DEBUG: VYHJ( %d ) = (%lE, %lE)\n", (nby + ny), c1ao->vyhj[nby + ny - 1].real(), c1ao->vyhj[nby + ny - 1].imag()); + cfun = (c1ao->vh[nbhj + lt20 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; + csum += cfun; // we were here + } + // label 20 + jsn *= -1; + lt20 += 2; + } + } + // label 22 + csum *= cr; + result += csum; } - // label 10 - int l1mp = l1 - ipamo; - int l1po = l1 + 1; - int m1mm2 = m1 - m2; - int m1mm2m = (m1mm2 > 0) ? m1mm2 + 1 : 1 - m1mm2; - int lminpo = (l2 - l1mp > 0) ? l2 - l1mp + 1 : l1mp - l2 + 1; - int lmaxpo = l2 + l1mp + 1; - int i3j0in = c1ao->ind3j[l1mp][l2 - 1]; - int ilin = -1; - if (m1mm2m > lminpo && (m1mm2m - lminpo) % 2 != 0) ilin = 0; - int isn = 1; - if (m1 % 2 != 0) isn *= -1; - if (lminpo % 2 == 0) { - isn *= -1; - if (l2 > l1mp) isn *= -1; + // Otherwise there is nothing to add + } // jm24 loop. Should go to 70 + } else { // label 30, IHI == 1 + for (int jm44 = 1; jm44 <= 3; jm44++) { + csum = cc0; + int mu = jm44 - 2; + int mupm1 = mu + m1; + int mupm2 = mu + m2; + if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { + int jsn = - isn; + if (mu == 0) jsn = isn; + double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); + int i3j0 = i3j0in; + if (mupm1 == 0 && mupm2 == 0) { + int lt34 = lminpo; + while (lt34 <= lmaxpo) { + i3j0++; + int l3 = lt34 - 1; + int ny = l3 * l3 + lt34; + double aors = 1.0 * (l3 + lt34); + double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + cfun = (c1ao->vh[nbhj + lt34 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; + csum += cfun; + jsn *= -1; + lt34 += 2; + } + // goes to 42 + } else { // label 36 + r3jjr(l1mp, l2, -mupm1, mupm2, c6); + int il = ilin; + int lt40 = lminpo; + while (lt40 <= lmaxpo) { + i3j0++; + if (m1mm2m <= lt40) { + il += 2; + int l3 = lt40 - 1; + int ny = l3 * l3 + lt40 + m1mm2; + double aors = 1.0 * (l3 + lt40); + double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + cfun = (c1ao->vh[nbhj + lt40 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; + csum += cfun; + } + // label 40 + jsn *= -1; + lt40 += 2; + } + } + // label 42 + csum *= cr; + result += csum; } - // label 12 - int nblmo = nbl - 1; - if (ihi != 2) { - int nbhj = nblmo * c4->litpo; - int nby = nblmo * c4->litpos; - if (ihi != 1) { - for (int jm24 = 1; jm24 <= 3; jm24++) { - csum = cc0; - int mu = jm24 - 2; - int mupm1 = mu + m1; - int mupm2 = mu + m2; - if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { - int jsn = -isn; - if (mu == 0) jsn = isn; - double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); - int i3j0 = i3j0in; - if (mupm1 == 0 && mupm2 == 0) { - int lt14 = lminpo; - while (lt14 <= lmaxpo) { - i3j0++; - int l3 = lt14 - 1; - int ny = l3 * l3 + lt14; - double aors = 1.0 * (l3 + lt14); - double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - cfun = (c1ao->vh[nbhj + lt14 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; - csum += cfun; - jsn *= -1; - lt14 += 2; - } - // goes to 22 - } else { // label 16 - r3jjr(l1mp, l2, -mupm1, mupm2, c6); - int il = ilin; - int lt20 = lminpo; - while (lt20 <= lmaxpo) { - i3j0++; - if (m1mm2m <= lt20) { - il += 2; - int l3 = lt20 - 1; - int ny = l3 * l3 + lt20 + m1mm2; - double aors = 1.0 * (l3 + lt20); - double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - //printf("DEBUG: VH( %d ) = (%lE, %lE)\n", (nbhj + lt20), c1ao->vh[nbhj + lt20 - 1].real(), c1ao->vh[nbhj + lt20 - 1].imag()); - //printf("DEBUG: VYHJ( %d ) = (%lE, %lE)\n", (nby + ny), c1ao->vyhj[nby + ny - 1].real(), c1ao->vyhj[nby + ny - 1].imag()); - cfun = (c1ao->vh[nbhj + lt20 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; - csum += cfun; // we were here - } - // label 20 - jsn *= -1; - lt20 += 2; - } - } - // label 22 - csum *= cr; - result += csum; - } - // Otherwise there is nothing to add - } // jm24 loop. Should go to 70 - } else { // label 30, IHI == 1 - for (int jm44 = 1; jm44 <= 3; jm44++) { - csum = cc0; - int mu = jm44 - 2; - int mupm1 = mu + m1; - int mupm2 = mu + m2; - if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { - int jsn = - isn; - if (mu == 0) jsn = isn; - double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); - int i3j0 = i3j0in; - if (mupm1 == 0 && mupm2 == 0) { - int lt34 = lminpo; - while (lt34 <= lmaxpo) { - i3j0++; - int l3 = lt34 - 1; - int ny = l3 * l3 + lt34; - double aors = 1.0 * (l3 + lt34); - double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - cfun = (c1ao->vh[nbhj + lt34 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; - csum += cfun; - jsn *= -1; - lt34 += 2; - } - // goes to 42 - } else { // label 36 - r3jjr(l1mp, l2, -mupm1, mupm2, c6); - int il = ilin; - int lt40 = lminpo; - while (lt40 <= lmaxpo) { - i3j0++; - if (m1mm2m <= lt40) { - il += 2; - int l3 = lt40 - 1; - int ny = l3 * l3 + lt40 + m1mm2; - double aors = 1.0 * (l3 + lt40); - double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - cfun = (c1ao->vh[nbhj + lt40 - 1] * c1ao->vyhj[nby + ny - 1]) * f3j; - csum += cfun; - } - // label 40 - jsn *= -1; - lt40 += 2; - } - } - // label 42 - csum *= cr; - result += csum; - } - // Otherwise there is nothing to add - } // jm44 loop. Should go to 70 - } - // goes to 70 - } else { // label 50, IHI == 2 - int nbhj = nblmo * c4->lmtpo; - int nby = nblmo * c4->lmtpos; - for (int jm64 = 1; jm64 <= 3; jm64++) { - csum = cc0; - int mu = jm64 - 2; - int mupm1 = mu + m1; - int mupm2 = mu + m2; - if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { - int jsn = -isn; - if (mu == 0) jsn = isn; - double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); - int i3j0 = i3j0in; - if (mupm1 == 0 && mupm2 == 0) { - int lt54 = lminpo; - while (lt54 <= lmaxpo) { - i3j0++; - int l3 = lt54 - 1; - int ny = l3 * l3 + lt54; - double aors = 1.0 * (l3 + lt54); - double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - cfun = (c1ao->vj0[nbhj + lt54 - 1] * c1ao->vyj0[nby + ny - 1]) * f3j; - csum += cfun; - jsn *= -1; - lt54 += 2; - } - // goes to 62 - } else { // label 56 - r3jjr(l1mp, l2, -mupm1, mupm2, c6); - int il = ilin; - int lt60 = lminpo; - while (lt60 <= lmaxpo) { - i3j0++; - if (m1mm2m <= lt60) { - il += 2; - int l3 = lt60 - 1; - int ny = l3 * l3 + lt60 + m1mm2; - double aors = 1.0 * (l3 + lt60); - double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; - cfun = (c1ao->vj0[nbhj + lt60 - 1] * c1ao->vyj0[nby + ny - 1]) * f3j; - csum += cfun; - } - // label 60 - jsn *= -1; - lt60 += 2; - } - } - // label 62 - csum *= cr; - result += csum; - } - // Otherwise there is nothing to add - } // jm64 loop. Should go to 70 + // Otherwise there is nothing to add + } // jm44 loop. Should go to 70 + } + // goes to 70 + } else { // label 50, IHI == 2 + int nbhj = nblmo * c4->lmtpo; + int nby = nblmo * c4->lmtpos; + for (int jm64 = 1; jm64 <= 3; jm64++) { + csum = cc0; + int mu = jm64 - 2; + int mupm1 = mu + m1; + int mupm2 = mu + m2; + if (mupm1 >= -l1mp && mupm1 <= l1mp && mupm2 >= - l2 && mupm2 <= l2) { + int jsn = -isn; + if (mu == 0) jsn = isn; + double cr = cgev(ipamo, mu, l1, m1) * cgev(0, mu, l2, m2); + int i3j0 = i3j0in; + if (mupm1 == 0 && mupm2 == 0) { + int lt54 = lminpo; + while (lt54 <= lmaxpo) { + i3j0++; + int l3 = lt54 - 1; + int ny = l3 * l3 + lt54; + double aors = 1.0 * (l3 + lt54); + double f3j = (c1ao->v3j0[i3j0 - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + cfun = (c1ao->vj0[nbhj + lt54 - 1] * c1ao->vyj0[nby + ny - 1]) * f3j; + csum += cfun; + jsn *= -1; + lt54 += 2; + } + // goes to 62 + } else { // label 56 + r3jjr(l1mp, l2, -mupm1, mupm2, c6); + int il = ilin; + int lt60 = lminpo; + while (lt60 <= lmaxpo) { + i3j0++; + if (m1mm2m <= lt60) { + il += 2; + int l3 = lt60 - 1; + int ny = l3 * l3 + lt60 + m1mm2; + double aors = 1.0 * (l3 + lt60); + double f3j = (c6->rac3j[il - 1] * c1ao->v3j0[i3j0 - 1] * sqrt(aors)) * jsn; + cfun = (c1ao->vj0[nbhj + lt60 - 1] * c1ao->vyj0[nby + ny - 1]) * f3j; + csum += cfun; + } + // label 60 + jsn *= -1; + lt60 += 2; + } } - // label 70 - const double four_pi = acos(0.0) * 8.0; - if (ipamo != 1) { - double cr = sqrt(four_pi * (l1 + l1po) * (l2 + l2 + 1)); - result *= cr; - } else { - double cr = sqrt(four_pi * (l1 + l1mp) * (l1 + l1po) * (l2 + l2 + 1) / l1po); - result *= (cr * uim); - } - return result; + // label 62 + csum *= cr; + result += csum; + } + // Otherwise there is nothing to add + } // jm64 loop. Should go to 70 + } + // label 70 + const double four_pi = acos(0.0) * 8.0; + if (ipamo != 1) { + double cr = sqrt(four_pi * (l1 + l1po) * (l2 + l2 + 1)); + result *= cr; + } else { + double cr = sqrt(four_pi * (l1 + l1mp) * (l1 + l1po) * (l2 + l2 + 1) / l1po); + result *= (cr * uim); + } + return result; } /*! \brief C++ porting of APC @@ -597,123 +597,123 @@ std::complex<double> ghit( * \param gapp: Matrix of complex. */ void apc( - double ****zpv, int le, std::complex<double> **am0m, std::complex<double> **w, - double sqk, double **gapr, std::complex<double> **gapp -) { - std::complex<double> **ac, **gap; - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - std::complex<double> uimmp, summ, sume, suem, suee, summp, sumep; - std::complex<double> suemp, sueep; - double cof = 1.0 / sqk; - double cimu = cof / sqrt(2.0); - int nlem = le * (le + 2); - const int nlemt = nlem + nlem; - ac = new std::complex<double>*[nlemt]; - gap = new std::complex<double>*[3]; - for (int ai = 0; ai < nlemt; ai++) ac[ai] = new std::complex<double>[2](); - for (int gi = 0; gi < 3; gi++) gap[gi] = new std::complex<double>[2](); - for (int j45 = 1; j45 <= nlemt; j45++) { - int j = j45 - 1; - ac[j][0] = cc0; - ac[j][1] = cc0; - for (int i45 = 1; i45 <= nlemt; i45++) { - int i = i45 - 1; - ac[j][0] += (am0m[j][i] * w[i][0]); - ac[j][1] += (am0m[j][i] * w[i][1]); - } //i45 loop - } //j45 loop - for (int imu90 = 1; imu90 <=3; imu90++) { - int mu = imu90 - 2; - gap[imu90 - 1][0] = cc0; - gap[imu90 - 1][1] = cc0; - gapp[imu90 - 1][0] = cc0; - gapp[imu90 - 1][1] = cc0; - for (int l80 =1; l80 <= le; l80++) { - int lpo = l80 + 1; - int ltpo = lpo + l80; - int imm = l80 * lpo; - for (int ilmp = 1; ilmp <= 3; ilmp++) { - if ((l80 == 1 && ilmp == 1) || (l80 == le && ilmp == 3)) continue; // ilmp loop - int lmpml = ilmp - 2; - int lmp = l80 + lmpml; - uimmp = (-1.0 * lmpml) * uim; - int impmmmp = lmp * (lmp + 1); - for (int im70 = 1; im70 <= ltpo; im70++) { - int m = im70 - lpo; - int mmp = m - mu; - int abs_mmp = (mmp > 0) ? mmp : -mmp; - if (abs_mmp <= lmp) { - int i = imm + m; - int ie = i + nlem; - int imp = impmmmp + mmp; - int impe = imp + nlem; - double cgc = cg1(lmpml, mu, l80, m); - int jpo = 2; - for (int ipo = 1; ipo <= 2; ipo++) { - if (ipo == 2) jpo = 1; - //printf("DEBUG: i=%d, ipo=%d, imp=%d\n", i, ipo, imp); - //fflush(stdout); - summ = dconjg(ac[i - 1][ipo - 1]) * ac[imp - 1][ipo - 1]; - sume = dconjg(ac[i - 1][ipo - 1]) * ac[impe - 1][ipo - 1]; - suem = dconjg(ac[ie - 1][ipo - 1]) * ac[imp - 1][ipo - 1]; - suee = dconjg(ac[ie - 1][ipo - 1]) * ac[impe - 1][ipo - 1]; - summp = dconjg(ac[i - 1][jpo - 1]) * ac[imp - 1][ipo - 1]; - sumep = dconjg(ac[i - 1][jpo - 1]) * ac[impe - 1][ipo - 1]; - suemp = dconjg(ac[ie - 1][jpo - 1]) * ac[imp - 1][ipo - 1]; - sueep = dconjg(ac[ie - 1][jpo - 1]) * ac[impe - 1][ipo - 1]; - if (lmpml != 0) { - summ *= uimmp; - sume *= uimmp; - suem *= uimmp; - suee *= uimmp; - summp *= uimmp; - sumep *= uimmp; - suemp *= uimmp; - sueep *= uimmp; - } - // label 55 - gap[imu90 - 1][ipo - 1] += ( - ( - summ * zpv[l80 - 1][ilmp - 1][0][0] - + sume * zpv[l80 - 1][ilmp - 1][0][1] - + suem * zpv[l80 - 1][ilmp - 1][1][0] - + suee * zpv[l80 - 1][ilmp - 1][1][1] - ) * cgc - ); - gapp[imu90 - 1][ipo - 1] += ( - ( - summp * zpv[l80 - 1][ilmp - 1][0][0] - + sumep * zpv[l80 - 1][ilmp - 1][0][1] - + suemp * zpv[l80 - 1][ilmp - 1][1][0] - + sueep * zpv[l80 - 1][ilmp - 1][1][1] - ) * cgc - ); - } // ipo loop - } // ends im70 loop - } // im70 loop - } // ilmp loop - } // l80 loop - } // imu90 loop - for (int ipo95 = 1; ipo95 <= 2; ipo95++) { - sume = gap[0][ipo95 - 1] * cimu; - suee = gap[1][ipo95 - 1] * cof; - suem = gap[2][ipo95 - 1] * cimu; - gapr[0][ipo95 - 1] = (sume - suem).real(); - gapr[1][ipo95 - 1] = ((sume + suem) * uim).real(); - gapr[2][ipo95 - 1] = suee.real(); - sumep = gapp[0][ipo95 - 1] * cimu; - sueep = gapp[1][ipo95 - 1] * cof; - suemp = gapp[2][ipo95 - 1] * cimu; - gapp[0][ipo95 - 1] = sumep - suemp; - gapp[1][ipo95 - 1] = (sumep + suemp) * uim; - gapp[2][ipo95 - 1] = sueep; - } // ipo95 loop - // Clean memory - for (int ai = nlemt - 1; ai > -1; ai--) delete[] ac[ai]; - for (int gi = 2; gi > -1; gi--) delete[] gap[gi]; - delete[] ac; - delete[] gap; + double ****zpv, int le, std::complex<double> **am0m, std::complex<double> **w, + double sqk, double **gapr, std::complex<double> **gapp + ) { + std::complex<double> **ac, **gap; + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + std::complex<double> uimmp, summ, sume, suem, suee, summp, sumep; + std::complex<double> suemp, sueep; + double cof = 1.0 / sqk; + double cimu = cof / sqrt(2.0); + int nlem = le * (le + 2); + const int nlemt = nlem + nlem; + ac = new std::complex<double>*[nlemt]; + gap = new std::complex<double>*[3]; + for (int ai = 0; ai < nlemt; ai++) ac[ai] = new std::complex<double>[2](); + for (int gi = 0; gi < 3; gi++) gap[gi] = new std::complex<double>[2](); + for (int j45 = 1; j45 <= nlemt; j45++) { + int j = j45 - 1; + ac[j][0] = cc0; + ac[j][1] = cc0; + for (int i45 = 1; i45 <= nlemt; i45++) { + int i = i45 - 1; + ac[j][0] += (am0m[j][i] * w[i][0]); + ac[j][1] += (am0m[j][i] * w[i][1]); + } //i45 loop + } //j45 loop + for (int imu90 = 1; imu90 <=3; imu90++) { + int mu = imu90 - 2; + gap[imu90 - 1][0] = cc0; + gap[imu90 - 1][1] = cc0; + gapp[imu90 - 1][0] = cc0; + gapp[imu90 - 1][1] = cc0; + for (int l80 =1; l80 <= le; l80++) { + int lpo = l80 + 1; + int ltpo = lpo + l80; + int imm = l80 * lpo; + for (int ilmp = 1; ilmp <= 3; ilmp++) { + if ((l80 == 1 && ilmp == 1) || (l80 == le && ilmp == 3)) continue; // ilmp loop + int lmpml = ilmp - 2; + int lmp = l80 + lmpml; + uimmp = (-1.0 * lmpml) * uim; + int impmmmp = lmp * (lmp + 1); + for (int im70 = 1; im70 <= ltpo; im70++) { + int m = im70 - lpo; + int mmp = m - mu; + int abs_mmp = (mmp > 0) ? mmp : -mmp; + if (abs_mmp <= lmp) { + int i = imm + m; + int ie = i + nlem; + int imp = impmmmp + mmp; + int impe = imp + nlem; + double cgc = cg1(lmpml, mu, l80, m); + int jpo = 2; + for (int ipo = 1; ipo <= 2; ipo++) { + if (ipo == 2) jpo = 1; + //printf("DEBUG: i=%d, ipo=%d, imp=%d\n", i, ipo, imp); + //fflush(stdout); + summ = dconjg(ac[i - 1][ipo - 1]) * ac[imp - 1][ipo - 1]; + sume = dconjg(ac[i - 1][ipo - 1]) * ac[impe - 1][ipo - 1]; + suem = dconjg(ac[ie - 1][ipo - 1]) * ac[imp - 1][ipo - 1]; + suee = dconjg(ac[ie - 1][ipo - 1]) * ac[impe - 1][ipo - 1]; + summp = dconjg(ac[i - 1][jpo - 1]) * ac[imp - 1][ipo - 1]; + sumep = dconjg(ac[i - 1][jpo - 1]) * ac[impe - 1][ipo - 1]; + suemp = dconjg(ac[ie - 1][jpo - 1]) * ac[imp - 1][ipo - 1]; + sueep = dconjg(ac[ie - 1][jpo - 1]) * ac[impe - 1][ipo - 1]; + if (lmpml != 0) { + summ *= uimmp; + sume *= uimmp; + suem *= uimmp; + suee *= uimmp; + summp *= uimmp; + sumep *= uimmp; + suemp *= uimmp; + sueep *= uimmp; + } + // label 55 + gap[imu90 - 1][ipo - 1] += ( + ( + summ * zpv[l80 - 1][ilmp - 1][0][0] + + sume * zpv[l80 - 1][ilmp - 1][0][1] + + suem * zpv[l80 - 1][ilmp - 1][1][0] + + suee * zpv[l80 - 1][ilmp - 1][1][1] + ) * cgc + ); + gapp[imu90 - 1][ipo - 1] += ( + ( + summp * zpv[l80 - 1][ilmp - 1][0][0] + + sumep * zpv[l80 - 1][ilmp - 1][0][1] + + suemp * zpv[l80 - 1][ilmp - 1][1][0] + + sueep * zpv[l80 - 1][ilmp - 1][1][1] + ) * cgc + ); + } // ipo loop + } // ends im70 loop + } // im70 loop + } // ilmp loop + } // l80 loop + } // imu90 loop + for (int ipo95 = 1; ipo95 <= 2; ipo95++) { + sume = gap[0][ipo95 - 1] * cimu; + suee = gap[1][ipo95 - 1] * cof; + suem = gap[2][ipo95 - 1] * cimu; + gapr[0][ipo95 - 1] = (sume - suem).real(); + gapr[1][ipo95 - 1] = ((sume + suem) * uim).real(); + gapr[2][ipo95 - 1] = suee.real(); + sumep = gapp[0][ipo95 - 1] * cimu; + sueep = gapp[1][ipo95 - 1] * cof; + suemp = gapp[2][ipo95 - 1] * cimu; + gapp[0][ipo95 - 1] = sumep - suemp; + gapp[1][ipo95 - 1] = (sumep + suemp) * uim; + gapp[2][ipo95 - 1] = sueep; + } // ipo95 loop + // Clean memory + for (int ai = nlemt - 1; ai > -1; ai--) delete[] ac[ai]; + for (int gi = 2; gi > -1; gi--) delete[] gap[gi]; + delete[] ac; + delete[] gap; } /*! \brief C++ porting of APCRA @@ -727,223 +727,223 @@ void apc( * \param gappm: Matrix of complex. */ void apcra( - double ****zpv, const int le, std::complex<double> **am0m, int inpol, double sqk, - double **gaprm, std::complex<double> **gappm -) { - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - std::complex<double> uimtl, uimtls, ca11, ca12, ca21, ca22; - std::complex<double> a11, a12, a21, a22, sum1, sum2, fc; - double ****svw = new double***[le]; - std::complex<double> ****svs = new std::complex<double>***[le]; - for (int i = 0; i < le; i++) { - svw[i] = new double**[3]; - svs[i] = new std::complex<double>**[3]; - for (int j = 0; j < 3; j++) { - svw[i][j] = new double*[2]; - svs[i][j] = new std::complex<double>*[2]; - for (int k = 0; k < 2; k++) { - svw[i][j][k] = new double[2](); - svs[i][j][k] = new std::complex<double>[2](); - } - } - } - int nlem = le * (le + 2); - for (int l28 = 1; l28 <= le; l28++) { - int lpo = l28 + 1; - int ltpo = lpo + l28; - double fl = sqrt(1.0 * ltpo); - for (int ilmp = 1; ilmp <= 3; ilmp++) { - if ((l28 == 1 && ilmp == 1) || (l28 == le && ilmp == 3)) continue; // ilmp loop - int lmpml = ilmp - 2; - int lmp = l28 + lmpml; - double flmp = sqrt(1.0 * (lmp + lmp + 1)); - double fllmp = flmp / fl; - double cgmmo = fllmp * cg1(lmpml, 0, l28, 1); - double cgmpo = fllmp * cg1(lmpml, 0, l28, -1); - if (inpol == 0) { - double cgs = cgmpo + cgmmo; - double cgd = cgmpo - cgmmo; - svw[l28 - 1][ilmp - 1][0][0] = cgs; - svw[l28 - 1][ilmp - 1][0][1] = cgd; - svw[l28 - 1][ilmp - 1][1][0] = cgd; - svw[l28 - 1][ilmp - 1][1][1] = cgs; - } else { // label 22 - svw[l28 - 1][ilmp - 1][0][0] = cgmpo; - svw[l28 - 1][ilmp - 1][1][0] = cgmpo; - svw[l28 - 1][ilmp - 1][0][1] = -cgmmo; - svw[l28 - 1][ilmp - 1][1][1] = cgmmo; - } - // label 26 - } // ilmp loop - } // l28 loop - for (int l30 = 1; l30 <= le; l30++) { // 0-init: can be omitted - for (int ilmp = 1; ilmp <= 3; ilmp++) { - for (int ipa = 1; ipa <= 2; ipa++) { - for (int ipamp = 1; ipamp <= 2; ipamp++) { - svs[l30 - 1][ilmp - 1][ipa - 1][ipamp - 1] = cc0; - } - } // ipa loop - } // ilmp loop - } // l30 loop - for (int l58 = 1; l58 <= le; l58 ++) { - int lpo = l58 + 1; - int ltpo = l58 + lpo; - int imm = l58 * lpo; - for (int ilmp = 1; ilmp <= 3; ilmp++) { - if ((l58 == 1 && ilmp == 1) || (l58 == le && ilmp == 3)) continue; // ilmp loop - int lmpml = ilmp - 2; - int lmp = l58 + lmpml; - int impmm = lmp * (lmp + 1); - uimtl = uim * (1.0 * lmpml); - if (lmpml == 0) uimtl = std::complex<double>(1.0, 0.0); - for (int im54 = 1; im54 <= ltpo; im54++) { - int m = im54 - lpo; - int i = imm + m; - int ie = i + nlem; - for (int imu52 = 1; imu52 <= 3; imu52++) { - int mu = imu52 - 2; - int mmp = m - mu; - int abs_mmp = (mmp > 0) ? mmp : -mmp; - if (abs_mmp <= lmp) { - int imp = impmm + mmp; - int impe = imp + nlem; - double cgc = cg1(lmpml, -mu, l58, -m); - for (int ls = 1; ls <= le; ls++) { - int lspo = ls + 1; - int lstpo = ls + lspo; - int ismm = ls * lspo; - for (int ilsmp = 1; ilsmp <= 3; ilsmp++) { - if ((ls == 1 && ilsmp == 1) || (ls == le && ilsmp == 3)) continue; // ilsmp loop - int lsmpml = ilsmp - 2; - int lsmp = ls + lsmpml; - int ismpmm = lsmp * (lsmp + 1); - uimtls = -uim * (1.0 * lsmpml); - if (lsmpml == 0) uimtls = std::complex<double>(1.0, 0.0); - for (int ims = 1; ims <= lstpo; ims++) { - int ms = ims - lspo; - int msmp = ms - mu; - int abs_msmp = (msmp > 0) ? msmp : -msmp; - if (abs_msmp <= lsmp) { - int is = ismm + ms; - int ise = is + nlem; - int ismp = ismpmm + msmp; - int ismpe = ismp + nlem; - double cgcs = cg1(lsmpml, mu, ls, ms); - fc = (uimtl * uimtls) * (cgc * cgcs); - ca11 = dconjg(am0m[is - 1][i - 1]); - ca12 = dconjg(am0m[is - 1][ie - 1]); - ca21 = dconjg(am0m[ise - 1][i - 1]); - ca22 = dconjg(am0m[ise - 1][ie - 1]); - a11 = am0m[ismp - 1][imp - 1]; - a12 = am0m[ismp - 1][impe - 1]; - a21 = am0m[ismpe - 1][imp - 1]; - a22 = am0m[ismpe - 1][impe - 1]; - double z11 = zpv[ls - 1][ilsmp - 1][0][0]; - double z12 = zpv[ls - 1][ilsmp - 1][0][1]; - double z21 = zpv[ls - 1][ilsmp - 1][1][0]; - double z22 = zpv[ls - 1][ilsmp - 1][1][1]; - svs[l58 - 1][ilmp - 1][0][0] += ((ca11 * a11 * z11 - + ca11 * a21 * z12 - + ca21 * a11 * z21 - + ca21 * a21 * z22) * fc); - svs[l58 - 1][ilmp - 1][0][1] += ((ca11 * a12 * z11 - + ca11 * a22 * z12 - + ca21 * a12 * z21 - + ca21 * a22 * z22) * fc); - svs[l58 - 1][ilmp - 1][1][0] += ((ca12 * a11 * z11 - + ca12 * a21 * z12 - + ca22 * a11 * z21 - + ca22 * a21 * z22) * fc); - svs[l58 - 1][ilmp - 1][1][1] += ((ca12 * a12 * z11 - + ca12 * a22 * z12 - + ca22 * a12 * z21 - + ca22 * a22 * z22) * fc); - } // ends ims loop - } // ims loop - } // ilsmp loop - } // ls loop - } // ends imu52 loop - } // imu52 loop - } // im54 loop - } // ilmp loop - } // l58 loop - sum1 = cc0; - sum2 = cc0; - for (int l68 = 1; l68 <= le; l68++) { - //int lpo = l68 + 1; - //int ltpo = l68 + lpo; - //int imm = l68 * lpo; - for (int ilmp = 1; ilmp <= 3; ilmp++) { - if ((l68 == 1 && ilmp == 1) || (l68 == le && ilmp == 3)) continue; // ilmp loop - if (inpol == 0) { - sum1 += ( - svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][0][0] - + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][0][1] - + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][1][0] - + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][1][1] - ); - sum2 += ( - svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][0][0] - + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][0][1] - + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][1][0] - + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][1][1] - ); - } else { // label 62 - sum1 += ( - svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][0][0] - + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][0][1] - + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][1][0] - + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][1][1] - ); - sum2 += ( - svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][0][0] - + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][0][1] - + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][1][0] - + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][1][1] - ); - } // label 66, ends ilmp loop - } // ilmp loop - } // l68 loop - const double half_pi = acos(0.0); - double cofs = half_pi * 2.0 / sqk; - gaprm[0][0] = 0.0; - gaprm[0][1] = 0.0; - gaprm[1][0] = 0.0; - gaprm[1][1] = 0.0; - gappm[0][0] = cc0; - gappm[0][1] = cc0; - gappm[1][0] = cc0; - gappm[1][1] = cc0; - if (inpol == 0) { - sum1 *= cofs; - sum2 *= cofs; - gaprm[2][0] = sum1.real(); - gaprm[2][1] = sum1.real(); - gappm[2][0] = sum2 * uim; - gappm[2][1] = -gappm[2][0]; - } else { // label 72 - cofs *= 2.0; - gaprm[2][0] = sum1.real() * cofs; - gaprm[2][1] = sum2.real() * cofs; - gappm[2][0] = cc0; - gappm[2][1] = cc0; + double ****zpv, const int le, std::complex<double> **am0m, int inpol, double sqk, + double **gaprm, std::complex<double> **gappm + ) { + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + std::complex<double> uimtl, uimtls, ca11, ca12, ca21, ca22; + std::complex<double> a11, a12, a21, a22, sum1, sum2, fc; + double ****svw = new double***[le]; + std::complex<double> ****svs = new std::complex<double>***[le]; + for (int i = 0; i < le; i++) { + svw[i] = new double**[3]; + svs[i] = new std::complex<double>**[3]; + for (int j = 0; j < 3; j++) { + svw[i][j] = new double*[2]; + svs[i][j] = new std::complex<double>*[2]; + for (int k = 0; k < 2; k++) { + svw[i][j][k] = new double[2](); + svs[i][j][k] = new std::complex<double>[2](); + } + } + } + int nlem = le * (le + 2); + for (int l28 = 1; l28 <= le; l28++) { + int lpo = l28 + 1; + int ltpo = lpo + l28; + double fl = sqrt(1.0 * ltpo); + for (int ilmp = 1; ilmp <= 3; ilmp++) { + if ((l28 == 1 && ilmp == 1) || (l28 == le && ilmp == 3)) continue; // ilmp loop + int lmpml = ilmp - 2; + int lmp = l28 + lmpml; + double flmp = sqrt(1.0 * (lmp + lmp + 1)); + double fllmp = flmp / fl; + double cgmmo = fllmp * cg1(lmpml, 0, l28, 1); + double cgmpo = fllmp * cg1(lmpml, 0, l28, -1); + if (inpol == 0) { + double cgs = cgmpo + cgmmo; + double cgd = cgmpo - cgmmo; + svw[l28 - 1][ilmp - 1][0][0] = cgs; + svw[l28 - 1][ilmp - 1][0][1] = cgd; + svw[l28 - 1][ilmp - 1][1][0] = cgd; + svw[l28 - 1][ilmp - 1][1][1] = cgs; + } else { // label 22 + svw[l28 - 1][ilmp - 1][0][0] = cgmpo; + svw[l28 - 1][ilmp - 1][1][0] = cgmpo; + svw[l28 - 1][ilmp - 1][0][1] = -cgmmo; + svw[l28 - 1][ilmp - 1][1][1] = cgmmo; + } + // label 26 + } // ilmp loop + } // l28 loop + for (int l30 = 1; l30 <= le; l30++) { // 0-init: can be omitted + for (int ilmp = 1; ilmp <= 3; ilmp++) { + for (int ipa = 1; ipa <= 2; ipa++) { + for (int ipamp = 1; ipamp <= 2; ipamp++) { + svs[l30 - 1][ilmp - 1][ipa - 1][ipamp - 1] = cc0; } - // Clean memory - for (int i = le - 1; i > -1; i--) { - for (int j = 2; j > -1; j--) { - for (int k = 1; k > -1; k--) { - delete[] svw[i][j][k]; - delete[] svs[i][j][k]; - } - delete[] svw[i][j]; - delete[] svs[i][j]; - } - delete[] svw[i]; - delete[] svs[i]; - } - delete[] svw; - delete[] svs; + } // ipa loop + } // ilmp loop + } // l30 loop + for (int l58 = 1; l58 <= le; l58 ++) { + int lpo = l58 + 1; + int ltpo = l58 + lpo; + int imm = l58 * lpo; + for (int ilmp = 1; ilmp <= 3; ilmp++) { + if ((l58 == 1 && ilmp == 1) || (l58 == le && ilmp == 3)) continue; // ilmp loop + int lmpml = ilmp - 2; + int lmp = l58 + lmpml; + int impmm = lmp * (lmp + 1); + uimtl = uim * (1.0 * lmpml); + if (lmpml == 0) uimtl = std::complex<double>(1.0, 0.0); + for (int im54 = 1; im54 <= ltpo; im54++) { + int m = im54 - lpo; + int i = imm + m; + int ie = i + nlem; + for (int imu52 = 1; imu52 <= 3; imu52++) { + int mu = imu52 - 2; + int mmp = m - mu; + int abs_mmp = (mmp > 0) ? mmp : -mmp; + if (abs_mmp <= lmp) { + int imp = impmm + mmp; + int impe = imp + nlem; + double cgc = cg1(lmpml, -mu, l58, -m); + for (int ls = 1; ls <= le; ls++) { + int lspo = ls + 1; + int lstpo = ls + lspo; + int ismm = ls * lspo; + for (int ilsmp = 1; ilsmp <= 3; ilsmp++) { + if ((ls == 1 && ilsmp == 1) || (ls == le && ilsmp == 3)) continue; // ilsmp loop + int lsmpml = ilsmp - 2; + int lsmp = ls + lsmpml; + int ismpmm = lsmp * (lsmp + 1); + uimtls = -uim * (1.0 * lsmpml); + if (lsmpml == 0) uimtls = std::complex<double>(1.0, 0.0); + for (int ims = 1; ims <= lstpo; ims++) { + int ms = ims - lspo; + int msmp = ms - mu; + int abs_msmp = (msmp > 0) ? msmp : -msmp; + if (abs_msmp <= lsmp) { + int is = ismm + ms; + int ise = is + nlem; + int ismp = ismpmm + msmp; + int ismpe = ismp + nlem; + double cgcs = cg1(lsmpml, mu, ls, ms); + fc = (uimtl * uimtls) * (cgc * cgcs); + ca11 = dconjg(am0m[is - 1][i - 1]); + ca12 = dconjg(am0m[is - 1][ie - 1]); + ca21 = dconjg(am0m[ise - 1][i - 1]); + ca22 = dconjg(am0m[ise - 1][ie - 1]); + a11 = am0m[ismp - 1][imp - 1]; + a12 = am0m[ismp - 1][impe - 1]; + a21 = am0m[ismpe - 1][imp - 1]; + a22 = am0m[ismpe - 1][impe - 1]; + double z11 = zpv[ls - 1][ilsmp - 1][0][0]; + double z12 = zpv[ls - 1][ilsmp - 1][0][1]; + double z21 = zpv[ls - 1][ilsmp - 1][1][0]; + double z22 = zpv[ls - 1][ilsmp - 1][1][1]; + svs[l58 - 1][ilmp - 1][0][0] += ((ca11 * a11 * z11 + + ca11 * a21 * z12 + + ca21 * a11 * z21 + + ca21 * a21 * z22) * fc); + svs[l58 - 1][ilmp - 1][0][1] += ((ca11 * a12 * z11 + + ca11 * a22 * z12 + + ca21 * a12 * z21 + + ca21 * a22 * z22) * fc); + svs[l58 - 1][ilmp - 1][1][0] += ((ca12 * a11 * z11 + + ca12 * a21 * z12 + + ca22 * a11 * z21 + + ca22 * a21 * z22) * fc); + svs[l58 - 1][ilmp - 1][1][1] += ((ca12 * a12 * z11 + + ca12 * a22 * z12 + + ca22 * a12 * z21 + + ca22 * a22 * z22) * fc); + } // ends ims loop + } // ims loop + } // ilsmp loop + } // ls loop + } // ends imu52 loop + } // imu52 loop + } // im54 loop + } // ilmp loop + } // l58 loop + sum1 = cc0; + sum2 = cc0; + for (int l68 = 1; l68 <= le; l68++) { + //int lpo = l68 + 1; + //int ltpo = l68 + lpo; + //int imm = l68 * lpo; + for (int ilmp = 1; ilmp <= 3; ilmp++) { + if ((l68 == 1 && ilmp == 1) || (l68 == le && ilmp == 3)) continue; // ilmp loop + if (inpol == 0) { + sum1 += ( + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][0][0] + + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][0][1] + + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][1][0] + + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][1][1] + ); + sum2 += ( + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][0][0] + + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][0][1] + + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][1][0] + + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][1][1] + ); + } else { // label 62 + sum1 += ( + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][0][0] + + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][0][1] + + svw[l68 - 1][ilmp - 1][0][0] * svs[l68 - 1][ilmp - 1][1][0] + + svw[l68 - 1][ilmp - 1][1][0] * svs[l68 - 1][ilmp - 1][1][1] + ); + sum2 += ( + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][0][0] + + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][0][1] + + svw[l68 - 1][ilmp - 1][0][1] * svs[l68 - 1][ilmp - 1][1][0] + + svw[l68 - 1][ilmp - 1][1][1] * svs[l68 - 1][ilmp - 1][1][1] + ); + } // label 66, ends ilmp loop + } // ilmp loop + } // l68 loop + const double half_pi = acos(0.0); + double cofs = half_pi * 2.0 / sqk; + gaprm[0][0] = 0.0; + gaprm[0][1] = 0.0; + gaprm[1][0] = 0.0; + gaprm[1][1] = 0.0; + gappm[0][0] = cc0; + gappm[0][1] = cc0; + gappm[1][0] = cc0; + gappm[1][1] = cc0; + if (inpol == 0) { + sum1 *= cofs; + sum2 *= cofs; + gaprm[2][0] = sum1.real(); + gaprm[2][1] = sum1.real(); + gappm[2][0] = sum2 * uim; + gappm[2][1] = -gappm[2][0]; + } else { // label 72 + cofs *= 2.0; + gaprm[2][0] = sum1.real() * cofs; + gaprm[2][1] = sum2.real() * cofs; + gappm[2][0] = cc0; + gappm[2][1] = cc0; + } + // Clean memory + for (int i = le - 1; i > -1; i--) { + for (int j = 2; j > -1; j--) { + for (int k = 1; k > -1; k--) { + delete[] svw[i][j][k]; + delete[] svs[i][j][k]; + } + delete[] svw[i][j]; + delete[] svs[i][j]; + } + delete[] svw[i]; + delete[] svs[i]; + } + delete[] svw; + delete[] svs; } /*! \brief C++ porting of CMS @@ -955,295 +955,295 @@ void apcra( * \param c6: `C6 *` */ void cms(std::complex<double> **am, C1 *c1, C1_AddOns *c1ao, C4 *c4, C6 *c6) { - std::complex<double> dm, de, cgh, cgk; - const std::complex<double> cc0(0.0, 0.0); - int ndi = c4->nsph * c4->nlim; - int nbl = 0; - int nsphmo = c4->nsph - 1; - for (int n1 = 1; n1 <= nsphmo; n1++) { // GPU portable? - int in1 = (n1 - 1) * c4->nlim; - int n1po = n1 + 1; - for (int n2 = n1po; n2 <= c4->nsph; n2++) { - int in2 = (n2 - 1) * c4->nlim; - nbl++; - for (int l1 = 1; l1 <= c4->li; l1++) { - int l1po = l1 + 1; - int il1 = l1po * l1; - int l1tpo = l1po + l1; - for (int im1 = 1; im1 <= l1tpo; im1++) { - int m1 = im1 - l1po; - int ilm1 = il1 + m1; - int ilm1e = ilm1 + ndi; - int i1 = in1 + ilm1; - int i1e = in1 + ilm1e; - int j1 = in2 + ilm1; - int j1e = in2 + ilm1e; - for (int l2 = 1; l2 <= c4->li; l2++) { - int l2po = l2 + 1; - int il2 = l2po * l2; - int l2tpo = l2po + l2; - int ish = ((l2 + l1) % 2 == 0) ? 1 : -1; - int isk = -ish; - for (int im2 = 1; im2 <= l2tpo; im2++) { - int m2 = im2 - l2po; - int ilm2 = il2 + m2; - int ilm2e = ilm2 + ndi; - int i2 = in2 + ilm2; - int i2e = in2 + ilm2e; - int j2 = in1 + ilm2; - int j2e = in1 + ilm2e; - cgh = ghit(0, 0, nbl, l1, m1, l2, m2, c1, c1ao, c4, c6); - cgk = ghit(0, 1, nbl, l1, m1, l2, m2, c1, c1ao, c4, c6); - am[i1 - 1][i2 - 1] = cgh; - am[i1 - 1][i2e - 1] = cgk; - am[i1e - 1][i2 - 1] = cgk; - am[i1e - 1][i2e - 1] = cgh; - am[j1 - 1][j2 - 1] = cgh * (1.0 * ish); - am[j1 - 1][j2e - 1] = cgk * (1.0 * isk); - am[j1e - 1][j2 - 1] = cgk * (1.0 * isk); - am[j1e - 1][j2e - 1] = cgh * (1.0 * ish); - } - } - } // im1 loop - } // l1 loop - } // n2 loop - } // n1 loop - for (int n1 = 1; n1 <= c4->nsph; n1++) { // GPU portable? - int in1 = (n1 - 1) * c4->nlim; - for (int l1 = 1; l1 <= c4->li; l1++) { - dm = c1->rmi[l1 - 1][n1 - 1]; - de = c1->rei[l1 - 1][n1 - 1]; - int l1po = l1 + 1; - int il1 = l1po * l1; - int l1tpo = l1po + l1; - for (int im1 = 1; im1 <= l1tpo; im1++) { - int m1 = im1 - l1po; - int ilm1 = il1 + m1; - int i1 = in1 + ilm1; - int i1e = i1 + ndi; - for (int ilm2 = 1; ilm2 <= c4->nlim; ilm2++) { - int i2 = in1 + ilm2; - int i2e = i2 + ndi; - am[i1 - 1][i2 - 1] = cc0; - am[i1 - 1][i2e - 1] = cc0; - am[i1e - 1][i2 - 1] = cc0; - am[i1e - 1][i2e - 1] = cc0; - } - am[i1 - 1][i1 - 1] = dm; - am[i1e - 1][i1e - 1] = de; - } // im1 loop - } // l1 loop - } // n1 loop + std::complex<double> dm, de, cgh, cgk; + const std::complex<double> cc0(0.0, 0.0); + int ndi = c4->nsph * c4->nlim; + int nbl = 0; + int nsphmo = c4->nsph - 1; + for (int n1 = 1; n1 <= nsphmo; n1++) { // GPU portable? + int in1 = (n1 - 1) * c4->nlim; + int n1po = n1 + 1; + for (int n2 = n1po; n2 <= c4->nsph; n2++) { + int in2 = (n2 - 1) * c4->nlim; + nbl++; + for (int l1 = 1; l1 <= c4->li; l1++) { + int l1po = l1 + 1; + int il1 = l1po * l1; + int l1tpo = l1po + l1; + for (int im1 = 1; im1 <= l1tpo; im1++) { + int m1 = im1 - l1po; + int ilm1 = il1 + m1; + int ilm1e = ilm1 + ndi; + int i1 = in1 + ilm1; + int i1e = in1 + ilm1e; + int j1 = in2 + ilm1; + int j1e = in2 + ilm1e; + for (int l2 = 1; l2 <= c4->li; l2++) { + int l2po = l2 + 1; + int il2 = l2po * l2; + int l2tpo = l2po + l2; + int ish = ((l2 + l1) % 2 == 0) ? 1 : -1; + int isk = -ish; + for (int im2 = 1; im2 <= l2tpo; im2++) { + int m2 = im2 - l2po; + int ilm2 = il2 + m2; + int ilm2e = ilm2 + ndi; + int i2 = in2 + ilm2; + int i2e = in2 + ilm2e; + int j2 = in1 + ilm2; + int j2e = in1 + ilm2e; + cgh = ghit(0, 0, nbl, l1, m1, l2, m2, c1, c1ao, c4, c6); + cgk = ghit(0, 1, nbl, l1, m1, l2, m2, c1, c1ao, c4, c6); + am[i1 - 1][i2 - 1] = cgh; + am[i1 - 1][i2e - 1] = cgk; + am[i1e - 1][i2 - 1] = cgk; + am[i1e - 1][i2e - 1] = cgh; + am[j1 - 1][j2 - 1] = cgh * (1.0 * ish); + am[j1 - 1][j2e - 1] = cgk * (1.0 * isk); + am[j1e - 1][j2 - 1] = cgk * (1.0 * isk); + am[j1e - 1][j2e - 1] = cgh * (1.0 * ish); + } + } + } // im1 loop + } // l1 loop + } // n2 loop + } // n1 loop + for (int n1 = 1; n1 <= c4->nsph; n1++) { // GPU portable? + int in1 = (n1 - 1) * c4->nlim; + for (int l1 = 1; l1 <= c4->li; l1++) { + dm = c1->rmi[l1 - 1][n1 - 1]; + de = c1->rei[l1 - 1][n1 - 1]; + int l1po = l1 + 1; + int il1 = l1po * l1; + int l1tpo = l1po + l1; + for (int im1 = 1; im1 <= l1tpo; im1++) { + int m1 = im1 - l1po; + int ilm1 = il1 + m1; + int i1 = in1 + ilm1; + int i1e = i1 + ndi; + for (int ilm2 = 1; ilm2 <= c4->nlim; ilm2++) { + int i2 = in1 + ilm2; + int i2e = i2 + ndi; + am[i1 - 1][i2 - 1] = cc0; + am[i1 - 1][i2e - 1] = cc0; + am[i1e - 1][i2 - 1] = cc0; + am[i1e - 1][i2e - 1] = cc0; + } + am[i1 - 1][i1 - 1] = dm; + am[i1e - 1][i1e - 1] = de; + } // im1 loop + } // l1 loop + } // n1 loop } /*! \brief C++ porting of CRSM1 * - * \param vk: `double` - * \param exri: `double` + * \param vk: `double` Wave number. + * \param exri: `double` External medium refractive index. * \param c1: `C1 *` * \param c1ao: `C1_AddOns *` * \param c4: `C4 *` * \param c6: `C6 *` */ void crsm1(double vk, double exri, C1 *c1, C1_AddOns *c1ao, C4 *c4, C6 *c6) { - std::complex<double> ***svf, ***svw, **svs; - const std::complex<double> cc0(0.0, 0.0); - std::complex<double> cam(0.0, 0.0); - const int le4po = 4 * c4->le + 1; - svf = new std::complex<double>**[le4po]; - svw = new std::complex<double>**[le4po]; - svs = new std::complex<double>*[le4po]; - for (int si = 0; si < le4po; si++) { - svf[si] = new std::complex<double>*[le4po]; - svw[si] = new std::complex<double>*[4]; - svs[si] = new std::complex<double>[4](); - for (int sj = 0; sj < le4po; sj++) svf[si][sj] = new std::complex<double>[4](); - for (int sj = 0; sj < 4; sj++) svw[si][sj] = new std::complex<double>[4](); - } - double exdc = exri * exri; - double ccs = 1.0 / (vk * vk); - const double pi4sq = 64.0 * acos(0.0) * acos(0.0); - double cint = ccs / (pi4sq * exdc); - int letpo = c4->le + c4->le + 1; - for (int i20 = 0; i20 < 16; i20++) c1ao->vintm[i20] = cc0; // 0-init: can be omitted - for (int lpo40 = 1; lpo40 <= letpo; lpo40++) { - int l = lpo40 - 1; - int ltpo = lpo40 + l; - int immn = letpo - l; - int immx = letpo + l; - for (int imf = immn; imf <= immx; imf++) { // 0-init: can be omitted - for (int ims = immn; ims <= immx; ims++) { - for (int ipo = 1; ipo <= 4; ipo++) { - svf[imf - 1][ims - 1][ipo - 1] = cc0; - } // ipo loop - } // ims loop - } // imf loop - for (int l1 = 1; l1 <= c4->le; l1++) { - int il1 = l1 * (l1 + 1); - for (int l2 = 1; l2 <= c4->le; l2++) { - int abs_l2ml1 = (l2 > l1) ? l2 - l1 : l1 - l2; - if (l < abs_l2ml1 || l > l2 + l1) continue; // l2 loop - int il2 = l2 * (l2 + 1); - for (int im = immn; im >= immx; im++) { // 0-init: can be omitted - for (int ipa = 1; ipa <= 4; ipa++) { - svs[im - 1][ipa - 1] = cc0; - for (int ipo = 1; ipo <= 4; ipo++) { - svw[im - 1][ipa - 1][ipo - 1] = cc0; - } // ipo loop - } // ipa loop - } // im loop - for (int im = immn; im <= immx; im++) { - int m = im - letpo; - r3jmr(l, l1, l2, m, c6); - int m1mnmo = (-l1 > -l2 - m) ? -(l1 + 1) : -(l2 + m + 1); - int nm1 = (l1 < l2 - m) ? (l1 - m1mnmo) : (l2 - m - m1mnmo); - for (int im1 = 1; im1 <= nm1; im1++) { - int m1 = -im1 - m1mnmo; - int isn = 1; - if (m1 % 2 != 0) isn = -1; - double cg3j = c6->rac3j[im1 - 1] * isn; - int ilm1 = il1 + m1; - int ilm2 = il2 + m1 - m; - int ipa = 0; - for (int ipa1 = 1; ipa1 <= 2; ipa1++) { - int i1 = ilm1; - if (ipa1 == 2) i1 = ilm1 + c4->nlem; - for (int ipa2 = 1; ipa2 <= 2; ipa2++) { - int i2 = ilm2; - if (ipa2 == 2) i2 = ilm2 + c4->nlem; - ipa++; - svs[im - 1][ipa - 1] += (c1ao->am0m[i1 - 1][i2 - 1] * cg3j); - int ipo = 0; - for (int ipo2 = 1; ipo2 <= 2; ipo2++) { - for (int ipo1 = 3; ipo1 <= 4; ipo1++) { - ipo++; - svw[im - 1][ipa - 1][ipo - 1] += (c1->w[i1 - 1][ipo1 - 1] * c1->w[i2 - 1][ipo2 - 1] * cg3j); - } // ipo1 loop - } // ipo2 loop - } // ipa2 loop - } // ipa1 loop - } // im1 loop - // label 32 loops - for (int imf = immn; imf <= immx; imf++) { - for (int ims = immn; ims <= immx; ims++) { - for (int ipo = 1; ipo <= 4; ipo++) { - for (int ipa = 1; ipa <= 4; ipa++) { - svf[imf - 1][ims - 1][ipo - 1] += (svw[imf - 1][ipa - 1][ipo - 1] * svs[ims - 1][ipa - 1]); - } // ipa loop - } // ipo loop - } // ims loop - } // imf loop - // ends loop level 34, which are l2 loop and l1 loop - } // im loop - } // l2 loop - } // l1 loop - for (int imf = immn; imf <= immx; imf++) { - for (int ims = immn; ims <= immx; ims++) { - int i = 0; - for (int ipo1 = 1; ipo1 <= 4; ipo1++) { - cam = dconjg(svf[imf - 1][ims - 1][ipo1 - 1]); - for (int ipo2 = 1; ipo2 <= 4; ipo2++) { - i++; - c1ao->vintm[i - 1] += (svf[imf - 1][ims - 1][ipo2 - 1] * cam * (1.0 * ltpo)); - } - } // ipo1 loop - } // ims loop - } // imf loop - } // lpo40 loop - for (int i42 = 0; i42 < 16; i42++) c1ao->vintm[i42] *= cint; + std::complex<double> ***svf, ***svw, **svs; + const std::complex<double> cc0(0.0, 0.0); + std::complex<double> cam(0.0, 0.0); + const int le4po = 4 * c4->le + 1; + svf = new std::complex<double>**[le4po]; + svw = new std::complex<double>**[le4po]; + svs = new std::complex<double>*[le4po]; + for (int si = 0; si < le4po; si++) { + svf[si] = new std::complex<double>*[le4po]; + svw[si] = new std::complex<double>*[4]; + svs[si] = new std::complex<double>[4](); + for (int sj = 0; sj < le4po; sj++) svf[si][sj] = new std::complex<double>[4](); + for (int sj = 0; sj < 4; sj++) svw[si][sj] = new std::complex<double>[4](); + } + double exdc = exri * exri; + double ccs = 1.0 / (vk * vk); + const double pi4sq = 64.0 * acos(0.0) * acos(0.0); + double cint = ccs / (pi4sq * exdc); + int letpo = c4->le + c4->le + 1; + for (int i20 = 0; i20 < 16; i20++) c1ao->vintm[i20] = cc0; // 0-init: can be omitted + for (int lpo40 = 1; lpo40 <= letpo; lpo40++) { + int l = lpo40 - 1; + int ltpo = lpo40 + l; + int immn = letpo - l; + int immx = letpo + l; + for (int imf = immn; imf <= immx; imf++) { // 0-init: can be omitted + for (int ims = immn; ims <= immx; ims++) { + for (int ipo = 1; ipo <= 4; ipo++) { + svf[imf - 1][ims - 1][ipo - 1] = cc0; + } // ipo loop + } // ims loop + } // imf loop + for (int l1 = 1; l1 <= c4->le; l1++) { + int il1 = l1 * (l1 + 1); + for (int l2 = 1; l2 <= c4->le; l2++) { + int abs_l2ml1 = (l2 > l1) ? l2 - l1 : l1 - l2; + if (l < abs_l2ml1 || l > l2 + l1) continue; // l2 loop + int il2 = l2 * (l2 + 1); + for (int im = immn; im >= immx; im++) { // 0-init: can be omitted + for (int ipa = 1; ipa <= 4; ipa++) { + svs[im - 1][ipa - 1] = cc0; + for (int ipo = 1; ipo <= 4; ipo++) { + svw[im - 1][ipa - 1][ipo - 1] = cc0; + } // ipo loop + } // ipa loop + } // im loop + for (int im = immn; im <= immx; im++) { + int m = im - letpo; + r3jmr(l, l1, l2, m, c6); + int m1mnmo = (-l1 > -l2 - m) ? -(l1 + 1) : -(l2 + m + 1); + int nm1 = (l1 < l2 - m) ? (l1 - m1mnmo) : (l2 - m - m1mnmo); + for (int im1 = 1; im1 <= nm1; im1++) { + int m1 = -im1 - m1mnmo; + int isn = 1; + if (m1 % 2 != 0) isn = -1; + double cg3j = c6->rac3j[im1 - 1] * isn; + int ilm1 = il1 + m1; + int ilm2 = il2 + m1 - m; + int ipa = 0; + for (int ipa1 = 1; ipa1 <= 2; ipa1++) { + int i1 = ilm1; + if (ipa1 == 2) i1 = ilm1 + c4->nlem; + for (int ipa2 = 1; ipa2 <= 2; ipa2++) { + int i2 = ilm2; + if (ipa2 == 2) i2 = ilm2 + c4->nlem; + ipa++; + svs[im - 1][ipa - 1] += (c1ao->am0m[i1 - 1][i2 - 1] * cg3j); + int ipo = 0; + for (int ipo2 = 1; ipo2 <= 2; ipo2++) { + for (int ipo1 = 3; ipo1 <= 4; ipo1++) { + ipo++; + svw[im - 1][ipa - 1][ipo - 1] += (c1->w[i1 - 1][ipo1 - 1] * c1->w[i2 - 1][ipo2 - 1] * cg3j); + } // ipo1 loop + } // ipo2 loop + } // ipa2 loop + } // ipa1 loop + } // im1 loop + // label 32 loops + for (int imf = immn; imf <= immx; imf++) { + for (int ims = immn; ims <= immx; ims++) { + for (int ipo = 1; ipo <= 4; ipo++) { + for (int ipa = 1; ipa <= 4; ipa++) { + svf[imf - 1][ims - 1][ipo - 1] += (svw[imf - 1][ipa - 1][ipo - 1] * svs[ims - 1][ipa - 1]); + } // ipa loop + } // ipo loop + } // ims loop + } // imf loop + // ends loop level 34, which are l2 loop and l1 loop + } // im loop + } // l2 loop + } // l1 loop + for (int imf = immn; imf <= immx; imf++) { + for (int ims = immn; ims <= immx; ims++) { + int i = 0; + for (int ipo1 = 1; ipo1 <= 4; ipo1++) { + cam = dconjg(svf[imf - 1][ims - 1][ipo1 - 1]); + for (int ipo2 = 1; ipo2 <= 4; ipo2++) { + i++; + c1ao->vintm[i - 1] += (svf[imf - 1][ims - 1][ipo2 - 1] * cam * (1.0 * ltpo)); + } + } // ipo1 loop + } // ims loop + } // imf loop + } // lpo40 loop + for (int i42 = 0; i42 < 16; i42++) c1ao->vintm[i42] *= cint; - // Clean memory - for (int si = le4po - 1; si > -1; si--) { - for (int sj = le4po - 1; sj > -1; sj--) delete[] svf[si][sj]; - for (int sj = 3; sj > -1; sj--) delete[] svw[si][sj]; - delete[] svf[si]; - delete[] svw[si]; - delete[] svs[si]; - } - delete[] svf; - delete[] svw; - delete[] svs; + // Clean memory + for (int si = le4po - 1; si > -1; si--) { + for (int sj = le4po - 1; sj > -1; sj--) delete[] svf[si][sj]; + for (int sj = 3; sj > -1; sj--) delete[] svw[si][sj]; + delete[] svf[si]; + delete[] svw[si]; + delete[] svs[si]; + } + delete[] svf; + delete[] svw; + delete[] svs; } /*! \brief C++ porting of HJV * - * \param exri: `double` - * \param vk: `double` - * \param jer: `int &` - * \param lcalc: `int &` + * \param exri: `double` External medium refractive index. + * \param vk: `double` Wave number. + * \param jer: `int &` Reference to error code flag. + * \param lcalc: `int &` Reference to the highest order accounted for in calculation. * \param arg: `complex\<double\> &` * \param c1: `C1 *` * \param c1ao: `C1_AddOns *` * \param c4: `C4 *` */ void hjv( - double exri, double vk, int &jer, int &lcalc, std::complex<double> &arg, - C1 *c1, C1_AddOns *c1ao, C4 *c4 -) { - int nsphmo = c4->nsph - 1; - int lit = c4->li + c4->li; - int lmt = c4->li + c4->le; - const int rfj_size = (lit > lmt) ? lit : lmt; - const int rfn_size = c4->litpo; - double *rfj, *rfn; - rfj = new double[rfj_size](); - rfn = new double[rfn_size](); - jer = 0; - int ivhb = 0; - for (int nf40 = 1; nf40 <= nsphmo; nf40++) { // GPU portable? - int nfpo = nf40 + 1; - for (int ns40 = nfpo; ns40 <= c4->nsph; ns40++) { - double rx = c1->rxx[nf40 - 1] - c1->rxx[ns40 - 1]; - double ry = c1->ryy[nf40 - 1] - c1->ryy[ns40 - 1]; - double rz = c1->rzz[nf40 - 1] - c1->rzz[ns40 - 1]; - double rr = sqrt(rx * rx + ry * ry + rz * rz); - double rarg = rr * vk * exri; - arg = std::complex<double>(rarg, 0.0); - rbf(lit, rarg, lcalc, rfj); - if (lcalc < lit) { - jer = 1; - delete[] rfj; - delete[] rfn; - return; - } - rnf(lit, rarg, lcalc, rfn); - if (lcalc < lit) { - jer = 2; - delete[] rfj; - delete[] rfn; - return; - } - for (int lpo38 = 1; lpo38 <= c4->litpo; lpo38++) { - double rpart = rfj[lpo38 - 1]; - double ipart = rfn[lpo38 - 1]; - c1ao->vh[lpo38 + ivhb - 1] = std::complex<double>(rpart, ipart); - } - ivhb += c4->litpo; - } // ns40 loop - } // nf40 loop - ivhb = 0; - for (int nf50 = 1; nf50 <= c4->nsph; nf50++) { - double rx = c1->rxx[nf50 - 1]; - double ry = c1->ryy[nf50 - 1]; - double rz = c1->rzz[nf50 - 1]; - if (!(rx == 0.0 && ry == 0.0 && rz == 0.0)) { - double rr = sqrt(rx * rx + ry * ry + rz * rz); - double rarg = rr * vk * exri; - rbf(lmt, rarg, lcalc, rfj); - if (lcalc < lmt) { - jer = 3; - delete[] rfj; - delete[] rfn; - return; - } - for (int lpo47 = 1; lpo47 <= c4->lmtpo; lpo47++) { - c1ao->vj0[lpo47 + ivhb - 1] = rfj[lpo47 - 1]; - } - } - ivhb += c4->lmtpo; - } // nf50 loop + double exri, double vk, int &jer, int &lcalc, std::complex<double> &arg, + C1 *c1, C1_AddOns *c1ao, C4 *c4 + ) { + int nsphmo = c4->nsph - 1; + int lit = c4->li + c4->li; + int lmt = c4->li + c4->le; + const int rfj_size = (lit > lmt) ? lit : lmt; + const int rfn_size = c4->litpo; + double *rfj, *rfn; + rfj = new double[rfj_size](); + rfn = new double[rfn_size](); + jer = 0; + int ivhb = 0; + for (int nf40 = 1; nf40 <= nsphmo; nf40++) { // GPU portable? + int nfpo = nf40 + 1; + for (int ns40 = nfpo; ns40 <= c4->nsph; ns40++) { + double rx = c1->rxx[nf40 - 1] - c1->rxx[ns40 - 1]; + double ry = c1->ryy[nf40 - 1] - c1->ryy[ns40 - 1]; + double rz = c1->rzz[nf40 - 1] - c1->rzz[ns40 - 1]; + double rr = sqrt(rx * rx + ry * ry + rz * rz); + double rarg = rr * vk * exri; + arg = std::complex<double>(rarg, 0.0); + rbf(lit, rarg, lcalc, rfj); + if (lcalc < lit) { + jer = 1; + delete[] rfj; + delete[] rfn; + return; + } + rnf(lit, rarg, lcalc, rfn); + if (lcalc < lit) { + jer = 2; + delete[] rfj; + delete[] rfn; + return; + } + for (int lpo38 = 1; lpo38 <= c4->litpo; lpo38++) { + double rpart = rfj[lpo38 - 1]; + double ipart = rfn[lpo38 - 1]; + c1ao->vh[lpo38 + ivhb - 1] = std::complex<double>(rpart, ipart); + } + ivhb += c4->litpo; + } // ns40 loop + } // nf40 loop + ivhb = 0; + for (int nf50 = 1; nf50 <= c4->nsph; nf50++) { + double rx = c1->rxx[nf50 - 1]; + double ry = c1->ryy[nf50 - 1]; + double rz = c1->rzz[nf50 - 1]; + if (!(rx == 0.0 && ry == 0.0 && rz == 0.0)) { + double rr = sqrt(rx * rx + ry * ry + rz * rz); + double rarg = rr * vk * exri; + rbf(lmt, rarg, lcalc, rfj); + if (lcalc < lmt) { + jer = 3; delete[] rfj; delete[] rfn; + return; + } + for (int lpo47 = 1; lpo47 <= c4->lmtpo; lpo47++) { + c1ao->vj0[lpo47 + ivhb - 1] = rfj[lpo47 - 1]; + } + } + ivhb += c4->lmtpo; + } // nf50 loop + delete[] rfj; + delete[] rfn; } /*! \brief C++ porting of LUCIN @@ -1254,380 +1254,380 @@ void hjv( * \param ier: `int &` */ void lucin(std::complex<double> **am, const int nddmst, int n, int &ier) { - /* NDDMST FIRST DIMENSION OF AM AS DECLARED IN DIMENSION - * STATEMENT. - * N NUMBER OF ROWS IN AM. - * IER IS REPLACED BY 1 FOR SINGULARITY. - */ - double *v = new double[nddmst]; - std::complex<double> ctemp, cfun; - std::complex<double> cc0 = std::complex<double>(0.0, 0.0); - ier = 0; - int nminus = n - 1; - for (int i = 1; i <= n; i++) { - double sum = 0.0; - for (int j = 1; j <= n; j++) { - sum += ( - am[i - 1][j - 1].real() * am[i - 1][j - 1].real() - + am[i - 1][j - 1].imag() * am[i - 1][j - 1].imag() - ); - } // j1319 loop - v[i - 1] = 1.0 / sum; - } // i1309 loop - // 2. REPLACE AM BY TRIANGULAR MATRICES (L,U) WHERE AM=L*U. - // REPLACE L(I,I) BY 1/L(I,I), READY FOR SECTION 4. - // (ROW INTERCHANGES TAKE PLACE, AND THE INDICES OF THE PIVOTAL ROWS - // ARE PLACED IN V.) - /* >>> THERE APPEARS TO BE A BUG IN THE FOLLOWING LOOP <<< */ - for (int k = 1; k <= n; k++) { - int kplus = k + 1; - int kminus = k - 1; - int l = k; - double psqmax = 0.0; - for (int i = k; i <= n; i++) { - cfun = cdtp(-am[i - 1][k - 1], am, i, 1, k, kminus); - ctemp = -cfun; - am[i - 1][k - 1] = ctemp; - double psq = v[i - 1] * (ctemp.real() * ctemp.real() + ctemp.imag() * ctemp.imag()); - if (psq > psqmax) { - psqmax = psq; - l = i; - } - } // i2029 loop - if (l != k) { - for (int j = 1; j <= n; j++) { - ctemp = am[k - 1][j - 1]; - am[k - 1][j - 1] = am[l - 1][j - 1]; - am[l - 1][j - 1] = ctemp; - } // j2049 loop - v[l - 1] = v[k - 1]; - } - // label 2011 - v[k - 1] = 1.0 * l; - if (psqmax == 0.0) { - ier = 1; - delete[] v; - return; - } - ctemp = 1.0 / am[k - 1][k - 1]; - am[k - 1][k - 1] = ctemp; - if (kplus <= n) { - for (int j = kplus; j <= n; j++) { - cfun = cdtp(-am[k - 1][j - 1], am, k, 1, j, kminus); - am[k - 1][j - 1] = -ctemp * cfun; - } // j2059 loop - } - } // k2019 loop - // 4. REPLACE AM BY ITS INVERSE AMINV. - // 4.1 REPLACE L AND U BY THEIR INVERSE LINV AND UINV. - for (int k = 1; k <= nminus; k++) { - int kplus = k + 1; - for (int i = kplus; i <= n; i++) { - cfun = cdtp(cc0, am, i, k, k, i - k); - am[i - 1][k - 1] = -am[i - 1][i - 1] * cfun; - cfun = cdtp(am[k - 1][i - 1], am, k, kplus, i, i - k - 1); - am[k - 1][i - 1] = -cfun; - } // i4119 loop - } // k4109 loop - // 4.2 FORM AMINV=UINV*LINV. - for (int k = 1; k <= n; k++) { - for (int i = 1; i <= n; i++) { - if (i < k) { - cfun = cdtp(cc0, am, i, k, k, n - k + 1); - am[i - 1][k -1] = cfun; - } - else { - cfun = cdtp(am[i - 1][k - 1], am, i, i + 1, k, n - i); - am[i - 1][k - 1] = cfun; - } - } // i4119 loop - } // k4209 loop - // 4.3 INTERCHANGE COLUMNS OF AMINV AS SPECIFIED BY V, BUT IN REVERSE - // ORDER. - for (int l = 1; l <= n; l++) { - int k = n - l + 1; - int kcol = (int)(v[k - 1]); - if (kcol != k) { - for (int i = 1; i <= n; i++) { - ctemp = am[i - 1][k - 1]; - am[i - 1][k - 1] = am[i - 1][kcol - 1]; - am[i - 1][kcol - 1] = ctemp; - } // i4319 loop - } - } // l4309 loop - delete[] v; + /* NDDMST FIRST DIMENSION OF AM AS DECLARED IN DIMENSION + * STATEMENT. + * N NUMBER OF ROWS IN AM. + * IER IS REPLACED BY 1 FOR SINGULARITY. + */ + double *v = new double[nddmst]; + std::complex<double> ctemp, cfun; + std::complex<double> cc0 = std::complex<double>(0.0, 0.0); + ier = 0; + int nminus = n - 1; + for (int i = 1; i <= n; i++) { + double sum = 0.0; + for (int j = 1; j <= n; j++) { + sum += ( + am[i - 1][j - 1].real() * am[i - 1][j - 1].real() + + am[i - 1][j - 1].imag() * am[i - 1][j - 1].imag() + ); + } // j1319 loop + v[i - 1] = 1.0 / sum; + } // i1309 loop + // 2. REPLACE AM BY TRIANGULAR MATRICES (L,U) WHERE AM=L*U. + // REPLACE L(I,I) BY 1/L(I,I), READY FOR SECTION 4. + // (ROW INTERCHANGES TAKE PLACE, AND THE INDICES OF THE PIVOTAL ROWS + // ARE PLACED IN V.) + /* >>> THERE APPEARS TO BE A BUG IN THE FOLLOWING LOOP <<< */ + for (int k = 1; k <= n; k++) { + int kplus = k + 1; + int kminus = k - 1; + int l = k; + double psqmax = 0.0; + for (int i = k; i <= n; i++) { + cfun = cdtp(-am[i - 1][k - 1], am, i, 1, k, kminus); + ctemp = -cfun; + am[i - 1][k - 1] = ctemp; + double psq = v[i - 1] * (ctemp.real() * ctemp.real() + ctemp.imag() * ctemp.imag()); + if (psq > psqmax) { + psqmax = psq; + l = i; + } + } // i2029 loop + if (l != k) { + for (int j = 1; j <= n; j++) { + ctemp = am[k - 1][j - 1]; + am[k - 1][j - 1] = am[l - 1][j - 1]; + am[l - 1][j - 1] = ctemp; + } // j2049 loop + v[l - 1] = v[k - 1]; + } + // label 2011 + v[k - 1] = 1.0 * l; + if (psqmax == 0.0) { + ier = 1; + delete[] v; + return; + } + ctemp = 1.0 / am[k - 1][k - 1]; + am[k - 1][k - 1] = ctemp; + if (kplus <= n) { + for (int j = kplus; j <= n; j++) { + cfun = cdtp(-am[k - 1][j - 1], am, k, 1, j, kminus); + am[k - 1][j - 1] = -ctemp * cfun; + } // j2059 loop + } + } // k2019 loop + // 4. REPLACE AM BY ITS INVERSE AMINV. + // 4.1 REPLACE L AND U BY THEIR INVERSE LINV AND UINV. + for (int k = 1; k <= nminus; k++) { + int kplus = k + 1; + for (int i = kplus; i <= n; i++) { + cfun = cdtp(cc0, am, i, k, k, i - k); + am[i - 1][k - 1] = -am[i - 1][i - 1] * cfun; + cfun = cdtp(am[k - 1][i - 1], am, k, kplus, i, i - k - 1); + am[k - 1][i - 1] = -cfun; + } // i4119 loop + } // k4109 loop + // 4.2 FORM AMINV=UINV*LINV. + for (int k = 1; k <= n; k++) { + for (int i = 1; i <= n; i++) { + if (i < k) { + cfun = cdtp(cc0, am, i, k, k, n - k + 1); + am[i - 1][k -1] = cfun; + } + else { + cfun = cdtp(am[i - 1][k - 1], am, i, i + 1, k, n - i); + am[i - 1][k - 1] = cfun; + } + } // i4119 loop + } // k4209 loop + // 4.3 INTERCHANGE COLUMNS OF AMINV AS SPECIFIED BY V, BUT IN REVERSE + // ORDER. + for (int l = 1; l <= n; l++) { + int k = n - l + 1; + int kcol = (int)(v[k - 1]); + if (kcol != k) { + for (int i = 1; i <= n; i++) { + ctemp = am[i - 1][k - 1]; + am[i - 1][k - 1] = am[i - 1][kcol - 1]; + am[i - 1][kcol - 1] = ctemp; + } // i4319 loop + } + } // l4309 loop + delete[] v; } /*! \brief C++ porting of MEXTC * - * \param vk: `double` - * \param exri: `double` + * \param vk: `double` Wave number. + * \param exri: `double` External medium refractive index. * \param fsac: Matrix of complex * \param cextlr: `double **` * \param cext: `double **` */ void mextc(double vk, double exri, std::complex<double> **fsac, double **cextlr, double **cext) { - double fa11r = fsac[0][0].real(); - double fa11i = fsac[0][0].imag(); - double fa21r = fsac[1][0].real(); - double fa21i = fsac[1][0].imag(); - double fa12r = fsac[0][1].real(); - double fa12i = fsac[0][1].imag(); - double fa22r = fsac[1][1].real(); - double fa22i = fsac[1][1].imag(); - cextlr[0][0] = fa11i * 2.0; - cextlr[0][1] = 0.0; - cextlr[0][2] = -fa12i; - cextlr[0][3] = -fa12r; - cextlr[1][0] = 0.0; - cextlr[1][1] = fa22i * 2.0; - cextlr[1][2] = -fa21i; - cextlr[1][3] = fa21r; - cextlr[2][0] = -fa21i * 2.0; - cextlr[2][1] = -fa12i * 2.0; - cextlr[2][2] = fa11i + fa22i; - cextlr[2][3] = fa22r - fa11r; - cextlr[3][0] = fa21r * 2.0; - cextlr[3][1] = -fa12r * 2.0; - cextlr[3][2] = fa11r - fa22r; - cextlr[3][3] = cextlr[2][2]; - cext[0][0] = cextlr[3][3]; - cext[1][1] = cextlr[3][3]; - cext[2][2] = cextlr[3][3]; - cext[2][3] = cextlr[2][3]; - cext[3][2] = cextlr[3][2]; - cext[3][3] = cextlr[3][3]; - cext[0][1] = fa11i - fa22i; - cext[0][2] = -fa12i - fa21i; - cext[0][3] = fa21r - fa12r; - cext[1][0] = cext[0][1]; - cext[1][2] = fa21i - fa12i; - cext[3][1] = fa12r + fa21r; - cext[1][3] = -cext[3][1]; - cext[2][0] = cext[0][2]; - cext[2][1] = -cext[1][2]; - cext[3][0] = cext[1][3]; - double ckm = vk / exri; - for (int i10 = 0; i10 < 4; i10++) { - for (int j10 = 0; j10 < 4; j10++) { - cextlr[i10][j10] *= ckm; - cext[i10][j10] *= ckm; - } - } + double fa11r = fsac[0][0].real(); + double fa11i = fsac[0][0].imag(); + double fa21r = fsac[1][0].real(); + double fa21i = fsac[1][0].imag(); + double fa12r = fsac[0][1].real(); + double fa12i = fsac[0][1].imag(); + double fa22r = fsac[1][1].real(); + double fa22i = fsac[1][1].imag(); + cextlr[0][0] = fa11i * 2.0; + cextlr[0][1] = 0.0; + cextlr[0][2] = -fa12i; + cextlr[0][3] = -fa12r; + cextlr[1][0] = 0.0; + cextlr[1][1] = fa22i * 2.0; + cextlr[1][2] = -fa21i; + cextlr[1][3] = fa21r; + cextlr[2][0] = -fa21i * 2.0; + cextlr[2][1] = -fa12i * 2.0; + cextlr[2][2] = fa11i + fa22i; + cextlr[2][3] = fa22r - fa11r; + cextlr[3][0] = fa21r * 2.0; + cextlr[3][1] = -fa12r * 2.0; + cextlr[3][2] = fa11r - fa22r; + cextlr[3][3] = cextlr[2][2]; + cext[0][0] = cextlr[3][3]; + cext[1][1] = cextlr[3][3]; + cext[2][2] = cextlr[3][3]; + cext[2][3] = cextlr[2][3]; + cext[3][2] = cextlr[3][2]; + cext[3][3] = cextlr[3][3]; + cext[0][1] = fa11i - fa22i; + cext[0][2] = -fa12i - fa21i; + cext[0][3] = fa21r - fa12r; + cext[1][0] = cext[0][1]; + cext[1][2] = fa21i - fa12i; + cext[3][1] = fa12r + fa21r; + cext[1][3] = -cext[3][1]; + cext[2][0] = cext[0][2]; + cext[2][1] = -cext[1][2]; + cext[3][0] = cext[1][3]; + double ckm = vk / exri; + for (int i10 = 0; i10 < 4; i10++) { + for (int j10 = 0; j10 < 4; j10++) { + cextlr[i10][j10] *= ckm; + cext[i10][j10] *= ckm; + } + } } /*! \brief C++ porting of PCROS * * This function is intended to evaluate the particle cross-section. QUESTIUON: correct? - * \param vk: `double` - * \param exri: `double` + * \param vk: `double` Wave number. + * \param exri: `double` External medium refractive index. * \param c1: `C1 *` * \param c1ao: `C1_AddOns *` * \param c4: `C4 *` */ void pcros(double vk, double exri, C1 *c1, C1_AddOns *c1ao, C4 *c4) { - const std::complex<double> cc0(0.0, 0.0); - std::complex<double> sump, sum1, sum2, sum3, sum4, am, amp, cc, csam; - const double exdc = exri * exri; - double ccs = 1.0 / (vk * vk); - double cccs = ccs / exdc; - csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); - const double pi4sq = 64.0 * acos(0.0) * acos(0.0); - double cfsq = 4.0 / (pi4sq *ccs * ccs); - const int nlemt = c4->nlem + c4->nlem; - int jpo = 2; - for (int ipo18 = 1; ipo18 <= 2; ipo18++) { - if (ipo18 == 2) jpo = 1; - int ipopt = ipo18 + 2; - int jpopt = jpo + 2; - double sum = 0.0; - sump = cc0; - sum1 = cc0; - sum2 = cc0; - sum3 = cc0; - sum4 = cc0; - for (int i12 = 1; i12 <= nlemt; i12++) { - int i = i12 - 1; - am = cc0; - amp = cc0; - for (int j10 = 1; j10 <= nlemt; j10++) { - int j = j10 - 1; - am += (c1ao->am0m[i][j] * c1->w[j][ipo18 - 1]); - amp += (c1ao->am0m[i][j] * c1->w[j][jpo - 1]); - } // j10 loop - sum += (dconjg(am) * am).real(); - sump += (dconjg(amp) * am); - sum1 += (dconjg(c1->w[i][ipo18 - 1]) * am); - sum2 += (dconjg(c1->w[i][jpo - 1]) * am); - sum3 += (c1->w[i][ipopt - 1] * am); - sum4 += (c1->w[i][jpopt - 1] * am); - } // i12 loop - c1ao->scsc[ipo18 - 1] = cccs * sum; - c1ao->scscp[ipo18 - 1] = cccs * sump; - c1ao->ecsc[ipo18 - 1] = -cccs * sum1.real(); - c1ao->ecscp[ipo18 - 1] = -cccs * sum2; - c1ao->fsac[ipo18 - 1][ipo18 - 1] = csam * sum1; - c1ao->fsac[jpo - 1][ipo18 - 1] = csam * sum2; - c1ao->sac[ipo18 - 1][ipo18 - 1] = csam * sum3; - c1ao->sac[jpo - 1][ipo18 - 1] = csam * sum4; - } // ipo18 loop - int i = 0; - for (int ipo1 = 1; ipo1 <= 2; ipo1++) { - for (int jpo1 = 1; jpo1 <= 2; jpo1++) { - cc = dconjg(c1ao->sac[jpo1 - 1][ipo1 - 1]); - for (int ipo2 = 1; ipo2 <= 2; ipo2 ++) { - for (int jpo2 = 1; jpo2 <= 2; jpo2++) { - c1ao->vint[i++] = c1ao->sac[jpo2 - 1][ipo2 - 1] * cc * cfsq; - } // jpo2 loop - } // ipo2 loop - } // jpo1 loop - } // ipo1 loop + const std::complex<double> cc0(0.0, 0.0); + std::complex<double> sump, sum1, sum2, sum3, sum4, am, amp, cc, csam; + const double exdc = exri * exri; + double ccs = 1.0 / (vk * vk); + double cccs = ccs / exdc; + csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); + const double pi4sq = 64.0 * acos(0.0) * acos(0.0); + double cfsq = 4.0 / (pi4sq *ccs * ccs); + const int nlemt = c4->nlem + c4->nlem; + int jpo = 2; + for (int ipo18 = 1; ipo18 <= 2; ipo18++) { + if (ipo18 == 2) jpo = 1; + int ipopt = ipo18 + 2; + int jpopt = jpo + 2; + double sum = 0.0; + sump = cc0; + sum1 = cc0; + sum2 = cc0; + sum3 = cc0; + sum4 = cc0; + for (int i12 = 1; i12 <= nlemt; i12++) { + int i = i12 - 1; + am = cc0; + amp = cc0; + for (int j10 = 1; j10 <= nlemt; j10++) { + int j = j10 - 1; + am += (c1ao->am0m[i][j] * c1->w[j][ipo18 - 1]); + amp += (c1ao->am0m[i][j] * c1->w[j][jpo - 1]); + } // j10 loop + sum += (dconjg(am) * am).real(); + sump += (dconjg(amp) * am); + sum1 += (dconjg(c1->w[i][ipo18 - 1]) * am); + sum2 += (dconjg(c1->w[i][jpo - 1]) * am); + sum3 += (c1->w[i][ipopt - 1] * am); + sum4 += (c1->w[i][jpopt - 1] * am); + } // i12 loop + c1ao->scsc[ipo18 - 1] = cccs * sum; + c1ao->scscp[ipo18 - 1] = cccs * sump; + c1ao->ecsc[ipo18 - 1] = -cccs * sum1.real(); + c1ao->ecscp[ipo18 - 1] = -cccs * sum2; + c1ao->fsac[ipo18 - 1][ipo18 - 1] = csam * sum1; + c1ao->fsac[jpo - 1][ipo18 - 1] = csam * sum2; + c1ao->sac[ipo18 - 1][ipo18 - 1] = csam * sum3; + c1ao->sac[jpo - 1][ipo18 - 1] = csam * sum4; + } // ipo18 loop + int i = 0; + for (int ipo1 = 1; ipo1 <= 2; ipo1++) { + for (int jpo1 = 1; jpo1 <= 2; jpo1++) { + cc = dconjg(c1ao->sac[jpo1 - 1][ipo1 - 1]); + for (int ipo2 = 1; ipo2 <= 2; ipo2 ++) { + for (int jpo2 = 1; jpo2 <= 2; jpo2++) { + c1ao->vint[i++] = c1ao->sac[jpo2 - 1][ipo2 - 1] * cc * cfsq; + } // jpo2 loop + } // ipo2 loop + } // jpo1 loop + } // ipo1 loop } /*! \brief C++ porting of PCRSM0 * - * \param vk: `double` - * \param exri: `double` - * \param inpol: `int` + * \param vk: `double` Wave number. + * \param exri: `double` External medium refractive index. + * \param inpol: `int` Incident field polarization type. * \param c1: `C1 *` * \param c1ao: `C1_AddOns *` * \param c4: `C4 *` */ void pcrsm0(double vk, double exri, int inpol, C1 *c1, C1_AddOns *c1ao, C4 *c4) { - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - std::complex<double> sum1, sum2, sum3, sum4, sumpd; - std::complex<double> sums1, sums2, sums3, sums4, csam; - double exdc = exri * exri; - double ccs = 4.0 * acos(0.0) / (vk * vk); - double cccs = ccs / exdc; - csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); - sum2 = cc0; - sum3 = cc0; - for (int i14 = 1; i14 <= c4->nlem; i14++) { // GPU portable? - int ie = i14 + c4->nlem; - sum2 += (c1ao->am0m[i14 - 1][i14 - 1] + c1ao->am0m[ie - 1][ie - 1]); - sum3 += (c1ao->am0m[i14 - 1][ie - 1] + c1ao->am0m[ie - 1][i14 - 1]); - } // i14 loop - double sumpi = 0.0; - sumpd = cc0; - int nlemt = c4->nlem + c4->nlem; - for (int i16 = 1; i16 <= nlemt; i16++) { - for (int j16 = 1; j16 <= c4->nlem; j16++) { - int je = j16 + c4->nlem; - double rvalue = ( - dconjg(c1ao->am0m[i16 - 1][j16 - 1]) * c1ao->am0m[i16 - 1][j16 - 1] - + dconjg(c1ao->am0m[i16 - 1][je - 1]) * c1ao->am0m[i16 - 1][je - 1] - ).real(); - sumpi += rvalue; - sumpd += ( - dconjg(c1ao->am0m[i16 - 1][j16 - 1]) * c1ao->am0m[i16 - 1][je - 1] - + dconjg(c1ao->am0m[i16 - 1][je - 1]) * c1ao->am0m[i16 - 1][j16 - 1] - ); - } // j16 loop - } // i16 loop - if (inpol == 0) { - sum1 = sum2; - sum4 = sum3 * uim; - sum3 = -sum4; - sums1 = sumpi; - sums2 = sumpi; - sums3 = sumpd * uim; - sums4 = -sums3; - } else { // label 18 - sum1 = sum2 + sum3; - sum2 = sum2 - sum3; - sum3 = cc0; - sum4 = cc0; - sums1 = sumpi - sumpd; - sums2 = sumpi + sumpd; - sums3 = cc0; - sums4 = cc0; - } - // label 20 - c1ao->ecscm[0] = -cccs * sum2.real(); - c1ao->ecscm[1] = -cccs * sum1.real(); - c1ao->ecscpm[0] = -cccs * sum4; - c1ao->ecscpm[1] = -cccs * sum3; - c1ao->fsacm[0][0] = csam * sum2; - c1ao->fsacm[1][0] = csam * sum4; - c1ao->fsacm[1][1] = csam * sum1; - c1ao->fsacm[0][1] = csam * sum3; - c1ao->scscm[0] = cccs * sums1.real(); - c1ao->scscm[1] = cccs * sums2.real(); - c1ao->scscpm[0] = cccs * sums3; - c1ao->scscpm[1] = cccs * sums4; + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + std::complex<double> sum1, sum2, sum3, sum4, sumpd; + std::complex<double> sums1, sums2, sums3, sums4, csam; + double exdc = exri * exri; + double ccs = 4.0 * acos(0.0) / (vk * vk); + double cccs = ccs / exdc; + csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); + sum2 = cc0; + sum3 = cc0; + for (int i14 = 1; i14 <= c4->nlem; i14++) { // GPU portable? + int ie = i14 + c4->nlem; + sum2 += (c1ao->am0m[i14 - 1][i14 - 1] + c1ao->am0m[ie - 1][ie - 1]); + sum3 += (c1ao->am0m[i14 - 1][ie - 1] + c1ao->am0m[ie - 1][i14 - 1]); + } // i14 loop + double sumpi = 0.0; + sumpd = cc0; + int nlemt = c4->nlem + c4->nlem; + for (int i16 = 1; i16 <= nlemt; i16++) { + for (int j16 = 1; j16 <= c4->nlem; j16++) { + int je = j16 + c4->nlem; + double rvalue = ( + dconjg(c1ao->am0m[i16 - 1][j16 - 1]) * c1ao->am0m[i16 - 1][j16 - 1] + + dconjg(c1ao->am0m[i16 - 1][je - 1]) * c1ao->am0m[i16 - 1][je - 1] + ).real(); + sumpi += rvalue; + sumpd += ( + dconjg(c1ao->am0m[i16 - 1][j16 - 1]) * c1ao->am0m[i16 - 1][je - 1] + + dconjg(c1ao->am0m[i16 - 1][je - 1]) * c1ao->am0m[i16 - 1][j16 - 1] + ); + } // j16 loop + } // i16 loop + if (inpol == 0) { + sum1 = sum2; + sum4 = sum3 * uim; + sum3 = -sum4; + sums1 = sumpi; + sums2 = sumpi; + sums3 = sumpd * uim; + sums4 = -sums3; + } else { // label 18 + sum1 = sum2 + sum3; + sum2 = sum2 - sum3; + sum3 = cc0; + sum4 = cc0; + sums1 = sumpi - sumpd; + sums2 = sumpi + sumpd; + sums3 = cc0; + sums4 = cc0; + } + // label 20 + c1ao->ecscm[0] = -cccs * sum2.real(); + c1ao->ecscm[1] = -cccs * sum1.real(); + c1ao->ecscpm[0] = -cccs * sum4; + c1ao->ecscpm[1] = -cccs * sum3; + c1ao->fsacm[0][0] = csam * sum2; + c1ao->fsacm[1][0] = csam * sum4; + c1ao->fsacm[1][1] = csam * sum1; + c1ao->fsacm[0][1] = csam * sum3; + c1ao->scscm[0] = cccs * sums1.real(); + c1ao->scscm[1] = cccs * sums2.real(); + c1ao->scscpm[0] = cccs * sums3; + c1ao->scscpm[1] = cccs * sums4; } /*! \brief C++ porting of POLAR * - * \param x: `double` - * \param y: `double` - * \param z: `double` - * \param r: `double &` - * \param cth: `double &` - * \param sth: `double &` - * \param cph: `double &` - * \param sph: `double &` + * \param x: `double` X-axis Cartesian coordinate. + * \param y: `double` Y-axis Cartesian coordinate. + * \param z: `double` Z-axis Cartesian coordinate. + * \param r: `double &` Reference to radial vector (output value). + * \param cth: `double &` Reference to the cosine of the azimuth coordinate (output value). + * \param sth: `double &` Reference to the sine of the azimuth coordinate (output value). + * \param cph: `double &` Reference to the cosine of the elevation coordinate (output value). + * \param sph: `double &` Reference to the sine of the elevation coordinate (output value). */ void polar( - double x, double y, double z, double &r, double &cth, double &sth, - double &cph, double &sph -) { - bool onx = (y == 0.0); - bool ony = (x == 0.0); - bool onz = (onx && ony); - double rho = 0.0; - if (!onz) { - if (!onx) { - if (!ony) { - rho = sqrt(x * x + y * y); - cph = x / rho; - sph = y / rho; - // goes to 25 - } else { // label 20 - rho = (y > 0.0) ? y : -y; - cph = 0.0; - sph = (y > 0.0) ? 1.0 : -1.0; - // goes to 25 - } - } else { // label 15 - rho = (x > 0.0) ? x : -x; - cph = (x > 0.0) ? 1.0 : -1.0; - sph = 0.0; - // goes to 25 - } - } else { // label 10 - cph = 1.0; - sph = 0.0; - // goes to 25 - } - // label 25 - if (z == 0.0) { - if (!onz) { - r = rho; - cth = 0.0; - sth = 1.0; - // returns - } else { // label 30 - r = 0.0; - cth = 1.0; - sth = 0.0; - // returns - } - } else { // label 35 - if (!onz) { - r = sqrt(rho * rho + z * z); - cth = z / r; - sth = rho / r; - // returns - } else { // label 40 - r = (z > 0.0) ? z : -z; - cth = (z > 0.0) ? 1.0 : -1.0; - sth = 0.0; - // returns - } - } + double x, double y, double z, double &r, double &cth, double &sth, + double &cph, double &sph + ) { + bool onx = (y == 0.0); + bool ony = (x == 0.0); + bool onz = (onx && ony); + double rho = 0.0; + if (!onz) { + if (!onx) { + if (!ony) { + rho = sqrt(x * x + y * y); + cph = x / rho; + sph = y / rho; + // goes to 25 + } else { // label 20 + rho = (y > 0.0) ? y : -y; + cph = 0.0; + sph = (y > 0.0) ? 1.0 : -1.0; + // goes to 25 + } + } else { // label 15 + rho = (x > 0.0) ? x : -x; + cph = (x > 0.0) ? 1.0 : -1.0; + sph = 0.0; + // goes to 25 + } + } else { // label 10 + cph = 1.0; + sph = 0.0; + // goes to 25 + } + // label 25 + if (z == 0.0) { + if (!onz) { + r = rho; + cth = 0.0; + sth = 1.0; + // returns + } else { // label 30 + r = 0.0; + cth = 1.0; + sth = 0.0; + // returns + } + } else { // label 35 + if (!onz) { + r = sqrt(rho * rho + z * z); + cth = z / r; + sth = rho / r; + // returns + } else { // label 40 + r = (z > 0.0) ? z : -z; + cth = (z > 0.0) ? 1.0 : -1.0; + sth = 0.0; + // returns + } + } } /*! \brief C++ porting of R3J000 @@ -1637,95 +1637,95 @@ void polar( * \param c6: `C6 *` Pointer to a C6 instance. */ void r3j000(int j2, int j3, C6 *c6) { - int jmx = j3 + j2; - if (jmx <= 0) { - c6->rac3j[0] = 1.0; - return; - } - int jmn = j3 - j2; - if (jmn < 0) jmn *= -1; - int njmo = (jmx - jmn) / 2; - int jf = jmx + jmx + 1; - int isn = 1; - if (jmn % 2 != 0) isn = -1; - if (njmo <= 0) { - double sj = 1.0 * jf; - double cnr = (1 / sqrt(sj)) * isn; - c6->rac3j[0] = cnr; - return; - } - double sjr = 1.0 * jf; - int jmxpos = (jmx + 1) * (jmx + 1); - int jmns = jmn * jmn; - int j1mo = jmx - 1; - int j1s = (j1mo + 1) * (j1mo + 1); - double cj = sqrt(1.0 * (jmxpos - j1s) * (j1s - jmns)); - int j1mos = j1mo * j1mo; - double cjmo = sqrt(1.0 * (jmxpos - j1mos) * (j1mos - jmns)); - if (njmo <= 1) { - c6->rac3j[0] = -cj / cjmo; - double sj = sjr + (c6->rac3j[0] * c6->rac3j[0]) * (jf - 4); - double cnr = (1.0 / sqrt(sj)) * isn; - c6->rac3j[1] = cnr; - c6->rac3j[0] *= cnr; - return; - } - int nj = njmo + 1; - int nmat = (nj + 1) / 2; - c6->rac3j[nj - 1] = 1.0; - c6->rac3j[njmo - 1] = -cj / cjmo; - if (nmat != njmo) { - int nbr = njmo - nmat; - for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { - int irr = nj - ibr45; - jf -= 4; - j1mo -= 2; - j1s = (j1mo + 1) * (j1mo + 1); - cj = sqrt(1.0 * (jmxpos - j1s) * (j1s - jmns)); - j1mos = j1mo * j1mo; - cjmo = sqrt(1.0 * (jmxpos - j1mos) * (j1mos - jmns)); - c6->rac3j[irr - 2] = c6->rac3j[irr - 1] * (-cj / cjmo); - sjr = sjr + (c6->rac3j[irr - 1] * c6->rac3j[irr - 1]) * jf; - } - } - // label 50 - double racmat = c6->rac3j[nmat - 1]; - sjr = sjr + (racmat * racmat) * (jf - 4); - c6->rac3j[0] = 1.0; - jf = jmn + jmn + 1; - double sjl = 1.0 * jf; - int j1pt = jmn + 2; - int j1pos = (j1pt - 1) * (j1pt - 1); - double cjpo = sqrt(1.0 * (jmxpos - j1pos) * (j1pos - jmns)); - int j1pts = j1pt * j1pt; - double cjpt = sqrt(1.0 * (jmxpos - j1pts) * (j1pts - jmns)); - c6->rac3j[1] = -cjpo / cjpt; - int nmatmo = nmat - 1; - if (nmatmo >= 2) { - for (int irl70 = 2; irl70 <= nmatmo; irl70++) { - jf += 4; - j1pt += 2; - j1pos = (j1pt - 1) * (j1pt - 1); - cjpo = sqrt(1.0 * (jmxpos - j1pos) * (j1pos - jmns)); - j1pts = j1pt * j1pt; - cjpt = sqrt(1.0 * (jmxpos - j1pts) * (j1pts - jmns)); - c6->rac3j[irl70] = c6->rac3j[irl70 - 1] * (-cjpo / cjpt); - sjl = sjl + (c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]) * jf; - } - } - // label 75 - double ratrac = racmat / c6->rac3j[nmat - 1]; - double rats = ratrac * ratrac; - double sj = sjr + sjl * rats; - c6->rac3j[nmat - 1] = racmat; - double cnr = (1.0 / sqrt(sj)) * isn; - for (int irr80 = nmat; irr80 <= nj; irr80++) { - c6->rac3j[irr80 - 1] *= cnr; - } - double cnl = cnr * ratrac; - for (int irl85 = 1; irl85 <= nmatmo; irl85++) { - c6->rac3j[irl85 - 1] *= cnl; - } + int jmx = j3 + j2; + if (jmx <= 0) { + c6->rac3j[0] = 1.0; + return; + } + int jmn = j3 - j2; + if (jmn < 0) jmn *= -1; + int njmo = (jmx - jmn) / 2; + int jf = jmx + jmx + 1; + int isn = 1; + if (jmn % 2 != 0) isn = -1; + if (njmo <= 0) { + double sj = 1.0 * jf; + double cnr = (1 / sqrt(sj)) * isn; + c6->rac3j[0] = cnr; + return; + } + double sjr = 1.0 * jf; + int jmxpos = (jmx + 1) * (jmx + 1); + int jmns = jmn * jmn; + int j1mo = jmx - 1; + int j1s = (j1mo + 1) * (j1mo + 1); + double cj = sqrt(1.0 * (jmxpos - j1s) * (j1s - jmns)); + int j1mos = j1mo * j1mo; + double cjmo = sqrt(1.0 * (jmxpos - j1mos) * (j1mos - jmns)); + if (njmo <= 1) { + c6->rac3j[0] = -cj / cjmo; + double sj = sjr + (c6->rac3j[0] * c6->rac3j[0]) * (jf - 4); + double cnr = (1.0 / sqrt(sj)) * isn; + c6->rac3j[1] = cnr; + c6->rac3j[0] *= cnr; + return; + } + int nj = njmo + 1; + int nmat = (nj + 1) / 2; + c6->rac3j[nj - 1] = 1.0; + c6->rac3j[njmo - 1] = -cj / cjmo; + if (nmat != njmo) { + int nbr = njmo - nmat; + for (int ibr45 = 1; ibr45 <= nbr; ibr45++) { + int irr = nj - ibr45; + jf -= 4; + j1mo -= 2; + j1s = (j1mo + 1) * (j1mo + 1); + cj = sqrt(1.0 * (jmxpos - j1s) * (j1s - jmns)); + j1mos = j1mo * j1mo; + cjmo = sqrt(1.0 * (jmxpos - j1mos) * (j1mos - jmns)); + c6->rac3j[irr - 2] = c6->rac3j[irr - 1] * (-cj / cjmo); + sjr = sjr + (c6->rac3j[irr - 1] * c6->rac3j[irr - 1]) * jf; + } + } + // label 50 + double racmat = c6->rac3j[nmat - 1]; + sjr = sjr + (racmat * racmat) * (jf - 4); + c6->rac3j[0] = 1.0; + jf = jmn + jmn + 1; + double sjl = 1.0 * jf; + int j1pt = jmn + 2; + int j1pos = (j1pt - 1) * (j1pt - 1); + double cjpo = sqrt(1.0 * (jmxpos - j1pos) * (j1pos - jmns)); + int j1pts = j1pt * j1pt; + double cjpt = sqrt(1.0 * (jmxpos - j1pts) * (j1pts - jmns)); + c6->rac3j[1] = -cjpo / cjpt; + int nmatmo = nmat - 1; + if (nmatmo >= 2) { + for (int irl70 = 2; irl70 <= nmatmo; irl70++) { + jf += 4; + j1pt += 2; + j1pos = (j1pt - 1) * (j1pt - 1); + cjpo = sqrt(1.0 * (jmxpos - j1pos) * (j1pos - jmns)); + j1pts = j1pt * j1pt; + cjpt = sqrt(1.0 * (jmxpos - j1pts) * (j1pts - jmns)); + c6->rac3j[irl70] = c6->rac3j[irl70 - 1] * (-cjpo / cjpt); + sjl = sjl + (c6->rac3j[irl70 - 1] * c6->rac3j[irl70 - 1]) * jf; + } + } + // label 75 + double ratrac = racmat / c6->rac3j[nmat - 1]; + double rats = ratrac * ratrac; + double sj = sjr + sjl * rats; + c6->rac3j[nmat - 1] = racmat; + double cnr = (1.0 / sqrt(sj)) * isn; + for (int irr80 = nmat; irr80 <= nj; irr80++) { + c6->rac3j[irr80 - 1] *= cnr; + } + double cnl = cnr * ratrac; + for (int irl85 = 1; irl85 <= nmatmo; irl85++) { + c6->rac3j[irl85 - 1] *= cnl; + } } /*! \brief C++ porting of RABA @@ -1739,134 +1739,134 @@ void r3j000(int j2, int j3, C6 *c6) { * \param tqcps: Matrix of complex. */ void raba( - int le, std::complex<double> **am0m, std::complex<double> **w, double **tqce, - std::complex<double> **tqcpe, double **tqcs, std::complex<double> **tqcps -) { - std::complex<double> **a, **ctqce, **ctqcs; - std::complex<double> acw, acwp, aca, acap, c1, c2, c3; - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - const double sq2i = 1.0 / sqrt(2.0); - int nlem = le * (le + 2); - const int nlemt = nlem + nlem; - a = new std::complex<double>*[nlemt]; - ctqce = new std::complex<double>*[2]; - ctqcs = new std::complex<double>*[2]; - for (int ai = 0; ai < nlemt; ai++) a[ai] = new std::complex<double>[2](); - for (int ci = 0; ci < 2; ci++) { - ctqce[ci] = new std::complex<double>[3](); - ctqcs[ci] = new std::complex<double>[3](); + int le, std::complex<double> **am0m, std::complex<double> **w, double **tqce, + std::complex<double> **tqcpe, double **tqcs, std::complex<double> **tqcps + ) { + std::complex<double> **a, **ctqce, **ctqcs; + std::complex<double> acw, acwp, aca, acap, c1, c2, c3; + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + const double sq2i = 1.0 / sqrt(2.0); + int nlem = le * (le + 2); + const int nlemt = nlem + nlem; + a = new std::complex<double>*[nlemt]; + ctqce = new std::complex<double>*[2]; + ctqcs = new std::complex<double>*[2]; + for (int ai = 0; ai < nlemt; ai++) a[ai] = new std::complex<double>[2](); + for (int ci = 0; ci < 2; ci++) { + ctqce[ci] = new std::complex<double>[3](); + ctqcs[ci] = new std::complex<double>[3](); + } + for (int i20 = 1; i20 <= nlemt; i20++) { + int i = i20 - 1; + c1 = cc0; + c2 = cc0; + for (int j10 = 1; j10 <= nlemt; j10++) { + int j = j10 - 1; + c1 += (am0m[i][j] * w[j][0]); + c2 += (am0m[i][j] * w[j][1]); + } // j10 loop + a[i][0] = c1; + a[i][1] = c2; + } //i20 loop + int jpo = 2; + for (int ipo70 = 1; ipo70 <= 2; ipo70++) { + if (ipo70 == 2) jpo = 1; + int ipo = ipo70 - 1; + ctqce[ipo][0] = cc0; + ctqce[ipo][1] = cc0; + ctqce[ipo][2] = cc0; + tqcpe[ipo][0] = cc0; + tqcpe[ipo][1] = cc0; + tqcpe[ipo][2] = cc0; + ctqcs[ipo][0] = cc0; + ctqcs[ipo][1] = cc0; + ctqcs[ipo][2] = cc0; + tqcps[ipo][0] = cc0; + tqcps[ipo][1] = cc0; + tqcps[ipo][2] = cc0; + for (int l60 = 1; l60 <= le; l60 ++) { + int lpo = l60 + 1; + int il = l60 * lpo; + int ltpo = l60 + lpo; + for (int im60 = 1; im60 <= ltpo; im60++) { + int m = im60 - lpo; + int i = m + il; + int ie = i + nlem; + int mmmu = m + 1; + int mmmmu = (mmmu > 0) ? mmmu : -mmmu; + double rmu = 0.0; + if (mmmmu <= l60) { + int immu = mmmu + il; + int immue = immu + nlem; + rmu = -sqrt(1.0 * (l60 + mmmu) * (l60 - m)) * sq2i; + acw = dconjg(a[i - 1][ipo]) * w[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[immue - 1][ipo]; + acwp = dconjg(a[i - 1][ipo]) * w[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[immue - 1][jpo - 1]; + aca = dconjg(a[i - 1][ipo]) * a[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[immue - 1][ipo]; + acap = dconjg(a[i - 1][ipo]) * a[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[immue - 1][jpo - 1]; + ctqce[ipo][0] += (acw * rmu); + tqcpe[ipo][0] += (acwp * rmu); + ctqcs[ipo][0] += (aca * rmu); + tqcps[ipo][0] += (acap * rmu); } - for (int i20 = 1; i20 <= nlemt; i20++) { - int i = i20 - 1; - c1 = cc0; - c2 = cc0; - for (int j10 = 1; j10 <= nlemt; j10++) { - int j = j10 - 1; - c1 += (am0m[i][j] * w[j][0]); - c2 += (am0m[i][j] * w[j][1]); - } // j10 loop - a[i][0] = c1; - a[i][1] = c2; - } //i20 loop - int jpo = 2; - for (int ipo70 = 1; ipo70 <= 2; ipo70++) { - if (ipo70 == 2) jpo = 1; - int ipo = ipo70 - 1; - ctqce[ipo][0] = cc0; - ctqce[ipo][1] = cc0; - ctqce[ipo][2] = cc0; - tqcpe[ipo][0] = cc0; - tqcpe[ipo][1] = cc0; - tqcpe[ipo][2] = cc0; - ctqcs[ipo][0] = cc0; - ctqcs[ipo][1] = cc0; - ctqcs[ipo][2] = cc0; - tqcps[ipo][0] = cc0; - tqcps[ipo][1] = cc0; - tqcps[ipo][2] = cc0; - for (int l60 = 1; l60 <= le; l60 ++) { - int lpo = l60 + 1; - int il = l60 * lpo; - int ltpo = l60 + lpo; - for (int im60 = 1; im60 <= ltpo; im60++) { - int m = im60 - lpo; - int i = m + il; - int ie = i + nlem; - int mmmu = m + 1; - int mmmmu = (mmmu > 0) ? mmmu : -mmmu; - double rmu = 0.0; - if (mmmmu <= l60) { - int immu = mmmu + il; - int immue = immu + nlem; - rmu = -sqrt(1.0 * (l60 + mmmu) * (l60 - m)) * sq2i; - acw = dconjg(a[i - 1][ipo]) * w[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[immue - 1][ipo]; - acwp = dconjg(a[i - 1][ipo]) * w[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[immue - 1][jpo - 1]; - aca = dconjg(a[i - 1][ipo]) * a[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[immue - 1][ipo]; - acap = dconjg(a[i - 1][ipo]) * a[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[immue - 1][jpo - 1]; - ctqce[ipo][0] += (acw * rmu); - tqcpe[ipo][0] += (acwp * rmu); - ctqcs[ipo][0] += (aca * rmu); - tqcps[ipo][0] += (acap * rmu); - } - // label 30 - rmu = -1.0 * m; - acw = dconjg(a[i - 1][ipo]) * w[i - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[ie - 1][ipo]; - acwp = dconjg(a[i - 1][ipo]) * w[i - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[ie - 1][jpo - 1]; - aca = dconjg(a[i - 1][ipo]) * a[i - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[ie - 1][ipo]; - acap = dconjg(a[i - 1][ipo]) * a[i - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[ie - 1][jpo - 1]; - ctqce[ipo][1] += (acw * rmu); - tqcpe[ipo][1] += (acwp * rmu); - ctqcs[ipo][1] += (aca * rmu); - tqcps[ipo][1] += (acap * rmu); - mmmu = m - 1; - mmmmu = (mmmu > 0) ? mmmu : -mmmu; - if (mmmmu <= l60) { - int immu = mmmu + il; - int immue = immu + nlem; - rmu = sqrt(1.0 * (l60 - mmmu) * (l60 + m)) * sq2i; - acw = dconjg(a[i - 1][ipo]) * w[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[immue - 1][ipo]; - acwp = dconjg(a[i - 1][ipo]) * w[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[immue - 1][jpo - 1]; - aca = dconjg(a[i - 1][ipo]) * a[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[immue - 1][ipo]; - acap = dconjg(a[i - 1][ipo]) * a[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[immue - 1][jpo - 1]; - ctqce[ipo][2] += (acw * rmu); - tqcpe[ipo][2] += (acwp * rmu); - ctqcs[ipo][2] += (aca * rmu); - tqcps[ipo][2] += (acap * rmu); - } // ends im60 loop - } // im60 loop - } // l60 loop - } // ipo70 loop - for (int ipo78 = 1; ipo78 <= 2; ipo78++) { - int ipo = ipo78 - 1; - tqce[ipo][0] = (ctqce[ipo][0] - ctqce[ipo][2]).real() * sq2i; - tqce[ipo][1] = ((ctqce[ipo][0] + ctqce[ipo][2]) * uim).real() * sq2i; - tqce[ipo][2] = ctqce[ipo][1].real(); - c1 = tqcpe[ipo][0]; - c2 = tqcpe[ipo][1]; - c3 = tqcpe[ipo][2]; - tqcpe[ipo][0] = (c1 - c3) * sq2i; - tqcpe[ipo][1] = (c1 + c3) * (uim * sq2i); - tqcpe[ipo][2] = c2; - tqcs[ipo][0] = -sq2i * (ctqcs[ipo][0] - ctqcs[ipo][2]).real(); - tqcs[ipo][1] = -sq2i * ((ctqcs[ipo][0] + ctqcs[ipo][2]) * uim).real(); - tqcs[ipo][2] = -1.0 * ctqcs[ipo][1].real(); - c1 = tqcps[ipo][0]; - c2 = tqcps[ipo][1]; - c3 = tqcps[ipo][2]; - tqcps[ipo][0] = -(c1 - c3) * sq2i; - tqcps[ipo][1] = -(c1 + c3) * (uim * sq2i); - tqcps[ipo][2] = -c2; - } // ipo78 loop - // Clean memory - for (int ai = 0; ai < nlemt; ai++) delete[] a[ai]; - for (int ci = 0; ci < 2; ci++) { - delete[] ctqce[ci]; - delete[] ctqcs[ci]; - } - delete[] a; - delete[] ctqce; - delete[] ctqcs; + // label 30 + rmu = -1.0 * m; + acw = dconjg(a[i - 1][ipo]) * w[i - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[ie - 1][ipo]; + acwp = dconjg(a[i - 1][ipo]) * w[i - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[ie - 1][jpo - 1]; + aca = dconjg(a[i - 1][ipo]) * a[i - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[ie - 1][ipo]; + acap = dconjg(a[i - 1][ipo]) * a[i - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[ie - 1][jpo - 1]; + ctqce[ipo][1] += (acw * rmu); + tqcpe[ipo][1] += (acwp * rmu); + ctqcs[ipo][1] += (aca * rmu); + tqcps[ipo][1] += (acap * rmu); + mmmu = m - 1; + mmmmu = (mmmu > 0) ? mmmu : -mmmu; + if (mmmmu <= l60) { + int immu = mmmu + il; + int immue = immu + nlem; + rmu = sqrt(1.0 * (l60 - mmmu) * (l60 + m)) * sq2i; + acw = dconjg(a[i - 1][ipo]) * w[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * w[immue - 1][ipo]; + acwp = dconjg(a[i - 1][ipo]) * w[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * w[immue - 1][jpo - 1]; + aca = dconjg(a[i - 1][ipo]) * a[immu - 1][ipo] + dconjg(a[ie - 1][ipo]) * a[immue - 1][ipo]; + acap = dconjg(a[i - 1][ipo]) * a[immu - 1][jpo - 1] + dconjg(a[ie - 1][ipo]) * a[immue - 1][jpo - 1]; + ctqce[ipo][2] += (acw * rmu); + tqcpe[ipo][2] += (acwp * rmu); + ctqcs[ipo][2] += (aca * rmu); + tqcps[ipo][2] += (acap * rmu); + } // ends im60 loop + } // im60 loop + } // l60 loop + } // ipo70 loop + for (int ipo78 = 1; ipo78 <= 2; ipo78++) { + int ipo = ipo78 - 1; + tqce[ipo][0] = (ctqce[ipo][0] - ctqce[ipo][2]).real() * sq2i; + tqce[ipo][1] = ((ctqce[ipo][0] + ctqce[ipo][2]) * uim).real() * sq2i; + tqce[ipo][2] = ctqce[ipo][1].real(); + c1 = tqcpe[ipo][0]; + c2 = tqcpe[ipo][1]; + c3 = tqcpe[ipo][2]; + tqcpe[ipo][0] = (c1 - c3) * sq2i; + tqcpe[ipo][1] = (c1 + c3) * (uim * sq2i); + tqcpe[ipo][2] = c2; + tqcs[ipo][0] = -sq2i * (ctqcs[ipo][0] - ctqcs[ipo][2]).real(); + tqcs[ipo][1] = -sq2i * ((ctqcs[ipo][0] + ctqcs[ipo][2]) * uim).real(); + tqcs[ipo][2] = -1.0 * ctqcs[ipo][1].real(); + c1 = tqcps[ipo][0]; + c2 = tqcps[ipo][1]; + c3 = tqcps[ipo][2]; + tqcps[ipo][0] = -(c1 - c3) * sq2i; + tqcps[ipo][1] = -(c1 + c3) * (uim * sq2i); + tqcps[ipo][2] = -c2; + } // ipo78 loop + // Clean memory + for (int ai = 0; ai < nlemt; ai++) delete[] a[ai]; + for (int ci = 0; ci < 2; ci++) { + delete[] ctqce[ci]; + delete[] ctqcs[ci]; + } + delete[] a; + delete[] ctqce; + delete[] ctqcs; } /*! \brief C++ porting of RFTR @@ -1887,81 +1887,81 @@ void raba( * \param fz: `double &` */ void rftr( - double *u, double *up, double *un, double *gapv, double extins, double scatts, - double &rapr, double &cosav, double &fp, double &fn, double &fk, double &fx, - double &fy, double &fz -) { - fk = u[0] * gapv[0] + u[1] * gapv[1] + u[2] * gapv[2]; - rapr = extins - fk; - cosav = fk / scatts; - fp = -(up[0] * gapv[0] + up[1] * gapv[1] + up[2] * gapv[2]); - fn = -(un[0] * gapv[0] + un[1] * gapv[1] + un[2] * gapv[2]); - fk = rapr; - fx = u[0] * extins - gapv[0]; - fy = u[1] * extins - gapv[1]; - fz = u[2] * extins - gapv[2]; + double *u, double *up, double *un, double *gapv, double extins, double scatts, + double &rapr, double &cosav, double &fp, double &fn, double &fk, double &fx, + double &fy, double &fz + ) { + fk = u[0] * gapv[0] + u[1] * gapv[1] + u[2] * gapv[2]; + rapr = extins - fk; + cosav = fk / scatts; + fp = -(up[0] * gapv[0] + up[1] * gapv[1] + up[2] * gapv[2]); + fn = -(un[0] * gapv[0] + un[1] * gapv[1] + un[2] * gapv[2]); + fk = rapr; + fx = u[0] * extins - gapv[0]; + fy = u[1] * extins - gapv[1]; + fz = u[2] * extins - gapv[2]; } /*! \brief C++ porting of SCR0 * - * \param vk: `double` QUESTION: definition? - * \param exri: `double` External medium refractive index. QUESTION: correct? + * \param vk: `double` Wave number + * \param exri: `double` External medium refractive index. * \param c1: `C1 *` Pointer to a C1 instance. * \param c1ao: `C1_AddOns *` Pointer to C1_AddOns instance. * \param c3: `C3 *` Pointer to a C3 instance. * \param c4: `C4 *` Pointer to a C4 structure. */ void scr0(double vk, double exri, C1 *c1, C1_AddOns *c1ao, C3 *c3, C4 * c4) { - const std::complex<double> cc0(0.0, 0.0); - double exdc = exri * exri; - double ccs = 4.0 * acos(0.0) / (vk * vk); - double cccs = ccs / exdc; - std::complex<double> sum21, rm, re, csam; - csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); - //double scs = 0.0, ecs = 0.0, acs = 0.0; - c3->scs = 0.0; - c3->ecs = 0.0; - c3->acs = 0.0; - c3->tfsas = cc0; - for (int i14 = 1; i14 <= c4->nsph; i14++) { - int iogi = c1->iog[i14 - 1]; - if (iogi >= i14) { - double sums = 0.0; - sum21 = cc0; - for (int l10 = 1; l10 <= c4->li; l10++) { - double fl = 1.0 * (l10 + l10 + 1); - rm = 1.0 / c1->rmi[l10 - 1][i14 - 1]; - re = 1.0 / c1->rei[l10 - 1][i14 - 1]; - double rvalue = (dconjg(rm) * rm + dconjg(re) * re).real() * fl; - sums += rvalue; - sum21 += ((rm + re) * fl); - } // l10 loop - sum21 *= -1.0; - double scasec = cccs * sums; - double extsec = -cccs * sum21.real(); - double abssec = extsec - scasec; - c1->sscs[i14 - 1] = scasec; - c1->sexs[i14 - 1] = extsec; - c1->sabs[i14 - 1] = abssec; - double gcss = c1->gcsv[i14 - 1]; - c1->sqscs[i14 - 1] = scasec / gcss; - c1->sqexs[i14 - 1] = extsec / gcss; - c1->sqabs[i14 - 1] = abssec / gcss; - c1->fsas[i14 - 1] = sum21 * csam; - } - // label 12 - c3->scs += c1->sscs[iogi - 1]; - c3->ecs += c1->sexs[iogi - 1]; - c3->acs += c1->sabs[iogi - 1]; - c3->tfsas += c1->fsas[iogi - 1]; - } // i14 loop + const std::complex<double> cc0(0.0, 0.0); + double exdc = exri * exri; + double ccs = 4.0 * acos(0.0) / (vk * vk); + double cccs = ccs / exdc; + std::complex<double> sum21, rm, re, csam; + csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); + //double scs = 0.0, ecs = 0.0, acs = 0.0; + c3->scs = 0.0; + c3->ecs = 0.0; + c3->acs = 0.0; + c3->tfsas = cc0; + for (int i14 = 1; i14 <= c4->nsph; i14++) { + int iogi = c1->iog[i14 - 1]; + if (iogi >= i14) { + double sums = 0.0; + sum21 = cc0; + for (int l10 = 1; l10 <= c4->li; l10++) { + double fl = 1.0 * (l10 + l10 + 1); + rm = 1.0 / c1->rmi[l10 - 1][i14 - 1]; + re = 1.0 / c1->rei[l10 - 1][i14 - 1]; + double rvalue = (dconjg(rm) * rm + dconjg(re) * re).real() * fl; + sums += rvalue; + sum21 += ((rm + re) * fl); + } // l10 loop + sum21 *= -1.0; + double scasec = cccs * sums; + double extsec = -cccs * sum21.real(); + double abssec = extsec - scasec; + c1->sscs[i14 - 1] = scasec; + c1->sexs[i14 - 1] = extsec; + c1->sabs[i14 - 1] = abssec; + double gcss = c1->gcsv[i14 - 1]; + c1->sqscs[i14 - 1] = scasec / gcss; + c1->sqexs[i14 - 1] = extsec / gcss; + c1->sqabs[i14 - 1] = abssec / gcss; + c1->fsas[i14 - 1] = sum21 * csam; + } + // label 12 + c3->scs += c1->sscs[iogi - 1]; + c3->ecs += c1->sexs[iogi - 1]; + c3->acs += c1->sabs[iogi - 1]; + c3->tfsas += c1->fsas[iogi - 1]; + } // i14 loop } /*! \brief C++ porting of SCR2 * - * \param vk: `double` QUESTION: definition? + * \param vk: `double` Wave number. * \param vkarg: `double` QUESTION: definition? - * \param exri: `double` External medium refractive index + * \param exri: `double` External medium refractive index. * \param duk: `double *` QUESTION: definition? * \param c1: `C1 *` Pointer to a C1 instance. * \param c1ao: `C1_AddOns *` Pointer to C1_AddOns instance. @@ -1969,85 +1969,85 @@ void scr0(double vk, double exri, C1 *c1, C1_AddOns *c1ao, C3 *c3, C4 * c4) { * \param c4: `C4 *` Pointer to a C4 structure. */ void scr2( - double vk, double vkarg, double exri, double *duk, C1 *c1, C1_AddOns *c1ao, - C3 *c3, C4 *c4) { - const std::complex<double> cc0(0.0, 0.0); - const std::complex<double> uim(0.0, 1.0); - std::complex<double> s11, s21, s12, s22, rm, re, csam, cph, phas, cc; - double ccs = 1.0 / (vk * vk); - csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); - const double pi4sq = 64.0 * acos(0.0) * acos(0.0); - double cfsq = 4.0 / (pi4sq * ccs * ccs); - cph = uim * exri * vkarg; - int ls = (c4->li < c4->le) ? c4->li : c4->le; - c3->tsas[0][0] = cc0; - c3->tsas[1][0] = cc0; - c3->tsas[0][1] = cc0; - c3->tsas[1][1] = cc0; - for (int i14 = 1; i14 <= c4->nsph; i14++) { - int i = i14 - 1; - int iogi = c1->iog[i14 - 1]; - if (iogi >= i14) { - int k = 0; - s11 = cc0; - s21 = cc0; - s12 = cc0; - s22 = cc0; - for (int l10 = 1; l10 <= ls; l10++) { - int l = l10 - 1; - rm = 1.0 / c1->rmi[l][i]; - re = 1.0 / c1->rei[l][i]; - int ltpo = l10 + l10 + 1; - for (int im10 = 1; im10 <= ltpo; im10++) { - k++; - int ke = k + c4->nlem; - s11 -= (c1->w[k - 1][2] * c1->w[k - 1][0] * rm + c1->w[ke - 1][2] * c1->w[ke - 1][0] * re); - s21 -= (c1->w[k - 1][3] * c1->w[k - 1][0] * rm + c1->w[ke - 1][3] * c1->w[ke - 1][0] * re); - s12 -= (c1->w[k - 1][2] * c1->w[k - 1][1] * rm + c1->w[ke - 1][2] * c1->w[ke - 1][1] * re); - s22 -= (c1->w[k - 1][3] * c1->w[k - 1][1] * rm + c1->w[ke - 1][3] * c1->w[ke - 1][1] * re); - } // im10 loop - } // l10 loop - c1->sas[i][0][0] = s11 * csam; - c1->sas[i][1][0] = s21 * csam; - c1->sas[i][0][1] = s12 * csam; - c1->sas[i][1][1] = s22 * csam; - } - // label 12 - phas = exp(cph * (duk[0] * c1->rxx[i] + duk[1] * c1->ryy[i] + duk[2] * c1->rzz[i])); - c3->tsas[0][0] += (c1->sas[iogi - 1][0][0] * phas); - c3->tsas[1][0] += (c1->sas[iogi - 1][1][0] * phas); - c3->tsas[0][1] += (c1->sas[iogi - 1][0][1] * phas); - c3->tsas[1][1] += (c1->sas[iogi - 1][1][1] * phas); - } // i14 loop - for (int i24 = 1; i24 <= c4->nsph; i24++) { - int iogi = c1->iog[i24 - 1]; - if (iogi >= i24) { - int j = 0; - for (int ipo1 = 1; ipo1 <=2; ipo1++) { - for (int jpo1 = 1; jpo1 <= 2; jpo1++) { - cc = dconjg(c1->sas[i24 - 1][jpo1 - 1][ipo1 - 1]); - for (int ipo2 = 1; ipo2 <= 2; ipo2++) { - for (int jpo2 = 1; jpo2 <= 2; jpo2++) { - j++; - c1ao->vints[i24 - 1][j - 1] = c1->sas[i24 - 1][jpo2 - 1][ipo2 - 1] * cc * cfsq; - } // jpo2 loop - } // ipo2 loop - } // jpo1 loop - } // ipo1 loop - } - } // i24 loop - int j = 0; - for (int ipo1 = 1; ipo1 <=2; ipo1++) { - for (int jpo1 = 1; jpo1 <= 2; jpo1++) { - cc = dconjg(c3->tsas[jpo1 - 1][ipo1 - 1]); - for (int ipo2 = 1; ipo2 <= 2; ipo2++) { - for (int jpo2 = 1; jpo2 <= 2; jpo2++) { - j++; - c1ao->vintt[j - 1] = c3->tsas[jpo2 - 1][ipo2 - 1] * cc * cfsq; - } // jpo2 loop - } // ipo2 loop - } // jpo1 loop - } // ipo1 loop + double vk, double vkarg, double exri, double *duk, C1 *c1, C1_AddOns *c1ao, + C3 *c3, C4 *c4) { + const std::complex<double> cc0(0.0, 0.0); + const std::complex<double> uim(0.0, 1.0); + std::complex<double> s11, s21, s12, s22, rm, re, csam, cph, phas, cc; + double ccs = 1.0 / (vk * vk); + csam = -(ccs / (exri * vk)) * std::complex<double>(0.0, 0.5); + const double pi4sq = 64.0 * acos(0.0) * acos(0.0); + double cfsq = 4.0 / (pi4sq * ccs * ccs); + cph = uim * exri * vkarg; + int ls = (c4->li < c4->le) ? c4->li : c4->le; + c3->tsas[0][0] = cc0; + c3->tsas[1][0] = cc0; + c3->tsas[0][1] = cc0; + c3->tsas[1][1] = cc0; + for (int i14 = 1; i14 <= c4->nsph; i14++) { + int i = i14 - 1; + int iogi = c1->iog[i14 - 1]; + if (iogi >= i14) { + int k = 0; + s11 = cc0; + s21 = cc0; + s12 = cc0; + s22 = cc0; + for (int l10 = 1; l10 <= ls; l10++) { + int l = l10 - 1; + rm = 1.0 / c1->rmi[l][i]; + re = 1.0 / c1->rei[l][i]; + int ltpo = l10 + l10 + 1; + for (int im10 = 1; im10 <= ltpo; im10++) { + k++; + int ke = k + c4->nlem; + s11 -= (c1->w[k - 1][2] * c1->w[k - 1][0] * rm + c1->w[ke - 1][2] * c1->w[ke - 1][0] * re); + s21 -= (c1->w[k - 1][3] * c1->w[k - 1][0] * rm + c1->w[ke - 1][3] * c1->w[ke - 1][0] * re); + s12 -= (c1->w[k - 1][2] * c1->w[k - 1][1] * rm + c1->w[ke - 1][2] * c1->w[ke - 1][1] * re); + s22 -= (c1->w[k - 1][3] * c1->w[k - 1][1] * rm + c1->w[ke - 1][3] * c1->w[ke - 1][1] * re); + } // im10 loop + } // l10 loop + c1->sas[i][0][0] = s11 * csam; + c1->sas[i][1][0] = s21 * csam; + c1->sas[i][0][1] = s12 * csam; + c1->sas[i][1][1] = s22 * csam; + } + // label 12 + phas = exp(cph * (duk[0] * c1->rxx[i] + duk[1] * c1->ryy[i] + duk[2] * c1->rzz[i])); + c3->tsas[0][0] += (c1->sas[iogi - 1][0][0] * phas); + c3->tsas[1][0] += (c1->sas[iogi - 1][1][0] * phas); + c3->tsas[0][1] += (c1->sas[iogi - 1][0][1] * phas); + c3->tsas[1][1] += (c1->sas[iogi - 1][1][1] * phas); + } // i14 loop + for (int i24 = 1; i24 <= c4->nsph; i24++) { + int iogi = c1->iog[i24 - 1]; + if (iogi >= i24) { + int j = 0; + for (int ipo1 = 1; ipo1 <=2; ipo1++) { + for (int jpo1 = 1; jpo1 <= 2; jpo1++) { + cc = dconjg(c1->sas[i24 - 1][jpo1 - 1][ipo1 - 1]); + for (int ipo2 = 1; ipo2 <= 2; ipo2++) { + for (int jpo2 = 1; jpo2 <= 2; jpo2++) { + j++; + c1ao->vints[i24 - 1][j - 1] = c1->sas[i24 - 1][jpo2 - 1][ipo2 - 1] * cc * cfsq; + } // jpo2 loop + } // ipo2 loop + } // jpo1 loop + } // ipo1 loop + } + } // i24 loop + int j = 0; + for (int ipo1 = 1; ipo1 <=2; ipo1++) { + for (int jpo1 = 1; jpo1 <= 2; jpo1++) { + cc = dconjg(c3->tsas[jpo1 - 1][ipo1 - 1]); + for (int ipo2 = 1; ipo2 <= 2; ipo2++) { + for (int jpo2 = 1; jpo2 <= 2; jpo2++) { + j++; + c1ao->vintt[j - 1] = c3->tsas[jpo2 - 1][ipo2 - 1] * cc * cfsq; + } // jpo2 loop + } // ipo2 loop + } // jpo1 loop + } // ipo1 loop } /*! \brief C++ porting of STR @@ -2060,79 +2060,79 @@ void scr2( * \param c6: `C6 *` Pointer to a C6 instance. */ void str(double **rcf, C1 *c1, C1_AddOns *c1ao, C3 *c3, C4 *c4, C6 *c6) { - std::complex<double> *ylm; - const double pi = acos(-1.0); - c3->gcs = 0.0; - double gcss = 0.0; - for (int i18 = 1; i18 <= c4->nsph; i18++) { - int iogi = c1->iog[i18 - 1]; - if (iogi >= i18) { - gcss = pi * c1->ros[i18 - 1] * c1->ros[i18 - 1]; - c1->gcsv[i18 - 1] = gcss; - int nsh = c1->nshl[i18 - 1]; - for (int j16 = 1; j16 <= nsh; j16++) { - c1->rc[i18 - 1][j16 - 1] = rcf[i18 - 1][j16 - 1] * c1->ros[i18 - 1]; - } // j16 loop - } - c3->gcs += gcss; - } // i18 loop - int ylm_size = (c4->litpos > c4->lmtpos) ? c4->litpos : c4->lmtpos; - ylm = new std::complex<double>[ylm_size](); - int i = 0; - for (int l1po28 = 1; l1po28 <= c4->lmpo; l1po28++) { - int l1 = l1po28 - 1; - for (int l2 = 1; l2 <= c4->lm; l2++) { - r3j000(l1, l2, c6); - c1ao->ind3j[l1po28 - 1][l2 - 1] = i; - int lmnpo = (l2 > l1) ? l2 - l1 + 1 : l1 - l2 + 1; - int lmxpo = l2 + l1 + 1; - int lpo28 = lmnpo; - int il = 0; - while (lpo28 <= lmxpo) { - i++; - il++; - c1ao->v3j0[i - 1] = c6->rac3j[il - 1]; - lpo28 += 2; - } - } // l2 loop - } // l1po28 loop - int nsphmo = c4->nsph - 1; - int lit = c4->li + c4->li; - int ivy = 0; - for (int nf40 = 1; nf40 <= nsphmo; nf40++) { // GPU portable? - int nfpo = nf40 + 1; - for (int ns40 = nfpo; ns40 <= c4->nsph; ns40++) { - double rx = c1->rxx[nf40 - 1] - c1->rxx[ns40 - 1]; - double ry = c1->ryy[nf40 - 1] - c1->ryy[ns40 - 1]; - double rz = c1->rzz[nf40 - 1] - c1->rzz[ns40 - 1]; - double rr = 0.0; - double crth = 0.0, srth = 0.0, crph = 0.0, srph = 0.0; - polar(rx, ry, rz, rr, crth, srth, crph, srph); - sphar(crth, srth, crph, srph, lit, ylm); - for (int iv38 = 1; iv38 <= c4->litpos; iv38++) { - c1ao->vyhj[iv38 + ivy - 1] = dconjg(ylm[iv38 - 1]); - } // iv38 loop - ivy += c4->litpos; - } // ns40 loop - } // nf40 loop - int lmt = c4->li + c4->le; - ivy = 0; - for (int nf50 = 1; nf50 <= c4->nsph; nf50++) { - double rx = c1->rxx[nf50 - 1]; - double ry = c1->ryy[nf50 - 1]; - double rz = c1->rzz[nf50 - 1]; - if (rx != 0.0 || ry != 0.0 || rz != 0.0) { - double rr = 0.0; - double crth = 0.0, srth = 0.0, crph = 0.0, srph = 0.0; - polar(rx, ry, rz, rr, crth, srth, crph, srph); - sphar(crth, srth, crph, srph, lmt, ylm); - for (int iv48 = 1; iv48 <= c4->lmtpos; iv48++) { - c1ao->vyj0[iv48 + ivy - 1] = dconjg(ylm[iv48 - 1]); - } // iv48 loop - } - ivy += c4->lmtpos; - } // nf50 loop - delete[] ylm; + std::complex<double> *ylm; + const double pi = acos(-1.0); + c3->gcs = 0.0; + double gcss = 0.0; + for (int i18 = 1; i18 <= c4->nsph; i18++) { + int iogi = c1->iog[i18 - 1]; + if (iogi >= i18) { + gcss = pi * c1->ros[i18 - 1] * c1->ros[i18 - 1]; + c1->gcsv[i18 - 1] = gcss; + int nsh = c1->nshl[i18 - 1]; + for (int j16 = 1; j16 <= nsh; j16++) { + c1->rc[i18 - 1][j16 - 1] = rcf[i18 - 1][j16 - 1] * c1->ros[i18 - 1]; + } // j16 loop + } + c3->gcs += gcss; + } // i18 loop + int ylm_size = (c4->litpos > c4->lmtpos) ? c4->litpos : c4->lmtpos; + ylm = new std::complex<double>[ylm_size](); + int i = 0; + for (int l1po28 = 1; l1po28 <= c4->lmpo; l1po28++) { + int l1 = l1po28 - 1; + for (int l2 = 1; l2 <= c4->lm; l2++) { + r3j000(l1, l2, c6); + c1ao->ind3j[l1po28 - 1][l2 - 1] = i; + int lmnpo = (l2 > l1) ? l2 - l1 + 1 : l1 - l2 + 1; + int lmxpo = l2 + l1 + 1; + int lpo28 = lmnpo; + int il = 0; + while (lpo28 <= lmxpo) { + i++; + il++; + c1ao->v3j0[i - 1] = c6->rac3j[il - 1]; + lpo28 += 2; + } + } // l2 loop + } // l1po28 loop + int nsphmo = c4->nsph - 1; + int lit = c4->li + c4->li; + int ivy = 0; + for (int nf40 = 1; nf40 <= nsphmo; nf40++) { // GPU portable? + int nfpo = nf40 + 1; + for (int ns40 = nfpo; ns40 <= c4->nsph; ns40++) { + double rx = c1->rxx[nf40 - 1] - c1->rxx[ns40 - 1]; + double ry = c1->ryy[nf40 - 1] - c1->ryy[ns40 - 1]; + double rz = c1->rzz[nf40 - 1] - c1->rzz[ns40 - 1]; + double rr = 0.0; + double crth = 0.0, srth = 0.0, crph = 0.0, srph = 0.0; + polar(rx, ry, rz, rr, crth, srth, crph, srph); + sphar(crth, srth, crph, srph, lit, ylm); + for (int iv38 = 1; iv38 <= c4->litpos; iv38++) { + c1ao->vyhj[iv38 + ivy - 1] = dconjg(ylm[iv38 - 1]); + } // iv38 loop + ivy += c4->litpos; + } // ns40 loop + } // nf40 loop + int lmt = c4->li + c4->le; + ivy = 0; + for (int nf50 = 1; nf50 <= c4->nsph; nf50++) { + double rx = c1->rxx[nf50 - 1]; + double ry = c1->ryy[nf50 - 1]; + double rz = c1->rzz[nf50 - 1]; + if (rx != 0.0 || ry != 0.0 || rz != 0.0) { + double rr = 0.0; + double crth = 0.0, srth = 0.0, crph = 0.0, srph = 0.0; + polar(rx, ry, rz, rr, crth, srth, crph, srph); + sphar(crth, srth, crph, srph, lmt, ylm); + for (int iv48 = 1; iv48 <= c4->lmtpos; iv48++) { + c1ao->vyj0[iv48 + ivy - 1] = dconjg(ylm[iv48 - 1]); + } // iv48 loop + } + ivy += c4->lmtpos; + } // nf50 loop + delete[] ylm; } /*! \brief C++ porting of TQR @@ -2150,15 +2150,15 @@ void str(double **rcf, C1 *c1, C1_AddOns *c1ao, C3 *c3, C4 *c4, C6 *c6) { * \param tsk: `double &` */ void tqr( - double *u, double *up, double *un, double *tqev, double *tqsv, double &tep, - double &ten, double &tek, double &tsp, double &tsn, double &tsk -) { - tep = up[0] * tqev[0] + up[1] * tqev[1] + up[2] * tqev[2]; - ten = un[0] * tqev[0] + un[1] * tqev[1] + un[2] * tqev[2]; - tek = u[0] * tqev[0] + u[1] * tqev[1] + u[2] * tqev[2]; - tsp = up[0] * tqsv[0] + up[1] * tqsv[1] + up[2] * tqsv[2]; - tsn = un[0] * tqsv[0] + un[1] * tqsv[1] + un[2] * tqsv[2]; - tsk = u[0] * tqsv[0] + u[1] * tqsv[1] + u[2] * tqsv[2]; + double *u, double *up, double *un, double *tqev, double *tqsv, double &tep, + double &ten, double &tek, double &tsp, double &tsn, double &tsk + ) { + tep = up[0] * tqev[0] + up[1] * tqev[1] + up[2] * tqev[2]; + ten = un[0] * tqev[0] + un[1] * tqev[1] + un[2] * tqev[2]; + tek = u[0] * tqev[0] + u[1] * tqev[1] + u[2] * tqev[2]; + tsp = up[0] * tqsv[0] + up[1] * tqsv[1] + up[2] * tqsv[2]; + tsn = un[0] * tqsv[0] + un[1] * tqsv[1] + un[2] * tqsv[2]; + tsk = u[0] * tqsv[0] + u[1] * tqsv[1] + u[2] * tqsv[2]; } /*! \brief C++ porting of ZTM @@ -2171,83 +2171,83 @@ void tqr( * \param c9: `C9 *` Pointer to a C9 instance. */ void ztm(std::complex<double> **am, C1 *c1, C1_AddOns *c1ao, C4 *c4, C6 *c6, C9 * c9) { - std::complex<double> gie, gle, a1, a2, a3, a4, sum1, sum2, sum3, sum4; - const std::complex<double> cc0(0.0, 0.0); - int ndi = c4->nsph * c4->nlim; - int i2 = 0; - for (int n2 = 1; n2 <= c4->nsph; n2++) { // GPU portable? - for (int l2 = 1; l2 <= c4->li; l2++) { - int l2tpo = l2 + l2 + 1; - int m2 = -l2 - 1; - for (int im2 = 1; im2 <= l2tpo; im2++) { - m2++; - i2++; - int i3 = 0; - for (int l3 = 1; l3 <= c4->le; l3++) { - int l3tpo = l3 + l3 + 1; - int m3 = -l3 - 1; - for (int im3 = 1; im3 <= l3tpo; im3++) { - m3++; - i3++; - c9->gis[i2 - 1][i3 - 1] = ghit(2, 0, n2, l2, m2, l3, m3, c1, c1ao, c4, c6); - c9->gls[i2 - 1][i3 - 1] = ghit(2, 1, n2, l2, m2, l3, m3, c1, c1ao, c4, c6); - } // im3 loop - } // l3 loop - } // im2 loop - } // l2 loop - } // n2 loop - for (int i1 = 1; i1 <= ndi; i1++) { // GPU portable? - int i1e = i1 + ndi; - for (int i3 = 1; i3 <= c4->nlem; i3++) { - int i3e = i3 + c4->nlem; - sum1 = cc0; - sum2 = cc0; - sum3 = cc0; - sum4 = cc0; - for (int i2 = 1; i2 <= ndi; i2++) { - int i2e = i2 + ndi; - gie = c9->gis[i2 - 1][i3 - 1]; - gle = c9->gls[i2 - 1][i3 - 1]; - a1 = am[i1 - 1][i2 - 1]; - a2 = am[i1 - 1][i2e - 1]; - a3 = am[i1e - 1][i2 - 1]; - a4 = am[i1e - 1][i2e - 1]; - sum1 += (a1 * gie + a2 * gle); - sum2 += (a1 * gle + a2 * gie); - sum3 += (a3 * gie + a4 * gle); - sum4 += (a3 * gle + a4 * gie); - } // i2 loop - c9->sam[i1 - 1][i3 - 1] = sum1; - c9->sam[i1 - 1][i3e - 1] = sum2; - c9->sam[i1e - 1][i3 - 1] = sum3; - c9->sam[i1e - 1][i3e - 1] = sum4; - } // i3 loop - } // i1 loop - for (int i1 = 1; i1 <= ndi; i1++) { - for (int i0 = 1; i0 <= c4->nlem; i0++) { - c9->gis[i1 - 1][i0 - 1] = dconjg(c9->gis[i1 - 1][i0 - 1]); - c9->gls[i1 - 1][i0 - 1] = dconjg(c9->gls[i1 - 1][i0 - 1]); - } // i0 loop - } // i1 loop - int nlemt = c4->nlem + c4->nlem; - for (int i0 = 1; i0 <= c4->nlem; i0++) { - int i0e = i0 + c4->nlem; - for (int i3 = 1; i3 <= nlemt; i3++) { - sum1 = cc0; - sum2 = cc0; - for (int i1 = 1; i1 <= ndi; i1 ++) { - int i1e = i1 + ndi; - a1 = c9->sam[i1 - 1][i3 - 1]; - a2 = c9->sam[i1e - 1][i3 - 1]; - gie = c9->gis[i1 - 1][i0 - 1]; - gle = c9->gls[i1 - 1][i0 - 1]; - sum1 += (a1 * gie + a2 * gle); - sum2 += (a1 * gle + a2 * gie); - } // i1 loop - c1ao->am0m[i0 - 1][i3 - 1] = -sum1; - c1ao->am0m[i0e - 1][i3 - 1] = -sum2; - } // i3 loop - } // i0 loop + std::complex<double> gie, gle, a1, a2, a3, a4, sum1, sum2, sum3, sum4; + const std::complex<double> cc0(0.0, 0.0); + int ndi = c4->nsph * c4->nlim; + int i2 = 0; + for (int n2 = 1; n2 <= c4->nsph; n2++) { // GPU portable? + for (int l2 = 1; l2 <= c4->li; l2++) { + int l2tpo = l2 + l2 + 1; + int m2 = -l2 - 1; + for (int im2 = 1; im2 <= l2tpo; im2++) { + m2++; + i2++; + int i3 = 0; + for (int l3 = 1; l3 <= c4->le; l3++) { + int l3tpo = l3 + l3 + 1; + int m3 = -l3 - 1; + for (int im3 = 1; im3 <= l3tpo; im3++) { + m3++; + i3++; + c9->gis[i2 - 1][i3 - 1] = ghit(2, 0, n2, l2, m2, l3, m3, c1, c1ao, c4, c6); + c9->gls[i2 - 1][i3 - 1] = ghit(2, 1, n2, l2, m2, l3, m3, c1, c1ao, c4, c6); + } // im3 loop + } // l3 loop + } // im2 loop + } // l2 loop + } // n2 loop + for (int i1 = 1; i1 <= ndi; i1++) { // GPU portable? + int i1e = i1 + ndi; + for (int i3 = 1; i3 <= c4->nlem; i3++) { + int i3e = i3 + c4->nlem; + sum1 = cc0; + sum2 = cc0; + sum3 = cc0; + sum4 = cc0; + for (int i2 = 1; i2 <= ndi; i2++) { + int i2e = i2 + ndi; + gie = c9->gis[i2 - 1][i3 - 1]; + gle = c9->gls[i2 - 1][i3 - 1]; + a1 = am[i1 - 1][i2 - 1]; + a2 = am[i1 - 1][i2e - 1]; + a3 = am[i1e - 1][i2 - 1]; + a4 = am[i1e - 1][i2e - 1]; + sum1 += (a1 * gie + a2 * gle); + sum2 += (a1 * gle + a2 * gie); + sum3 += (a3 * gie + a4 * gle); + sum4 += (a3 * gle + a4 * gie); + } // i2 loop + c9->sam[i1 - 1][i3 - 1] = sum1; + c9->sam[i1 - 1][i3e - 1] = sum2; + c9->sam[i1e - 1][i3 - 1] = sum3; + c9->sam[i1e - 1][i3e - 1] = sum4; + } // i3 loop + } // i1 loop + for (int i1 = 1; i1 <= ndi; i1++) { + for (int i0 = 1; i0 <= c4->nlem; i0++) { + c9->gis[i1 - 1][i0 - 1] = dconjg(c9->gis[i1 - 1][i0 - 1]); + c9->gls[i1 - 1][i0 - 1] = dconjg(c9->gls[i1 - 1][i0 - 1]); + } // i0 loop + } // i1 loop + int nlemt = c4->nlem + c4->nlem; + for (int i0 = 1; i0 <= c4->nlem; i0++) { + int i0e = i0 + c4->nlem; + for (int i3 = 1; i3 <= nlemt; i3++) { + sum1 = cc0; + sum2 = cc0; + for (int i1 = 1; i1 <= ndi; i1 ++) { + int i1e = i1 + ndi; + a1 = c9->sam[i1 - 1][i3 - 1]; + a2 = c9->sam[i1e - 1][i3 - 1]; + gie = c9->gis[i1 - 1][i0 - 1]; + gle = c9->gls[i1 - 1][i0 - 1]; + sum1 += (a1 * gie + a2 * gle); + sum2 += (a1 * gle + a2 * gie); + } // i1 loop + c1ao->am0m[i0 - 1][i3 - 1] = -sum1; + c1ao->am0m[i0e - 1][i3 - 1] = -sum2; + } // i3 loop + } // i0 loop } /*! \brief Sum all the elements of a matrix (debug function). @@ -2257,11 +2257,11 @@ void ztm(std::complex<double> **am, C1 *c1, C1_AddOns *c1ao, C4 *c4, C6 *c6, C9 * \param cols: `int` */ std::complex<double> summat(std::complex<double> **mat, int rows, int cols) { - std::complex<double> result(0.0, 0.0); - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) result += mat[i][j]; - } - return result; + std::complex<double> result(0.0, 0.0); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) result += mat[i][j]; + } + return result; } #endif diff --git a/src/include/sph_subs.h b/src/include/sph_subs.h index dd3470da68ed49ebc8f8fe31d9a4b9ef22f05072..21eba3ecdb7ce3d0e2a87bf3c8454a378aeb8e26 100644 --- a/src/include/sph_subs.h +++ b/src/include/sph_subs.h @@ -511,6 +511,9 @@ void pwma( } /*! \brief C++ porting of RABAS + * + * This function computes radiation torque on the particle as a result + * of the difference between the extinction and the scattering contributions. * * \param inpol: `int` * \param li: `int` diff --git a/src/libnptm/Configuration.cpp b/src/libnptm/Configuration.cpp index 517e7ea9726a80a758d512df4b69d1412bcb225f..96d055a11f555c217044cec6802461dd465effd7 100644 --- a/src/libnptm/Configuration.cpp +++ b/src/libnptm/Configuration.cpp @@ -1,5 +1,5 @@ /*! \file Configuration.cpp -*/ + */ #include <cmath> #include <cstdio> @@ -13,921 +13,910 @@ using namespace std; GeometryConfiguration::GeometryConfiguration( - int _nsph, int _lm, int _in_pol, int _npnt, int _npntts, int _isam, - int _li, int _le, int _mxndm, int _iavm, - double *x, double *y, double *z, - double in_th_start, double in_th_step, double in_th_end, - double sc_th_start, double sc_th_step, double sc_th_end, - double in_ph_start, double in_ph_step, double in_ph_end, - double sc_ph_start, double sc_ph_step, double sc_ph_end, - int _jwtm - ) { - number_of_spheres = _nsph; - l_max = _lm; - in_pol = _in_pol; - npnt = _npnt; - npntts = _npntts; - meridional_type = _isam; - li = _li; - le = _le; - mxndm = _mxndm; - iavm = _iavm; - in_theta_start = in_th_start; - in_theta_step = in_th_step; - in_theta_end = in_th_end; - in_phi_start = in_ph_start; - in_phi_step = in_ph_step; - in_phi_end = in_ph_end; - sc_theta_start = sc_th_start; - sc_theta_step = sc_th_step; - sc_theta_end = sc_th_end; - sc_phi_start = sc_ph_start; - sc_phi_step = sc_ph_step; - sc_phi_end = sc_ph_end; - jwtm = _jwtm; - sph_x = x; - sph_y = y; - sph_z = z; + int _nsph, int _lm, int _in_pol, int _npnt, int _npntts, int _isam, + int _li, int _le, int _mxndm, int _iavm, + double *x, double *y, double *z, + double in_th_start, double in_th_step, double in_th_end, + double sc_th_start, double sc_th_step, double sc_th_end, + double in_ph_start, double in_ph_step, double in_ph_end, + double sc_ph_start, double sc_ph_step, double sc_ph_end, + int _jwtm + ) { + number_of_spheres = _nsph; + l_max = _lm; + in_pol = _in_pol; + npnt = _npnt; + npntts = _npntts; + meridional_type = _isam; + li = _li; + le = _le; + mxndm = _mxndm; + iavm = _iavm; + in_theta_start = in_th_start; + in_theta_step = in_th_step; + in_theta_end = in_th_end; + in_phi_start = in_ph_start; + in_phi_step = in_ph_step; + in_phi_end = in_ph_end; + sc_theta_start = sc_th_start; + sc_theta_step = sc_th_step; + sc_theta_end = sc_th_end; + sc_phi_start = sc_ph_start; + sc_phi_step = sc_ph_step; + sc_phi_end = sc_ph_end; + jwtm = _jwtm; + sph_x = x; + sph_y = y; + sph_z = z; } GeometryConfiguration::~GeometryConfiguration() { - delete[] sph_x; - delete[] sph_y; - delete[] sph_z; + delete[] sph_x; + delete[] sph_y; + delete[] sph_z; } GeometryConfiguration* GeometryConfiguration::from_legacy(string file_name) { - int num_lines = 0; - int last_read_line = 0; - string *file_lines; - string str_target, str_num; - smatch m; - try { - file_lines = load_file(file_name, &num_lines); - } catch (exception &ex) { - throw OpenConfigurationFileException(file_name); - } - int _nsph = 0, _lm = 0, _in_pol = 0, _npnt = 0, _npntts = 0, _isam = 0; - int _li = 0, _le = 0, _mxndm = 0, _iavm = 0; - regex re = regex("-?[0-9]+"); - str_target = file_lines[last_read_line++]; + int num_lines = 0; + int last_read_line = 0; + string *file_lines; + string str_target, str_num; + smatch m; + try { + file_lines = load_file(file_name, &num_lines); + } catch (...) { + OpenConfigurationFileException ex(file_name); + throw ex; + } + int _nsph = 0, _lm = 0, _in_pol = 0, _npnt = 0, _npntts = 0, _isam = 0; + int _li = 0, _le = 0, _mxndm = 0, _iavm = 0; + regex re = regex("-?[0-9]+"); + str_target = file_lines[last_read_line++]; + regex_search(str_target, m, re); + _nsph = stoi(m.str()); + if (_nsph == 1) { + for (int ri = 0; ri < 5; ri++) { + str_target = m.suffix().str(); + regex_search(str_target, m, re); + if (ri == 0) _lm = stoi(m.str()); + if (ri == 1) _in_pol = stoi(m.str()); + if (ri == 2) _npnt = stoi(m.str()); + if (ri == 3) _npntts = stoi(m.str()); + if (ri == 4) _isam = stoi(m.str()); + } + } else { + for (int ri = 0; ri < 8; ri++) { + str_target = m.suffix().str(); + regex_search(str_target, m, re); + if (ri == 0) _li = stoi(m.str()); + if (ri == 1) _le = stoi(m.str()); + if (ri == 2) _mxndm = stoi(m.str()); + if (ri == 3) _in_pol = stoi(m.str()); + if (ri == 4) _npnt = stoi(m.str()); + if (ri == 5) _npntts = stoi(m.str()); + if (ri == 6) _iavm = stoi(m.str()); + if (ri == 7) _isam = stoi(m.str()); + } + } + double *x, *y, *z; + x = new double[_nsph]; + y = new double[_nsph]; + z = new double[_nsph]; + if (_nsph == 1) { + x[0] = 0.0; + y[0] = 0.0; + z[0] = 0.0; + } else { + for (int i = 0; i < _nsph; i++) { + str_target = file_lines[last_read_line++]; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + for (int ri = 0; ri < 3; ri++) { regex_search(str_target, m, re); - //sscanf(file_lines[last_read_line].c_str(), " %d", &_nsph); - _nsph = stoi(m.str()); - if (_nsph == 1) { - //sscanf( - // file_lines[last_read_line++].c_str(), - // " %*d %d %d %d %d %d", - // &_lm, &_in_pol, &_npnt, &_npntts, &_isam - //); - for (int ri = 0; ri < 5; ri++) { - str_target = m.suffix().str(); - regex_search(str_target, m, re); - if (ri == 0) _lm = stoi(m.str()); - if (ri == 1) _in_pol = stoi(m.str()); - if (ri == 2) _npnt = stoi(m.str()); - if (ri == 3) _npntts = stoi(m.str()); - if (ri == 4) _isam = stoi(m.str()); - } - } else { - //sscanf( - // file_lines[last_read_line++].c_str(), - // " %*d %d %d %d %d %d %d %d %d", - // &_li, &_le, &_mxndm, &_in_pol, &_npnt, &_npntts, &_iavm, &_isam - //); - for (int ri = 0; ri < 8; ri++) { - str_target = m.suffix().str(); - regex_search(str_target, m, re); - if (ri == 0) _li = stoi(m.str()); - if (ri == 1) _le = stoi(m.str()); - if (ri == 2) _mxndm = stoi(m.str()); - if (ri == 3) _in_pol = stoi(m.str()); - if (ri == 4) _npnt = stoi(m.str()); - if (ri == 5) _npntts = stoi(m.str()); - if (ri == 6) _iavm = stoi(m.str()); - if (ri == 7) _isam = stoi(m.str()); - } - } - double *x, *y, *z; - x = new double[_nsph]; - y = new double[_nsph]; - z = new double[_nsph]; - if (_nsph == 1) { - x[0] = 0.0; - y[0] = 0.0; - z[0] = 0.0; - } else { - for (int i = 0; i < _nsph; i++) { - str_target = file_lines[last_read_line++]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - for (int ri = 0; ri < 3; ri++) { - regex_search(str_target, m, re); - str_num = regex_replace(m.str(), regex("D"), "e"); - str_num = regex_replace(str_num, regex("d"), "e"); - if (ri == 0) x[i] = stod(str_num); - if (ri == 1) y[i] = stod(str_num); - if (ri == 2) z[i] = stod(str_num); - str_target = m.suffix().str(); - } - } - } - double in_th_start, in_th_end, in_th_step, sc_th_start, sc_th_end, sc_th_step; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - str_target = file_lines[last_read_line++]; - for (int ri = 0; ri < 6; ri++) { - regex_search(str_target, m, re); - str_num = regex_replace(m.str(), regex("D"), "e"); - str_num = regex_replace(str_num, regex("d"), "e"); - if (ri == 0) in_th_start = stod(str_num); - if (ri == 1) in_th_step = stod(str_num); - if (ri == 2) in_th_end = stod(str_num); - if (ri == 3) sc_th_start = stod(str_num); - if (ri == 4) sc_th_step = stod(str_num); - if (ri == 5) sc_th_end = stod(str_num); - str_target = m.suffix().str(); - } + str_num = regex_replace(m.str(), regex("D"), "e"); + str_num = regex_replace(str_num, regex("d"), "e"); + if (ri == 0) x[i] = stod(str_num); + if (ri == 1) y[i] = stod(str_num); + if (ri == 2) z[i] = stod(str_num); + str_target = m.suffix().str(); + } + } + } + double in_th_start, in_th_end, in_th_step, sc_th_start, sc_th_end, sc_th_step; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + str_target = file_lines[last_read_line++]; + for (int ri = 0; ri < 6; ri++) { + regex_search(str_target, m, re); + str_num = regex_replace(m.str(), regex("D"), "e"); + str_num = regex_replace(str_num, regex("d"), "e"); + if (ri == 0) in_th_start = stod(str_num); + if (ri == 1) in_th_step = stod(str_num); + if (ri == 2) in_th_end = stod(str_num); + if (ri == 3) sc_th_start = stod(str_num); + if (ri == 4) sc_th_step = stod(str_num); + if (ri == 5) sc_th_end = stod(str_num); + str_target = m.suffix().str(); + } - double in_ph_start, in_ph_end, in_ph_step, sc_ph_start, sc_ph_end, sc_ph_step; - str_target = file_lines[last_read_line++]; - for (int ri = 0; ri < 6; ri++) { - regex_search(str_target, m, re); - str_num = regex_replace(m.str(), regex("D"), "e"); - str_num = regex_replace(str_num, regex("d"), "e"); - if (ri == 0) in_ph_start = stod(str_num); - if (ri == 1) in_ph_step = stod(str_num); - if (ri == 2) in_ph_end = stod(str_num); - if (ri == 3) sc_ph_start = stod(str_num); - if (ri == 4) sc_ph_step = stod(str_num); - if (ri == 5) sc_ph_end = stod(str_num); - str_target = m.suffix().str(); - } + double in_ph_start, in_ph_end, in_ph_step, sc_ph_start, sc_ph_end, sc_ph_step; + str_target = file_lines[last_read_line++]; + for (int ri = 0; ri < 6; ri++) { + regex_search(str_target, m, re); + str_num = regex_replace(m.str(), regex("D"), "e"); + str_num = regex_replace(str_num, regex("d"), "e"); + if (ri == 0) in_ph_start = stod(str_num); + if (ri == 1) in_ph_step = stod(str_num); + if (ri == 2) in_ph_end = stod(str_num); + if (ri == 3) sc_ph_start = stod(str_num); + if (ri == 4) sc_ph_step = stod(str_num); + if (ri == 5) sc_ph_end = stod(str_num); + str_target = m.suffix().str(); + } - int _jwtm; - re = regex("[0-9]+"); - str_target = file_lines[last_read_line++]; - regex_search(str_target, m, re); - //sscanf(file_lines[last_read_line].c_str(), " %d", &_nsph); - _jwtm = stoi(m.str()); - GeometryConfiguration *conf = new GeometryConfiguration( - _nsph, _lm, _in_pol, _npnt, _npntts, _isam, - _li, _le, _mxndm, _iavm, - x, y, z, - in_th_start, in_th_step, in_th_end, - sc_th_start, sc_th_step, sc_th_end, - in_ph_start, in_ph_step, in_ph_end, - sc_ph_start, sc_ph_step, sc_ph_end, - _jwtm - ); - return conf; + int _jwtm; + re = regex("[0-9]+"); + str_target = file_lines[last_read_line++]; + regex_search(str_target, m, re); + _jwtm = stoi(m.str()); + GeometryConfiguration *conf = new GeometryConfiguration( + _nsph, _lm, _in_pol, _npnt, _npntts, _isam, + _li, _le, _mxndm, _iavm, + x, y, z, + in_th_start, in_th_step, in_th_end, + sc_th_start, sc_th_step, sc_th_end, + in_ph_start, in_ph_step, in_ph_end, + sc_ph_start, sc_ph_step, sc_ph_end, + _jwtm + ); + return conf; } ScattererConfiguration::ScattererConfiguration( - int nsph, - double *scale_vector, - int nxi, - string variable_name, - int *iog_vector, - double *ros_vector, - int *nshl_vector, - double **rcf_vector, - int dielectric_func_type, - complex<double> ***dc_matrix, - bool is_external, - double ex, - double w, - double x - ) { - number_of_spheres = nsph; - number_of_scales = nxi; - reference_variable_name = variable_name; - iog_vec = iog_vector; - radii_of_spheres = ros_vector; - nshl_vec = nshl_vector; - rcf = rcf_vector; - idfc = dielectric_func_type, - dc0_matrix = dc_matrix; - use_external_sphere = is_external; - exdc = ex; - wp = w; - xip = x; - if (variable_name == "XIV") scale_vec = scale_vector; - else { - scale_vec = new double[number_of_scales](); - const double pi2 = 2.0 * acos(-1.0); - const double evc = 6.5821188e-16; - for (int si = 0; si < number_of_scales; si++) { - double value = scale_vector[si]; - if (variable_name.compare("WNS") == 0) value *= (3.0e8 / wp); - else if (variable_name.compare("WLS") == 0) value = pi2 / value * 3.0e8 / wp; - else if (variable_name.compare("PUS") == 0) value /= wp; - else if (variable_name.compare("EVS") == 0) value /= (evc * wp); - scale_vec[si] = value; - } - } + int nsph, + double *scale_vector, + int nxi, + string variable_name, + int *iog_vector, + double *ros_vector, + int *nshl_vector, + double **rcf_vector, + int dielectric_func_type, + complex<double> ***dc_matrix, + bool is_external, + double ex, + double w, + double x + ) { + number_of_spheres = nsph; + number_of_scales = nxi; + reference_variable_name = variable_name; + iog_vec = iog_vector; + radii_of_spheres = ros_vector; + nshl_vec = nshl_vector; + rcf = rcf_vector; + idfc = dielectric_func_type, + dc0_matrix = dc_matrix; + use_external_sphere = is_external; + exdc = ex; + wp = w; + xip = x; + if (variable_name == "XIV") scale_vec = scale_vector; + else { + scale_vec = new double[number_of_scales](); + const double pi2 = 2.0 * acos(-1.0); + const double evc = 6.5821188e-16; + for (int si = 0; si < number_of_scales; si++) { + double value = scale_vector[si]; + if (variable_name.compare("WNS") == 0) value *= (3.0e8 / wp); + else if (variable_name.compare("WLS") == 0) value = pi2 / value * 3.0e8 / wp; + else if (variable_name.compare("PUS") == 0) value /= wp; + else if (variable_name.compare("EVS") == 0) value /= (evc * wp); + scale_vec[si] = value; + } + } } ScattererConfiguration::~ScattererConfiguration() { - int max_ici = 0; - for (int i = 1; i <= number_of_spheres; i++) { - if (iog_vec[i - 1] < i) continue; - int nsh = nshl_vec[i - 1]; - if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; - } - for (int i = 0; i < max_ici; i++) { - for (int j = 0; j < number_of_spheres; j++) { - delete[] dc0_matrix[i][j]; - } - } - delete[] dc0_matrix; - for (int i = 0; i < number_of_spheres; i++) { - delete[] rcf[i]; - } - delete[] nshl_vec; - delete[] radii_of_spheres; - delete[] iog_vec; - delete[] scale_vec; + int max_ici = 0; + for (int i = 1; i <= number_of_spheres; i++) { + if (iog_vec[i - 1] < i) continue; + int nsh = nshl_vec[i - 1]; + if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; + } + for (int i = 0; i < max_ici; i++) { + for (int j = 0; j < number_of_spheres; j++) { + delete[] dc0_matrix[i][j]; + } + } + delete[] dc0_matrix; + for (int i = 0; i < number_of_spheres; i++) { + delete[] rcf[i]; + } + delete[] nshl_vec; + delete[] radii_of_spheres; + delete[] iog_vec; + delete[] scale_vec; } ScattererConfiguration* ScattererConfiguration::from_binary(string file_name, string mode) { - int nsph; - int *iog; - double _exdc, _wp, _xip; - int _idfc, nxi; - int *nshl_vector; - double *xi_vec; - double *ros_vector; - double **rcf_vector; - complex<double> ***dc0m; - if (mode.compare("LEGACY") == 0) { // Legacy mode was chosen. - int max_ici = 0; - fstream input; - input.open(file_name.c_str(), ios::in | ios::binary); - if (input.is_open()) { - input.read(reinterpret_cast<char *>(&nsph), sizeof(int)); - iog = new int[nsph](); - for (int i = 0; i < nsph; i++) { - input.read(reinterpret_cast<char *>(&(iog[i])), sizeof(int)); - } - input.read(reinterpret_cast<char *>(&_exdc), sizeof(double)); - input.read(reinterpret_cast<char *>(&_wp), sizeof(double)); - input.read(reinterpret_cast<char *>(&_xip), sizeof(double)); - input.read(reinterpret_cast<char *>(&_idfc), sizeof(int)); - input.read(reinterpret_cast<char *>(&nxi), sizeof(int)); - try { - xi_vec = new double[nxi](); - } catch (bad_alloc &ex) { - throw UnrecognizedConfigurationException("Wrong parameter set: invalid number of scales " + nxi); - } - for (int i = 0; i < nxi; i++) { - input.read(reinterpret_cast<char *>(&(xi_vec[i])), sizeof(double)); - } - nshl_vector = new int[nsph](); - ros_vector = new double[nsph](); - rcf_vector = new double*[nsph]; - for (int i115 = 1; i115 <= nsph; i115++) { - if (iog[i115 - 1] < i115) { - rcf_vector[i115 - 1] = new double[1](); - continue; - } - input.read(reinterpret_cast<char *>(&(nshl_vector[i115 - 1])), sizeof(int)); - input.read(reinterpret_cast<char *>(&(ros_vector[i115 - 1])), sizeof(double)); - int nsh = nshl_vector[i115 - 1]; - if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; - try { - rcf_vector[i115 - 1] = new double[nsh](); - } catch (bad_alloc &ex) { - throw UnrecognizedConfigurationException("Wrong parameter set: invalid number of layers " + nsh); - } - for (int nsi = 0; nsi < nsh; nsi++) { - input.read(reinterpret_cast<char *>(&(rcf_vector[i115 - 1][nsi])), sizeof(double)); - } - } - dc0m = new complex<double>**[max_ici]; - for (int dim1 = 0; dim1 < max_ici; dim1++) { - dc0m[dim1] = new complex<double>*[nsph]; - for (int dim2 = 0; dim2 < nsph; dim2++) { - dc0m[dim1][dim2] = new complex<double>[nxi](); - } - } - for (int jxi468 = 1; jxi468 <= nxi; jxi468++) { - if (_idfc != 0 && jxi468 > 1) continue; - for (int i162 = 1; i162 <= nsph; i162++) { - if (iog[i162 - 1] < i162) continue; - int nsh = nshl_vector[i162 - 1]; - int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? - for (int i157 = 0; i157 < ici; i157++) { - double dc0_real, dc0_img; - input.read(reinterpret_cast<char *>(&dc0_real), sizeof(double)); - input.read(reinterpret_cast<char *>(&dc0_img), sizeof(double)); - dc0m[i157][i162 - 1][jxi468 - 1] = dc0_real + 1i * dc0_img; - } - } - } - input.close(); - } else { // Opening of the input file did not succeed. - throw OpenConfigurationFileException(file_name); - } - } else { // A different binary format was chosen. - //TODO: this part is not yet implemented. - // Functions to write optimized file formats may be invoked here. + int nsph; + int *iog; + double _exdc, _wp, _xip; + int _idfc, nxi; + int *nshl_vector; + double *xi_vec; + double *ros_vector; + double **rcf_vector; + complex<double> ***dc0m; + if (mode.compare("LEGACY") == 0) { // Legacy mode was chosen. + int max_ici = 0; + fstream input; + input.open(file_name.c_str(), ios::in | ios::binary); + if (input.is_open()) { + input.read(reinterpret_cast<char *>(&nsph), sizeof(int)); + iog = new int[nsph](); + for (int i = 0; i < nsph; i++) { + input.read(reinterpret_cast<char *>(&(iog[i])), sizeof(int)); + } + input.read(reinterpret_cast<char *>(&_exdc), sizeof(double)); + input.read(reinterpret_cast<char *>(&_wp), sizeof(double)); + input.read(reinterpret_cast<char *>(&_xip), sizeof(double)); + input.read(reinterpret_cast<char *>(&_idfc), sizeof(int)); + input.read(reinterpret_cast<char *>(&nxi), sizeof(int)); + try { + xi_vec = new double[nxi](); + } catch (const bad_alloc &ex) { + throw UnrecognizedConfigurationException("Wrong parameter set: invalid number of scales " + nxi); + } + for (int i = 0; i < nxi; i++) { + input.read(reinterpret_cast<char *>(&(xi_vec[i])), sizeof(double)); + } + nshl_vector = new int[nsph](); + ros_vector = new double[nsph](); + rcf_vector = new double*[nsph]; + for (int i115 = 1; i115 <= nsph; i115++) { + if (iog[i115 - 1] < i115) { + rcf_vector[i115 - 1] = new double[1](); + continue; } - ScattererConfiguration *conf = new ScattererConfiguration( - nsph, - xi_vec, - nxi, - "XIV", - iog, - ros_vector, - nshl_vector, - rcf_vector, - _idfc, - dc0m, - false, - _exdc, - _wp, - _xip - ); - return conf; -} - -ScattererConfiguration* ScattererConfiguration::from_dedfb(string dedfb_file_name) { - int num_lines = 0; - int last_read_line = 0; - string *file_lines; - regex re; - smatch m; + input.read(reinterpret_cast<char *>(&(nshl_vector[i115 - 1])), sizeof(int)); + input.read(reinterpret_cast<char *>(&(ros_vector[i115 - 1])), sizeof(double)); + int nsh = nshl_vector[i115 - 1]; + if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; try { - file_lines = load_file(dedfb_file_name, &num_lines); - } catch (exception &ex) { - throw OpenConfigurationFileException(dedfb_file_name); + rcf_vector[i115 - 1] = new double[nsh](); + } catch (const bad_alloc &ex) { + throw UnrecognizedConfigurationException("Wrong parameter set: invalid number of layers " + nsh); } - int nsph, ies; - int max_ici = 0; - re = regex("[0-9]+"); - string str_target = file_lines[last_read_line]; - for (int ri = 0; ri < 2; ri++) { - regex_search(str_target, m, re); - if (ri == 0) nsph = stoi(m.str()); - if (ri == 1) ies = stoi(m.str()); - str_target = m.suffix().str(); + for (int nsi = 0; nsi < nsh; nsi++) { + input.read(reinterpret_cast<char *>(&(rcf_vector[i115 - 1][nsi])), sizeof(double)); } - if (ies != 0) ies = 1; - double _exdc, _wp, _xip; - str_target = file_lines[++last_read_line]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - for (int ri = 0; ri < 3; ri++) { - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - if (ri == 0) _exdc = stod(str_number); - if (ri == 1) _wp = stod(str_number); - if (ri == 2) _xip = stod(str_number); - str_target = m.suffix().str(); + } + dc0m = new complex<double>**[max_ici]; + for (int dim1 = 0; dim1 < max_ici; dim1++) { + dc0m[dim1] = new complex<double>*[nsph]; + for (int dim2 = 0; dim2 < nsph; dim2++) { + dc0m[dim1][dim2] = new complex<double>[nxi](); } - int _idfc, nxi, instpc, insn; - re = regex("-?[0-9]+"); - for (int ri = 0; ri < 4; ri++) { - regex_search(str_target, m, re); - if (ri == 0) _idfc = stoi(m.str()); - if (ri == 1) nxi = stoi(m.str()); - if (ri == 2) instpc = stoi(m.str()); - if (ri == 3) insn = stoi(m.str()); - str_target = m.suffix().str(); + } + for (int jxi468 = 1; jxi468 <= nxi; jxi468++) { + if (_idfc != 0 && jxi468 > 1) continue; + for (int i162 = 1; i162 <= nsph; i162++) { + if (iog[i162 - 1] < i162) continue; + int nsh = nshl_vector[i162 - 1]; + int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? + for (int i157 = 0; i157 < ici; i157++) { + double dc0_real, dc0_img; + input.read(reinterpret_cast<char *>(&dc0_real), sizeof(double)); + input.read(reinterpret_cast<char *>(&dc0_img), sizeof(double)); + dc0m[i157][i162 - 1][jxi468 - 1] = dc0_real + 1i * dc0_img; + } } + } + input.close(); + } else { // Opening of the input file did not succeed. + OpenConfigurationFileException ex(file_name); + throw ex; + } + } else { // A different binary format was chosen. + //TODO: this part is not yet implemented. + // Functions to write optimized file formats may be invoked here. + } + ScattererConfiguration *conf = new ScattererConfiguration( + nsph, + xi_vec, + nxi, + "XIV", + iog, + ros_vector, + nshl_vector, + rcf_vector, + _idfc, + dc0m, + false, + _exdc, + _wp, + _xip + ); + return conf; +} + +ScattererConfiguration* ScattererConfiguration::from_dedfb(string dedfb_file_name) { + int num_lines = 0; + int last_read_line = 0; + string *file_lines; + regex re; + smatch m; + try { + file_lines = load_file(dedfb_file_name, &num_lines); + } catch (...) { + OpenConfigurationFileException ex(dedfb_file_name); + throw ex; + } + int nsph, ies; + int max_ici = 0; + re = regex("[0-9]+"); + string str_target = file_lines[last_read_line]; + for (int ri = 0; ri < 2; ri++) { + regex_search(str_target, m, re); + if (ri == 0) nsph = stoi(m.str()); + if (ri == 1) ies = stoi(m.str()); + str_target = m.suffix().str(); + } + if (ies != 0) ies = 1; + double _exdc, _wp, _xip; + str_target = file_lines[++last_read_line]; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + for (int ri = 0; ri < 3; ri++) { + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + if (ri == 0) _exdc = stod(str_number); + if (ri == 1) _wp = stod(str_number); + if (ri == 2) _xip = stod(str_number); + str_target = m.suffix().str(); + } + int _idfc, nxi, instpc, insn; + re = regex("-?[0-9]+"); + for (int ri = 0; ri < 4; ri++) { + regex_search(str_target, m, re); + if (ri == 0) _idfc = stoi(m.str()); + if (ri == 1) nxi = stoi(m.str()); + if (ri == 2) instpc = stoi(m.str()); + if (ri == 3) insn = stoi(m.str()); + str_target = m.suffix().str(); + } - double *variable_vector; - string variable_name; + double *variable_vector; + string variable_name; - if (_idfc < 0) { // Diel. functions at XIP value and XI is scale factor - variable_name = "XIV"; - if (instpc < 1) { // The variable vector is explicitly defined. - double xi; - //int xi_exp; - List<double> xi_vector; - //sscanf(file_lines[++last_read_line].c_str(), " %9lE D%d", &xi, &xi_exp); - str_target = file_lines[++last_read_line]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - xi = stod(str_number); - xi_vector.set(0, xi); - for (int jxi310 = 1; jxi310 < nxi; jxi310++) { - str_target = file_lines[++last_read_line]; - regex_search(str_target, m, re); - str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - xi = stod(str_number); - xi_vector.append(xi); - } - variable_vector = xi_vector.to_array(); - } else { // instpc >= 1: the variable vector is defined in steps - double xi, xi_step; - str_target = file_lines[++last_read_line]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - regex_search(str_target, m, re); - for (int ri = 0; ri < 2; ri++) { - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - if (ri == 0) xi = stod(str_number); - if (ri == 1) xi_step = stod(str_number); - str_target = m.suffix().str(); - } - variable_vector = new double[nxi](); - for (int jxi320 = 0; jxi320 < nxi; jxi320++) { - variable_vector[jxi320] = xi; - xi += xi_step; - } - } - } else { // idfc >= 0 - variable_vector = new double[nxi](); - if (instpc == 0) { // The variable vector is explicitly defined - double vs; - //int vs_exp; - for (int jxi_r = 0; jxi_r < nxi; jxi_r++) { - //sscanf(file_lines[++last_read_line].c_str(), " %lf D%d", &vs, &vs_exp); - str_target = file_lines[++last_read_line]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - vs = stod(str_number); - variable_vector[jxi_r] = vs; - } - switch (insn) { - case 1: //xi vector definition - variable_name = "XIV"; - break; - case 2: //wave number vector definition - variable_name = "WNS"; - break; - case 3: //wavelength vector definition - variable_name = "WLS"; - break; - case 4: //pu vector definition - variable_name = "PUS"; - break; - case 5: //eV vector definition - variable_name = "EVS"; - break; - } - } else { // The variable vector needs to be computed in steps - double vs, vs_step; - //int vs_exp, vs_step_exp; - //sscanf(file_lines[++last_read_line].c_str(), " %lf D%d %lf D%d", &vs, &vs_exp, &vs_step, &vs_step_exp); - str_target = file_lines[++last_read_line]; - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - regex_search(str_target, m, re); - for (int ri = 0; ri < 2; ri++) { - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - if (ri == 0) vs = stod(str_number); - if (ri == 1) vs_step = stod(str_number); - str_target = m.suffix().str(); - } - for (int jxi110w = 0; jxi110w < nxi; jxi110w++) { - variable_vector[jxi110w] = vs; - vs += vs_step; - } - switch (insn) { - case 1: //xi vector definition - variable_name = "XIV"; - break; - case 2: //wave number vector definition - variable_name = "WNS"; - break; - case 3: //wavelength vector definition - variable_name = "WLS"; - break; - case 4: //pu vector definition - variable_name = "PUS"; - break; - case 5: //eV vector definition - variable_name = "EVS"; - break; - } - } - } - last_read_line++; - int *iog_vector = new int[nsph](); - double *ros_vector = new double[nsph](); - double **rcf_vector = new double*[nsph]; - int *nshl_vector = new int[nsph](); - //printf("\nDEBUG: reading IOG from %s", file_lines[last_read_line].c_str()); - //fflush(stdout); - for (int i = 0; i < nsph; i++) { - string read_format = ""; - for (int j = 0; j < (i % 15); j++) read_format += " %*d"; - read_format += " %d"; - sscanf(file_lines[last_read_line].c_str(), read_format.c_str(), (iog_vector + i)); - if (i > 0 && i % 15 == 0) { - last_read_line++; - //printf("DEBUG: reading IOG from %s", file_lines[last_read_line].c_str()); - //fflush(stdout); - } - } - for (int i113 = 1; i113 <= nsph; i113++) { - int i_val, nsh; - double ros_val; - //int ros_val_exp; - if (iog_vector[i113 - 1] < i113) { - rcf_vector[i113 - 1] = new double[1](); - continue; - } - //sscanf(file_lines[++last_read_line].c_str(), " %d %lf D%d", &i_val, &ros_val, &ros_val_exp); - re = regex("[0-9]+"); - str_target = file_lines[++last_read_line]; - regex_search(str_target, m, re); - i_val = stoi(m.str()); - str_target = m.suffix(); - re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - ros_val = stod(str_number); - nshl_vector[i113 - 1] = i_val; - if (max_ici < (i_val + 1) / 2) max_ici = (i_val + 1) / 2; - ros_vector[i113 - 1] = ros_val; - nsh = nshl_vector[i113 - 1]; - if (i113 == 1) nsh += ies; - rcf_vector[i113 - 1] = new double[nsh](); - for (int ns = 0; ns < nsh; ns++) { - double ns_rcf; - //int ns_rcf_exp; - //sscanf(file_lines[++last_read_line].c_str(), " %lf D%d", &ns_rcf, &ns_rcf_exp); - str_target = file_lines[++last_read_line]; - regex_search(str_target, m, re); - str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - ns_rcf = stod(str_number); - rcf_vector[i113 - 1][ns] = ns_rcf; - } - } - complex<double> ***dc0m = new complex<double>**[max_ici]; - for (int dim1 = 0; dim1 < max_ici; dim1++) { - dc0m[dim1] = new complex<double>*[nsph]; - for (int dim2 = 0; dim2 < nsph; dim2++) { - dc0m[dim1][dim2] = new complex<double>[nxi](); - } - } + if (_idfc < 0) { // Diel. functions at XIP value and XI is scale factor + variable_name = "XIV"; + if (instpc < 1) { // The variable vector is explicitly defined. + double xi; + List<double> xi_vector; + str_target = file_lines[++last_read_line]; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + xi = stod(str_number); + xi_vector.set(0, xi); + for (int jxi310 = 1; jxi310 < nxi; jxi310++) { + str_target = file_lines[++last_read_line]; + regex_search(str_target, m, re); + str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + xi = stod(str_number); + xi_vector.append(xi); + } + variable_vector = xi_vector.to_array(); + } else { // instpc >= 1: the variable vector is defined in steps + double xi, xi_step; + str_target = file_lines[++last_read_line]; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + regex_search(str_target, m, re); + for (int ri = 0; ri < 2; ri++) { + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + if (ri == 0) xi = stod(str_number); + if (ri == 1) xi_step = stod(str_number); + str_target = m.suffix().str(); + } + variable_vector = new double[nxi](); + for (int jxi320 = 0; jxi320 < nxi; jxi320++) { + variable_vector[jxi320] = xi; + xi += xi_step; + } + } + } else { // idfc >= 0 + variable_vector = new double[nxi](); + if (instpc == 0) { // The variable vector is explicitly defined + double vs; + for (int jxi_r = 0; jxi_r < nxi; jxi_r++) { + str_target = file_lines[++last_read_line]; re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); - for (int jxi468 = 1; jxi468 <= nxi; jxi468++) { - if (_idfc != 0 && jxi468 > 1) continue; - for (int i162 = 1; i162 <= nsph; i162++) { - if (iog_vector[i162 - 1] < i162) continue; - int nsh = nshl_vector[i162 - 1]; - int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? - if (i162 == 1) ici = ici + ies; - for (int i157 = 0; i157 < ici; i157++) { - double dc0_real, dc0_img; - //int dc0_real_exp, dc0_img_exp; - //sscanf(file_lines[++last_read_line].c_str(), " (%lf D%d, %lf D%d)", &dc0_real, &dc0_real_exp, &dc0_img, &dc0_img_exp); - str_target = file_lines[++last_read_line]; - regex_search(str_target, m, re); - string str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - dc0_real = stod(str_number); - str_target = m.suffix().str(); - regex_search(str_target, m, re); - str_number = m.str(); - str_number = regex_replace(str_number, regex("D"), "e"); - str_number = regex_replace(str_number, regex("d"), "e"); - dc0_img = stod(str_number); - dc0m[i157][i162 - 1][jxi468 - 1] = std::complex<double>(dc0_real, dc0_img); - } - } - } + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + vs = stod(str_number); + variable_vector[jxi_r] = vs; + } + switch (insn) { + case 1: //xi vector definition + variable_name = "XIV"; + break; + case 2: //wave number vector definition + variable_name = "WNS"; + break; + case 3: //wavelength vector definition + variable_name = "WLS"; + break; + case 4: //pu vector definition + variable_name = "PUS"; + break; + case 5: //eV vector definition + variable_name = "EVS"; + break; + } + } else { // The variable vector needs to be computed in steps + double vs, vs_step; + str_target = file_lines[++last_read_line]; + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + regex_search(str_target, m, re); + for (int ri = 0; ri < 2; ri++) { + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + if (ri == 0) vs = stod(str_number); + if (ri == 1) vs_step = stod(str_number); + str_target = m.suffix().str(); + } + for (int jxi110w = 0; jxi110w < nxi; jxi110w++) { + variable_vector[jxi110w] = vs; + vs += vs_step; + } + switch (insn) { + case 1: //xi vector definition + variable_name = "XIV"; + break; + case 2: //wave number vector definition + variable_name = "WNS"; + break; + case 3: //wavelength vector definition + variable_name = "WLS"; + break; + case 4: //pu vector definition + variable_name = "PUS"; + break; + case 5: //eV vector definition + variable_name = "EVS"; + break; + } + } + } + //last_read_line++; + int *iog_vector = new int[nsph](); + double *ros_vector = new double[nsph](); + double **rcf_vector = new double*[nsph]; + int *nshl_vector = new int[nsph](); + /*for (int i = 0; i < nsph; i++) { + string read_format = ""; + for (int j = 0; j < (i % 15); j++) read_format += " %*d"; + read_format += " %d"; + sscanf(file_lines[last_read_line].c_str(), read_format.c_str(), (iog_vector + i)); + if (i > 0 && i % 15 == 0) { + last_read_line++; + } + }*/ + int filled_iogs = 0; + re = regex("[0-9]+"); + while (filled_iogs < nsph) { + string str_target = file_lines[++last_read_line]; + while(regex_search(str_target, m, re)) { + iog_vector[filled_iogs++] = stoi(m.str()); + str_target = m.suffix().str(); + if (filled_iogs == nsph) break; + } + } + for (int i113 = 1; i113 <= nsph; i113++) { + int i_val, nsh; + double ros_val; + if (iog_vector[i113 - 1] < i113) { + rcf_vector[i113 - 1] = new double[1](); + continue; + } + re = regex("[0-9]+"); + str_target = file_lines[++last_read_line]; + regex_search(str_target, m, re); + i_val = stoi(m.str()); + str_target = m.suffix(); + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + ros_val = stod(str_number); + nshl_vector[i113 - 1] = i_val; + if (max_ici < (i_val + 1) / 2) max_ici = (i_val + 1) / 2; + ros_vector[i113 - 1] = ros_val; + nsh = nshl_vector[i113 - 1]; + if (i113 == 1) nsh += ies; + rcf_vector[i113 - 1] = new double[nsh](); + for (int ns = 0; ns < nsh; ns++) { + double ns_rcf; + //int ns_rcf_exp; + //sscanf(file_lines[++last_read_line].c_str(), " %lf D%d", &ns_rcf, &ns_rcf_exp); + str_target = file_lines[++last_read_line]; + regex_search(str_target, m, re); + str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + ns_rcf = stod(str_number); + rcf_vector[i113 - 1][ns] = ns_rcf; + } + } + complex<double> ***dc0m = new complex<double>**[max_ici]; + for (int dim1 = 0; dim1 < max_ici; dim1++) { + dc0m[dim1] = new complex<double>*[nsph]; + for (int dim2 = 0; dim2 < nsph; dim2++) { + dc0m[dim1][dim2] = new complex<double>[nxi](); + } + } + re = regex("-?[0-9]+\\.[0-9]+([eEdD][-+]?)?[0-9]+"); + for (int jxi468 = 1; jxi468 <= nxi; jxi468++) { + if (_idfc != 0 && jxi468 > 1) continue; + for (int i162 = 1; i162 <= nsph; i162++) { + if (iog_vector[i162 - 1] < i162) continue; + int nsh = nshl_vector[i162 - 1]; + int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? + if (i162 == 1) ici = ici + ies; + for (int i157 = 0; i157 < ici; i157++) { + double dc0_real, dc0_img; + //int dc0_real_exp, dc0_img_exp; + //sscanf(file_lines[++last_read_line].c_str(), " (%lf D%d, %lf D%d)", &dc0_real, &dc0_real_exp, &dc0_img, &dc0_img_exp); + str_target = file_lines[++last_read_line]; + regex_search(str_target, m, re); + string str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + dc0_real = stod(str_number); + str_target = m.suffix().str(); + regex_search(str_target, m, re); + str_number = m.str(); + str_number = regex_replace(str_number, regex("D"), "e"); + str_number = regex_replace(str_number, regex("d"), "e"); + dc0_img = stod(str_number); + dc0m[i157][i162 - 1][jxi468 - 1] = std::complex<double>(dc0_real, dc0_img); + } + } + } - ScattererConfiguration *config = new ScattererConfiguration( - nsph, - variable_vector, - nxi, - variable_name, - iog_vector, - ros_vector, - nshl_vector, - rcf_vector, - _idfc, - dc0m, - (ies > 0), - _exdc, - _wp, - _xip - ); - delete[] file_lines; - return config; + ScattererConfiguration *config = new ScattererConfiguration( + nsph, + variable_vector, + nxi, + variable_name, + iog_vector, + ros_vector, + nshl_vector, + rcf_vector, + _idfc, + dc0m, + (ies > 0), + _exdc, + _wp, + _xip + ); + delete[] file_lines; + return config; } void ScattererConfiguration::print() { - int ies = (use_external_sphere)? 1 : 0; - int max_ici = 0; - printf("### CONFIGURATION DATA ###\n"); - printf("NSPH = %d\n", number_of_spheres); - printf("ROS = ["); - for (int i = 0; i < number_of_spheres; i++) printf("\t%lg", radii_of_spheres[i]); - printf("\t]\n"); - printf("IOG = ["); - for (int i = 0; i < number_of_spheres; i++) printf("\t%d", iog_vec[i]); - printf("\t]\n"); - printf("NSHL = ["); - for (int i = 0; i < number_of_spheres; i++) printf("\t%d", nshl_vec[i]); - printf("\t]\n"); - printf("RCF = [\n"); - for (int i = 1; i <= number_of_spheres; i++) { - int nsh = nshl_vec[i - 1]; - if (i == 1) nsh += ies; - if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; - printf(" ["); - for (int ns = 0; ns < nsh; ns++) { - printf("\t%lg", rcf[i - 1][ns]); - } - printf("\t]\n"); - } - printf(" ]\n"); - printf("SCALE = %s\n", reference_variable_name.c_str()); - printf("NXI = %d\n", number_of_scales); - printf("VEC = ["); - for (int i = 0; i < number_of_scales; i++) printf("\t%lg", scale_vec[i]); - printf("\t]\n"); - printf("DC0M = [\n"); - for (int i = 0; i < max_ici; i++) { - printf(" [\n"); - for (int j = 0; j < number_of_spheres; j++) { - printf(" ["); - for (int k = 0; k < number_of_scales; k++) { - if (idfc != 0 and k > 0) continue; - printf("\t%lg + i(%lg)", dc0_matrix[i][j][k].real(), dc0_matrix[i][j][k].imag()); - } - printf("\t]\n"); - } - printf(" ]\n"); - } - printf(" ]\n"); + int ies = (use_external_sphere)? 1 : 0; + int max_ici = 0; + printf("### CONFIGURATION DATA ###\n"); + printf("NSPH = %d\n", number_of_spheres); + printf("ROS = ["); + for (int i = 0; i < number_of_spheres; i++) printf("\t%lg", radii_of_spheres[i]); + printf("\t]\n"); + printf("IOG = ["); + for (int i = 0; i < number_of_spheres; i++) printf("\t%d", iog_vec[i]); + printf("\t]\n"); + printf("NSHL = ["); + for (int i = 0; i < number_of_spheres; i++) printf("\t%d", nshl_vec[i]); + printf("\t]\n"); + printf("RCF = [\n"); + for (int i = 1; i <= number_of_spheres; i++) { + int nsh = nshl_vec[i - 1]; + if (i == 1) nsh += ies; + if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; + printf(" ["); + for (int ns = 0; ns < nsh; ns++) { + printf("\t%lg", rcf[i - 1][ns]); + } + printf("\t]\n"); + } + printf(" ]\n"); + printf("SCALE = %s\n", reference_variable_name.c_str()); + printf("NXI = %d\n", number_of_scales); + printf("VEC = ["); + for (int i = 0; i < number_of_scales; i++) printf("\t%lg", scale_vec[i]); + printf("\t]\n"); + printf("DC0M = [\n"); + for (int i = 0; i < max_ici; i++) { + printf(" [\n"); + for (int j = 0; j < number_of_spheres; j++) { + printf(" ["); + for (int k = 0; k < number_of_scales; k++) { + if (idfc != 0 and k > 0) continue; + printf("\t%lg + i(%lg)", dc0_matrix[i][j][k].real(), dc0_matrix[i][j][k].imag()); + } + printf("\t]\n"); + } + printf(" ]\n"); + } + printf(" ]\n"); } void ScattererConfiguration::write_binary(string file_name, string mode) { - const double two_pi = acos(0.0) * 4.0; - const double evc = 6.5821188e-16; - int max_ici = 0; - bool is_new_vector = false; - if (mode.compare("LEGACY") == 0) { // Legacy mode was chosen. - fstream output; - int ies = (use_external_sphere)? 1 : 0; - double *xi_vec; - if (reference_variable_name.compare("XIV") == 0) xi_vec = scale_vec; - else { - is_new_vector = true; - xi_vec = new double[number_of_scales]; - if (reference_variable_name.compare("WNS") == 0) { - for (int i = 0; i < number_of_scales; i++) - xi_vec[i] = 3.0e8 * scale_vec[i] / wp; - } else if (reference_variable_name.compare("WLS") == 0) { - for (int i = 0; i < number_of_scales; i++) { - double wn = two_pi / scale_vec[i]; - xi_vec[i] = 3.0e8 * wn / wp; - } - } else if (reference_variable_name.compare("PUS") == 0) { - for (int i = 0; i < number_of_scales; i++) - xi_vec[i] = scale_vec[i] / wp; - } else if (reference_variable_name.compare("EVS") == 0) { - for (int i = 0; i < number_of_scales; i++) { - double pu = scale_vec[i] / evc; - xi_vec[i] = pu / wp; - } - } else { - throw UnrecognizedConfigurationException( - "Wrong parameter set: unrecognized scale type " - + reference_variable_name - ); - } - } - output.open(file_name.c_str(), ios::out | ios::binary); - output.write(reinterpret_cast<char *>(&number_of_spheres), sizeof(int)); - for (int i = 0; i < number_of_spheres; i++) - output.write(reinterpret_cast<char *>(&(iog_vec[i])), sizeof(int)); - output.write(reinterpret_cast<char *>(&exdc), sizeof(double)); - output.write(reinterpret_cast<char *>(&wp), sizeof(double)); - output.write(reinterpret_cast<char *>(&xip), sizeof(double)); - output.write(reinterpret_cast<char *>(&idfc), sizeof(int)); - output.write(reinterpret_cast<char *>(&number_of_scales), sizeof(int)); - for (int i = 0; i < number_of_scales; i++) - output.write(reinterpret_cast<char *>(&(xi_vec[i])), sizeof(double)); - for (int i115 = 1; i115 <= number_of_spheres; i115++) { - if (iog_vec[i115 - 1] < i115) continue; - output.write(reinterpret_cast<char *>(&(nshl_vec[i115 - 1])), sizeof(int)); - output.write(reinterpret_cast<char *>(&(radii_of_spheres[i115 - 1])), sizeof(double)); - int nsh = nshl_vec[i115 - 1]; - if (i115 == 1) nsh += ies; - if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; - for (int nsi = 0; nsi < nsh; nsi++) - output.write(reinterpret_cast<char *>(&(rcf[i115 - 1][nsi])), sizeof(double)); - } - for (int jxi468 = 1; jxi468 <= number_of_scales; jxi468++) { - if (idfc != 0 && jxi468 > 1) continue; - for (int i162 = 1; i162 <= number_of_spheres; i162++) { - if (iog_vec[i162 - 1] < i162) continue; - int nsh = nshl_vec[i162 - 1]; - int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? - if (i162 == 1) ici = ici + ies; - for (int i157 = 0; i157 < ici; i157++) { - double dc0_real, dc0_img; - dc0_real = dc0_matrix[i157][i162 - 1][jxi468 - 1].real(); - dc0_img = dc0_matrix[i157][i162 - 1][jxi468 - 1].imag(); - // The FORTRAN code writes the complex numbers as a 16-byte long binary stream. - // Here we assume that the 16 bytes are equally split in 8 bytes to represent the - // real part and 8 bytes to represent the imaginary one. - output.write(reinterpret_cast<char *>(&dc0_real), sizeof(double)); - output.write(reinterpret_cast<char *>(&dc0_img), sizeof(double)); - } - } - } - if (is_new_vector) delete[] xi_vec; - output.close(); + const double two_pi = acos(0.0) * 4.0; + const double evc = 6.5821188e-16; + int max_ici = 0; + bool is_new_vector = false; + if (mode.compare("LEGACY") == 0) { // Legacy mode was chosen. + fstream output; + int ies = (use_external_sphere)? 1 : 0; + double *xi_vec; + if (reference_variable_name.compare("XIV") == 0) xi_vec = scale_vec; + else { + is_new_vector = true; + xi_vec = new double[number_of_scales]; + if (reference_variable_name.compare("WNS") == 0) { + for (int i = 0; i < number_of_scales; i++) + xi_vec[i] = 3.0e8 * scale_vec[i] / wp; + } else if (reference_variable_name.compare("WLS") == 0) { + for (int i = 0; i < number_of_scales; i++) { + double wn = two_pi / scale_vec[i]; + xi_vec[i] = 3.0e8 * wn / wp; + } + } else if (reference_variable_name.compare("PUS") == 0) { + for (int i = 0; i < number_of_scales; i++) + xi_vec[i] = scale_vec[i] / wp; + } else if (reference_variable_name.compare("EVS") == 0) { + for (int i = 0; i < number_of_scales; i++) { + double pu = scale_vec[i] / evc; + xi_vec[i] = pu / wp; } + } else { + throw UnrecognizedConfigurationException( + "Wrong parameter set: unrecognized scale type " + + reference_variable_name + ); + } + } + output.open(file_name.c_str(), ios::out | ios::binary); + output.write(reinterpret_cast<char *>(&number_of_spheres), sizeof(int)); + for (int i = 0; i < number_of_spheres; i++) + output.write(reinterpret_cast<char *>(&(iog_vec[i])), sizeof(int)); + output.write(reinterpret_cast<char *>(&exdc), sizeof(double)); + output.write(reinterpret_cast<char *>(&wp), sizeof(double)); + output.write(reinterpret_cast<char *>(&xip), sizeof(double)); + output.write(reinterpret_cast<char *>(&idfc), sizeof(int)); + output.write(reinterpret_cast<char *>(&number_of_scales), sizeof(int)); + for (int i = 0; i < number_of_scales; i++) + output.write(reinterpret_cast<char *>(&(xi_vec[i])), sizeof(double)); + for (int i115 = 1; i115 <= number_of_spheres; i115++) { + if (iog_vec[i115 - 1] < i115) continue; + output.write(reinterpret_cast<char *>(&(nshl_vec[i115 - 1])), sizeof(int)); + output.write(reinterpret_cast<char *>(&(radii_of_spheres[i115 - 1])), sizeof(double)); + int nsh = nshl_vec[i115 - 1]; + if (i115 == 1) nsh += ies; + if (max_ici < (nsh + 1) / 2) max_ici = (nsh + 1) / 2; + for (int nsi = 0; nsi < nsh; nsi++) + output.write(reinterpret_cast<char *>(&(rcf[i115 - 1][nsi])), sizeof(double)); + } + for (int jxi468 = 1; jxi468 <= number_of_scales; jxi468++) { + if (idfc != 0 && jxi468 > 1) continue; + for (int i162 = 1; i162 <= number_of_spheres; i162++) { + if (iog_vec[i162 - 1] < i162) continue; + int nsh = nshl_vec[i162 - 1]; + int ici = (nsh + 1) / 2; // QUESTION: is integer division really intended here? + if (i162 == 1) ici = ici + ies; + for (int i157 = 0; i157 < ici; i157++) { + double dc0_real, dc0_img; + dc0_real = dc0_matrix[i157][i162 - 1][jxi468 - 1].real(); + dc0_img = dc0_matrix[i157][i162 - 1][jxi468 - 1].imag(); + // The FORTRAN code writes the complex numbers as a 16-byte long binary stream. + // Here we assume that the 16 bytes are equally split in 8 bytes to represent the + // real part and 8 bytes to represent the imaginary one. + output.write(reinterpret_cast<char *>(&dc0_real), sizeof(double)); + output.write(reinterpret_cast<char *>(&dc0_img), sizeof(double)); + } + } + } + if (is_new_vector) delete[] xi_vec; + output.close(); + } } void ScattererConfiguration::write_formatted(string file_name) { - const double evc = 6.5821188e-16; - const double two_pi = acos(0.0) * 4.0; - double *xi_vec; - int ici; - int ies = (use_external_sphere)? 1: 0; - FILE *output = fopen(file_name.c_str(), "w"); - int scale_type = -1; - if (reference_variable_name.compare("XIV") == 0) scale_type = 0; - else if (reference_variable_name.compare("WNS") == 0) scale_type = 1; - else if (reference_variable_name.compare("WLS") == 0) scale_type = 2; - else if (reference_variable_name.compare("PUS") == 0) scale_type = 3; - else if (reference_variable_name.compare("EVS") == 0) scale_type = 4; - if (idfc >= 0) { // Dielectric functions are constant or they depend on XI - double *pu_vec, *ev_vec, *wn_vec, *wl_vec; - xi_vec = new double[number_of_scales]; - pu_vec = new double[number_of_scales]; - ev_vec = new double[number_of_scales]; - wn_vec = new double[number_of_scales]; - wl_vec = new double[number_of_scales]; - switch (scale_type) { - case 0: - fprintf(output, " JXI XIV WNS WLS PUS EVS\n"); - for (int i = 0; i < number_of_scales; i++) { - xi_vec[i] = scale_vec[i]; - pu_vec[i] = xi_vec[i] * wp; - ev_vec[i] = pu_vec[i] * evc; - wn_vec[i] = pu_vec[i] / 3.0e8; - wl_vec[i] = two_pi / wn_vec[i]; - fprintf( - output, - "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", - (i + 1), - xi_vec[i], - wn_vec[i], - wl_vec[i], - pu_vec[i], - ev_vec[i] - ); - } - break; - case 1: - fprintf(output, " JXI WNS WLS PUS EVS XIV\n"); - for (int i = 0; i < number_of_scales; i++) { - wn_vec[i] = scale_vec[i]; - wl_vec[i] = two_pi / wn_vec[i]; - xi_vec[i] = 3.0e8 * wn_vec[i] / wp; - pu_vec[i] = xi_vec[i] * wp; - ev_vec[i] = pu_vec[i] * evc; - fprintf( - output, - "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", - (i + 1), - wn_vec[i], - wl_vec[i], - pu_vec[i], - ev_vec[i], - xi_vec[i] - ); - } - break; - case 2: - fprintf(output, " JXI WLS WNS PUS EVS XIV\n"); - for (int i = 0; i < number_of_scales; i++) { - wl_vec[i] = scale_vec[i]; - wn_vec[i] = two_pi / wl_vec[i]; - xi_vec[i] = 3.0e8 * wn_vec[i] / wp; - pu_vec[i] = xi_vec[i] * wp; - ev_vec[i] = pu_vec[i] * evc; - fprintf( - output, - "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", - (i + 1), - wl_vec[i], - wn_vec[i], - pu_vec[i], - ev_vec[i], - xi_vec[i] - ); - } - break; - case 3: - fprintf(output, " JXI PUS WNS WLS EVS XIV\n"); - for (int i = 0; i < number_of_scales; i++) { - pu_vec[i] = scale_vec[i]; - xi_vec[i] = pu_vec[i] / wp; - wn_vec[i] = pu_vec[i] / 3.0e8; - wl_vec[i] = two_pi / wn_vec[i]; - ev_vec[i] = pu_vec[i] * evc; - fprintf( - output, - "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", - (i + 1), - pu_vec[i], - wn_vec[i], - wl_vec[i], - ev_vec[i], - xi_vec[i] - ); - } - break; - case 4: - fprintf(output, " JXI EVS WNS WLS PUS XIV\n"); - for (int i = 0; i < number_of_scales; i++) { - ev_vec[i] = scale_vec[i]; - pu_vec[i] = ev_vec[i] / evc; - xi_vec[i] = pu_vec[i] / wp; - wn_vec[i] = pu_vec[i] / 3.0e8; - wl_vec[i] = two_pi / wn_vec[i]; - fprintf( - output, - "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", - (i + 1), - ev_vec[i], - wn_vec[i], - wl_vec[i], - pu_vec[i], - xi_vec[i] - ); - } - break; - default: - throw UnrecognizedConfigurationException( - "Wonrg parameter set: unrecognized scale variable type " - + reference_variable_name - ); - break; - } - } else { // idfc < 0, Dielectric functions are at XIP and XI is scale for dimensions - double pu, wn; - xi_vec = scale_vec; - pu = xip * wp; - wn = pu / 3.0e8; - fprintf(output, " XIP WN WL PU EV\n"); - fprintf(output, " %13.4lE", xip); - fprintf(output, "%13.4lE", wn); - fprintf(output, "%13.4lE", two_pi / wn); - fprintf(output, "%13.4lE", pu); - fprintf(output, "%13.4lE\n", pu * evc); - fprintf(output, " SCALE FACTORS XI\n"); - for (int i = 0; i < number_of_scales; i++) - fprintf(output, "%5d%13.4lE\n", (i + 1), xi_vec[i]); + const double evc = 6.5821188e-16; + const double two_pi = acos(0.0) * 4.0; + double *xi_vec; + int ici; + int ies = (use_external_sphere)? 1: 0; + FILE *output = fopen(file_name.c_str(), "w"); + int scale_type = -1; + if (reference_variable_name.compare("XIV") == 0) scale_type = 0; + else if (reference_variable_name.compare("WNS") == 0) scale_type = 1; + else if (reference_variable_name.compare("WLS") == 0) scale_type = 2; + else if (reference_variable_name.compare("PUS") == 0) scale_type = 3; + else if (reference_variable_name.compare("EVS") == 0) scale_type = 4; + if (idfc >= 0) { // Dielectric functions are constant or they depend on XI + double *pu_vec, *ev_vec, *wn_vec, *wl_vec; + xi_vec = new double[number_of_scales]; + pu_vec = new double[number_of_scales]; + ev_vec = new double[number_of_scales]; + wn_vec = new double[number_of_scales]; + wl_vec = new double[number_of_scales]; + switch (scale_type) { + case 0: + fprintf(output, " JXI XIV WNS WLS PUS EVS\n"); + for (int i = 0; i < number_of_scales; i++) { + xi_vec[i] = scale_vec[i]; + pu_vec[i] = xi_vec[i] * wp; + ev_vec[i] = pu_vec[i] * evc; + wn_vec[i] = pu_vec[i] / 3.0e8; + wl_vec[i] = two_pi / wn_vec[i]; + fprintf( + output, + "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", + (i + 1), + xi_vec[i], + wn_vec[i], + wl_vec[i], + pu_vec[i], + ev_vec[i] + ); + } + break; + case 1: + fprintf(output, " JXI WNS WLS PUS EVS XIV\n"); + for (int i = 0; i < number_of_scales; i++) { + wn_vec[i] = scale_vec[i]; + wl_vec[i] = two_pi / wn_vec[i]; + xi_vec[i] = 3.0e8 * wn_vec[i] / wp; + pu_vec[i] = xi_vec[i] * wp; + ev_vec[i] = pu_vec[i] * evc; + fprintf( + output, + "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", + (i + 1), + wn_vec[i], + wl_vec[i], + pu_vec[i], + ev_vec[i], + xi_vec[i] + ); + } + break; + case 2: + fprintf(output, " JXI WLS WNS PUS EVS XIV\n"); + for (int i = 0; i < number_of_scales; i++) { + wl_vec[i] = scale_vec[i]; + wn_vec[i] = two_pi / wl_vec[i]; + xi_vec[i] = 3.0e8 * wn_vec[i] / wp; + pu_vec[i] = xi_vec[i] * wp; + ev_vec[i] = pu_vec[i] * evc; + fprintf( + output, + "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", + (i + 1), + wl_vec[i], + wn_vec[i], + pu_vec[i], + ev_vec[i], + xi_vec[i] + ); + } + break; + case 3: + fprintf(output, " JXI PUS WNS WLS EVS XIV\n"); + for (int i = 0; i < number_of_scales; i++) { + pu_vec[i] = scale_vec[i]; + xi_vec[i] = pu_vec[i] / wp; + wn_vec[i] = pu_vec[i] / 3.0e8; + wl_vec[i] = two_pi / wn_vec[i]; + ev_vec[i] = pu_vec[i] * evc; + fprintf( + output, + "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", + (i + 1), + pu_vec[i], + wn_vec[i], + wl_vec[i], + ev_vec[i], + xi_vec[i] + ); + } + break; + case 4: + fprintf(output, " JXI EVS WNS WLS PUS XIV\n"); + for (int i = 0; i < number_of_scales; i++) { + ev_vec[i] = scale_vec[i]; + pu_vec[i] = ev_vec[i] / evc; + xi_vec[i] = pu_vec[i] / wp; + wn_vec[i] = pu_vec[i] / 3.0e8; + wl_vec[i] = two_pi / wn_vec[i]; + fprintf( + output, + "%5d%13.4lE%13.4lE%13.4lE%13.4lE%13.4lE\n", + (i + 1), + ev_vec[i], + wn_vec[i], + wl_vec[i], + pu_vec[i], + xi_vec[i] + ); + } + break; + default: + throw UnrecognizedConfigurationException( + "Wonrg parameter set: unrecognized scale variable type " + + reference_variable_name + ); + break; + } + } else { // idfc < 0, Dielectric functions are at XIP and XI is scale for dimensions + double pu, wn; + xi_vec = scale_vec; + pu = xip * wp; + wn = pu / 3.0e8; + fprintf(output, " XIP WN WL PU EV\n"); + fprintf(output, " %13.4lE", xip); + fprintf(output, "%13.4lE", wn); + fprintf(output, "%13.4lE", two_pi / wn); + fprintf(output, "%13.4lE", pu); + fprintf(output, "%13.4lE\n", pu * evc); + fprintf(output, " SCALE FACTORS XI\n"); + for (int i = 0; i < number_of_scales; i++) + fprintf(output, "%5d%13.4lE\n", (i + 1), xi_vec[i]); + } + if (idfc != 0) { + fprintf(output, " DIELECTRIC CONSTANTS\n"); + for (int i473 = 1; i473 <= number_of_spheres; i473++) { + if (iog_vec[i473 - 1] != i473) continue; + ici = (nshl_vec[i473 - 1] + 1) / 2; + if (i473 == 1) ici += ies; + fprintf(output, " SPHERE N.%4d\n", i473); + for (int ic472 = 0; ic472 < ici; ic472++) { + double dc0_real = dc0_matrix[ic472][i473 - 1][0].real(), dc0_img = dc0_matrix[ic472][i473 - 1][0].imag(); + fprintf(output, "%5d %12.4lE%12.4lE\n", (ic472 + 1), dc0_real, dc0_img); + } + } + } else { + fprintf(output, " DIELECTRIC FUNCTIONS\n"); + for (int i478 = 1; i478 <= number_of_spheres; i478++) { + if (iog_vec[i478 - 1] != i478) continue; + ici = (nshl_vec[i478 - 1] + 1) / 2; + if (i478 == 1) ici += ies; + fprintf(output, " SPHERE N.%4d\n", i478); + for (int ic477 = 1; ic477 <= ici; ic477++) { + fprintf(output, " NONTRANSITION LAYER N.%2d, SCALE = %3s\n", ic477, reference_variable_name.c_str()); + for (int jxi476 = 0; jxi476 < number_of_scales; jxi476++) { + double dc0_real = dc0_matrix[ic477 - 1][i478 - 1][jxi476].real(); + double dc0_img = dc0_matrix[ic477 - 1][i478 - 1][jxi476].imag(); + fprintf(output, "%5d%12.4lE%12.4lE\n", (jxi476 + 1), dc0_real, dc0_img); } - if (idfc != 0) { - fprintf(output, " DIELECTRIC CONSTANTS\n"); - for (int i473 = 1; i473 <= number_of_spheres; i473++) { - if (iog_vec[i473 - 1] != i473) continue; - ici = (nshl_vec[i473 - 1] + 1) / 2; - if (i473 == 1) ici += ies; - fprintf(output, " SPHERE N.%4d\n", i473); - for (int ic472 = 0; ic472 < ici; ic472++) { - double dc0_real = dc0_matrix[ic472][i473 - 1][0].real(), dc0_img = dc0_matrix[ic472][i473 - 1][0].imag(); - fprintf(output, "%5d %12.4lE%12.4lE\n", (ic472 + 1), dc0_real, dc0_img); - } - } - } else { - fprintf(output, " DIELECTRIC FUNCTIONS\n"); - for (int i478 = 1; i478 <= number_of_spheres; i478++) { - if (iog_vec[i478 - 1] != i478) continue; - ici = (nshl_vec[i478 - 1] + 1) / 2; - if (i478 == 1) ici += ies; - fprintf(output, " SPHERE N.%4d\n", i478); - for (int ic477 = 1; ic477 <= ici; ic477++) { - fprintf(output, " NONTRANSITION LAYER N.%2d, SCALE = %3s\n", ic477, reference_variable_name.c_str()); - for (int jxi476 = 0; jxi476 < number_of_scales; jxi476++) { - double dc0_real = dc0_matrix[ic477 - 1][i478 - 1][jxi476].real(); - double dc0_img = dc0_matrix[ic477 - 1][i478 - 1][jxi476].imag(); - fprintf(output, "%5d%12.4lE%12.4lE\n", (jxi476 + 1), dc0_real, dc0_img); - } - } - } - } - fclose(output); + } + } + } + fclose(output); } diff --git a/src/scripts/pycompare.py b/src/scripts/pycompare.py index d919a82a8418971ea568341a30f7c466f2aa37bf..92420746426358d0c4327991d9126512c45db670 100755 --- a/src/scripts/pycompare.py +++ b/src/scripts/pycompare.py @@ -6,7 +6,7 @@ # Comparing the numeric output can be rendered hard by the amount of information # contained in a typical output file and the necessity to determine whether a # difference is actually significant or just caused by numeric noise hitting -# negligible values. The task of this script is to compare two output files, in +# negligible values. The task of `pycompare.py` is to compare two output files, in # the assumption that they were written by the FORTRAN and the C++ versions of # the code and to flag all the possible inconsistencies according to various # severity levels (namely: NOISE, WARNING, and ERROR). @@ -105,7 +105,7 @@ def compare_files(config): line_count = len(f_lines) num_len = 1 if (line_count > 0): - num_len = int(log10(line_count)) + 1 + num_len = max(4, int(log10(line_count)) + 1) if (config['log_html']): l_file = open(config['html_output'], 'w') l_file.write("<!DOCTYPE html>\n") @@ -157,11 +157,13 @@ def compare_files(config): # # \returns mismatch_count: `tuple(int, int, int)` A tuple that bundles # together the numbers of detected errors, warnings and noisy values. -def compare_lines(f_line, c_line, config, line_num=0, num_len=1, log_file=None): +def compare_lines(f_line, c_line, config, line_num=0, num_len=4, log_file=None): errors = 0 warnings = 0 noisy = 0 f_line = f_line.replace("D-","E-").replace("D+","E+") + ref_format = " <div><span style=\"font-weight: bold; color: rgb(125,125,125)\"><pre><code>{0:%ds}"%num_len + ref_line = (ref_format + ": {1:s}</code></pre></span></div>\n").format("ORIG", f_line[:-1]) if (f_line == c_line): if log_file is not None: if (config['full_log']): @@ -246,6 +248,7 @@ def compare_lines(f_line, c_line, config, line_num=0, num_len=1, log_file=None): + c_groups[-1] + "</code></span><code>" + c_line[c_ends[-1]:len(c_line) - 2] ) log_file.write(log_line + "</code></pre></div>\n") + log_file.write(ref_line) else: # The two lines contain a different number of numeric values if (log_file is not None): num_format = " <div><pre><code>{0:0%dd}"%num_len @@ -255,6 +258,7 @@ def compare_lines(f_line, c_line, config, line_num=0, num_len=1, log_file=None): + c_line + "</code></span><code>" ) log_file.write(log_line + "</code></pre></div>\n") + log_file.write(ref_line) errors += 1 return (errors, warnings, noisy) diff --git a/src/sphere/Makefile b/src/sphere/Makefile index 7c616b7ca9368a4e27bfaf3d2b486d08a88dfafb..f70b833d290c562539f544462ca51069c53f4a6d 100644 --- a/src/sphere/Makefile +++ b/src/sphere/Makefile @@ -3,7 +3,7 @@ FC=gfortran FCFLAGS=-std=legacy -O3 LFLAGS= CXX=g++ -CXXFLAGS=-O0 -ggdb -pg -coverage +CXXFLAGS=-O2 -ggdb -pg -coverage CXXLFLAGS= all: edfb sph np_sphere diff --git a/src/sphere/sphere.cpp b/src/sphere/sphere.cpp index 2cbafe99a37c1e0db0ec952b387c873745288a26..4c4892f9a79528b43ee409313805f30e97a616f7 100644 --- a/src/sphere/sphere.cpp +++ b/src/sphere/sphere.cpp @@ -18,566 +18,583 @@ using namespace std; * \param output_path: `string` Directory to write the output files in. */ void sphere(string config_file, string data_file, string output_path) { - complex<double> arg, s0, tfsas; - double th, ph; - printf("INFO: making legacy configuration...\n"); - ScattererConfiguration *sconf = ScattererConfiguration::from_dedfb(config_file); - GeometryConfiguration *gconf = GeometryConfiguration::from_legacy(data_file); - if (sconf->number_of_spheres == gconf->number_of_spheres) { - int isq, ibf; - double *argi, *args, *gaps; - double cost, sint, cosp, sinp; - double costs, sints, cosps, sinps; - double scan; - double *duk = new double[3]; - double *u = new double[3]; - double *us = new double[3]; - double *un = new double[3]; - double *uns = new double[3]; - double *up = new double[3]; - double *ups = new double[3]; - double *upmp = new double[3]; - double *upsmp = new double[3]; - double *unmp = new double[3]; - double *unsmp = new double[3]; - double **cmul = new double*[4]; - double **cmullr = new double*[4]; - for (int i = 0; i < 4; i++) { - cmul[i] = new double[4]; - cmullr[i] = new double[4]; + complex<double> arg, s0, tfsas; + double th, ph; + printf("INFO: making legacy configuration...\n"); + ScattererConfiguration *sconf = NULL; + try { + sconf = ScattererConfiguration::from_dedfb(config_file); + } catch(const OpenConfigurationFileException &ex) { + printf("\nERROR: failed to open scatterer configuration file.\n"); + printf("FILE: %s\n", ex.what()); + exit(1); + } + sconf->write_formatted(output_path + "c_OEDFB"); + sconf->write_binary(output_path + "c_TEDF"); + GeometryConfiguration *gconf = NULL; + try { + gconf = GeometryConfiguration::from_legacy(data_file); + } catch(const OpenConfigurationFileException &ex) { + printf("\nERROR: failed to open geometry configuration file.\n"); + printf("FILE: %s\n", ex.what()); + if (sconf) delete sconf; + exit(1); + } + if (sconf->number_of_spheres == gconf->number_of_spheres) { + int isq, ibf; + double *argi, *args, *gaps; + double cost, sint, cosp, sinp; + double costs, sints, cosps, sinps; + double scan; + double *duk = new double[3]; + double *u = new double[3]; + double *us = new double[3]; + double *un = new double[3]; + double *uns = new double[3]; + double *up = new double[3]; + double *ups = new double[3]; + double *upmp = new double[3]; + double *upsmp = new double[3]; + double *unmp = new double[3]; + double *unsmp = new double[3]; + double **cmul = new double*[4]; + double **cmullr = new double*[4]; + for (int i = 0; i < 4; i++) { + cmul[i] = new double[4]; + cmullr[i] = new double[4]; + } + complex<double> **tqspe, **tqsps; + double **tqse, **tqss; + tqse = new double*[2]; + tqss = new double*[2]; + tqspe = new std::complex<double>*[2]; + tqsps = new std::complex<double>*[2]; + for (int ti = 0; ti < 2; ti++) { + tqse[ti] = new double[2](); + tqss[ti] = new double[2](); + tqspe[ti] = new std::complex<double>[2](); + tqsps[ti] = new std::complex<double>[2](); + } + double frx = 0.0, fry = 0.0, frz = 0.0; + double cfmp, cfsp, sfmp, sfsp; + complex<double> *vint = new complex<double>[16]; + int jw; + int nsph = gconf->number_of_spheres; + C1 *c1 = new C1(nsph, gconf->l_max, sconf->nshl_vec, sconf->iog_vec); + for (int i = 0; i < nsph; i++) { + c1->ros[i] = sconf->radii_of_spheres[i]; + } + C2 *c2 = new C2(nsph, 5, gconf->npnt, gconf->npntts); + argi = new double[1]; + args = new double[1]; + gaps = new double[2]; + FILE *output = fopen((output_path + "/c_OSPH").c_str(), "w"); + fprintf(output, " READ(IR,*)NSPH,LM,INPOL,NPNT,NPNTTS,ISAM\n"); + fprintf( + output, + " %5d%5d%5d%5d%5d%5d\n", + gconf->number_of_spheres, + gconf->l_max, + gconf->in_pol, + gconf->npnt, + gconf->npntts, + gconf->meridional_type + ); + fprintf(output, " READ(IR,*)TH,THSTP,THLST,THS,THSSTP,THSLST\n"); + fprintf( + output, + " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", + gconf->in_theta_start, + gconf->in_theta_step, + gconf->in_theta_end, + gconf->sc_theta_start, + gconf->sc_theta_step, + gconf->sc_theta_end + ); + fprintf(output, " READ(IR,*)PH,PHSTP,PHLST,PHS,PHSSTP,PHSLST\n"); + fprintf( + output, + " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", + gconf->in_phi_start, + gconf->in_phi_step, + gconf->in_phi_end, + gconf->sc_phi_start, + gconf->sc_phi_step, + gconf->sc_phi_end + ); + fprintf(output, " READ(IR,*)JWTM\n"); + fprintf( + output, + " %5d\n", + gconf->jwtm + ); + fprintf(output, " READ(ITIN)NSPHT\n"); + fprintf(output, " READ(ITIN)(IOG(I),I=1,NSPH)\n"); + fprintf(output, " READ(ITIN)EXDC,WP,XIP,IDFC,NXI\n"); + fprintf(output, " READ(ITIN)(XIV(I),I=1,NXI)\n"); + fprintf(output, " READ(ITIN)NSHL(I),ROS(I)\n"); + fprintf(output, " READ(ITIN)(RCF(I,NS),NS=1,NSH)\n \n"); + double sml = 1.0e-3; + int nth = 0, nph = 0; + if (gconf->in_theta_step != 0.0) + nth = int((gconf->in_theta_end - gconf->in_theta_start) / gconf->in_theta_step + sml); + nth += 1; + if (gconf->in_phi_step != 0.0) + nph = int((gconf->in_phi_end - gconf->in_phi_start) / gconf->in_phi_step + sml); + nph += 1; + int nths = 0, nphs = 0; + double thsca; + if (gconf->meridional_type > 1) { // ISAM > 1, fixed scattering angle + nths = 1; + thsca = gconf->sc_theta_start - gconf->in_theta_start; + } else { //ISAM <= 1 + if (gconf->in_theta_step != 0.0) + nths = int((gconf->sc_theta_end - gconf->sc_theta_start) / gconf->sc_theta_step + sml); + nths += 1; + if (gconf->meridional_type == 1) { // ISAM = 1 + nphs = 1; + } else { // ISAM < 1 + if (gconf->sc_phi_step != 0.0) + nphs = int((gconf->sc_phi_end - gconf->sc_phi_start) / gconf->sc_phi_step + sml); + nphs += 1; + } + } + int nk = nth * nph; + int nks = nths * nphs; + int nkks = nk * nks; + double th1 = gconf->in_theta_start; + double ph1 = gconf->in_phi_start; + double ths1 = gconf->sc_theta_start; + double phs1 = gconf->sc_phi_start; + const double half_pi = acos(0.0); + const double pi = 2.0 * half_pi; + double gcs = 0.0; + for (int i116 = 0; i116 < nsph; i116++) { + int i = i116 + 1; + int iogi = c1->iog[i116]; + if (iogi >= i) { + double gcss = pi * c1->ros[i116] * c1->ros[i116]; + c1->gcsv[i116] = gcss; + int nsh = c1->nshl[i116]; + for (int j115 = 0; j115 < nsh; j115++) { + c1->rc[i116][j115] = sconf->rcf[i116][j115] * c1->ros[i116]; + } + } + gcs += c1->gcsv[iogi]; + } + double ****zpv = new double***[gconf->l_max]; //[gconf->l_max][3][2][2]; // Matrix: dim[LM x 3 x 2 x 2] + for (int zi = 0; zi < gconf->l_max; zi++) { + zpv[zi] = new double**[3]; + for (int zj = 0; zj < 3; zj++) { + zpv[zi][zj] = new double*[2]; + for (int zk = 0; zk < 2; zk++) { + zpv[zi][zj][zk] = new double[2](); + } + } + } + thdps(gconf->l_max, zpv); + double exri = sqrt(sconf->exdc); + fprintf(output, " REFR. INDEX OF EXTERNAL MEDIUM=%15.7lE\n", exri); + fstream tppoan; + string tppoan_name = output_path + "/c_TPPOAN_sph"; + tppoan.open(tppoan_name.c_str(), ios::binary|ios::out); + if (tppoan.is_open()) { + int imode = 10; + tppoan.write(reinterpret_cast<char *>(&imode), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&(gconf->meridional_type)), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&(gconf->in_pol)), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&(sconf->number_of_scales)), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&nth), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&nph), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&nths), sizeof(int)); + tppoan.write(reinterpret_cast<char *>(&nphs), sizeof(int)); + + for (int nsi = 0; nsi < nsph; nsi++) + tppoan.write(reinterpret_cast<char *>(&(sconf->iog_vec[nsi])), sizeof(int)); + if (gconf->in_pol == 0) fprintf(output, " LIN\n"); + else fprintf(output, " CIRC\n"); + fprintf(output, " \n"); + double wn = sconf->wp / 3.0e8; + double sqsfi = 1.0; + double vk, vkarg; + if (sconf->idfc < 0) { + vk = sconf->xip * wn; + fprintf(output, " VK=%15.7lE, XI IS SCALE FACTOR FOR LENGTHS\n", vk); + fprintf(output, " \n"); + } + for (int jxi488 = 0; jxi488 < sconf->number_of_scales; jxi488++) { + printf("INFO: running scale iteration...\n"); + int jxi = jxi488 + 1; + fprintf(output, "========== JXI =%3d ====================\n", jxi); + double xi = sconf->scale_vec[jxi488]; + if (sconf->idfc >= 0) { + vk = xi * wn; + vkarg = vk; + fprintf(output, " VK=%15.7lE, XI=%15.7lE\n", xi, vk); + } else { // IDFC < 0 + vkarg = xi * vk; + sqsfi = 1.0 / (xi * xi); + fprintf(output, " XI=%15.7lE\n", xi); + } + tppoan.write(reinterpret_cast<char *>(&vk), sizeof(double)); + for (int i132 = 0; i132 < nsph; i132++) { + int i = i132 + 1; + int iogi = sconf->iog_vec[i132]; + if (iogi != i) { + for (int l123 = 0; l123 < gconf->l_max; l123++) { + c1->rmi[l123][i132] = c1->rmi[l123][iogi - 1]; + c1->rei[l123][i132] = c1->rei[l123][iogi - 1]; + } + continue; // i132 + } + int nsh = sconf->nshl_vec[i132]; + int ici = (nsh + 1) / 2; + if (sconf->idfc == 0) { + for (int ic = 0; ic < ici; ic++) + c2->dc0[ic] = sconf->dc0_matrix[ic][i132][0]; // WARNING: IDFC=0 is not tested! + } else { // IDFC != 0 + if (jxi == 1) { + for (int ic = 0; ic < ici; ic++) { + c2->dc0[ic] = sconf->dc0_matrix[ic][i132][jxi488]; + } + } + } + if (nsh % 2 == 0) c2->dc0[ici] = sconf->exdc; + int jer = 0; + int lcalc = 0; + dme( + gconf->l_max, i, gconf->npnt, gconf->npntts, vkarg, + sconf->exdc, exri, c1, c2, jer, lcalc, arg + ); + if (jer != 0) { + fprintf(output, " STOP IN DME\n"); + fprintf(output, " AT %1d LCALC=%3d TOO SMALL WITH ARG=%15.7lE+i(%15.7lE)\n", jer, lcalc, arg.real(), arg.imag()); + tppoan.close(); + fclose(output); + return; + } + } // i132 + if (sconf->idfc >= 0 and nsph == 1 and jxi == gconf->jwtm) { + // This is the condition that writes the transition matrix to output. + int is = 1111; + fstream ttms; + string ttms_name = output_path + "/c_TTMS_sph"; + ttms.open(ttms_name.c_str(), ios::binary | ios::out); + if (ttms.is_open()) { + ttms.write(reinterpret_cast<char *>(&is), sizeof(int)); + ttms.write(reinterpret_cast<char *>(&(gconf->l_max)), sizeof(int)); + ttms.write(reinterpret_cast<char *>(&vk), sizeof(double)); + ttms.write(reinterpret_cast<char *>(&exri), sizeof(double)); + for (int lmi = 0; lmi < gconf->l_max; lmi++) { + complex<double> element1 = -1.0 / c1->rmi[0][lmi]; + complex<double> element2 = -1.0 / c1->rei[0][lmi]; + ttms.write(reinterpret_cast<char *>(&element1), sizeof(complex<double>)); + ttms.write(reinterpret_cast<char *>(&element2), sizeof(complex<double>)); + } + ttms.write(reinterpret_cast<char *>(&(sconf->radii_of_spheres[0])), sizeof(double)); + ttms.close(); + } else { // Failed to open output file. Should never happen. + printf("ERROR: could not open TTMS file.\n"); + tppoan.close(); + } + } + double cs0 = 0.25 * vk * vk * vk / half_pi; + //printf("DEBUG: cs0 = %lE\n", cs0); + sscr0(tfsas, nsph, gconf->l_max, vk, exri, c1); + //printf("DEBUG: TFSAS = (%lE,%lE)\n", tfsas.real(), tfsas.imag()); + double sqk = vk * vk * sconf->exdc; + aps(zpv, gconf->l_max, nsph, c1, sqk, gaps); + rabas(gconf->in_pol, gconf->l_max, nsph, c1, tqse, tqspe, tqss, tqsps); + for (int i170 = 0; i170 < nsph; i170++) { + int i = i170 + 1; + if (c1->iog[i170] >= i) { + double albeds = c1->sscs[i170] / c1->sexs[i170]; + c1->sqscs[i170] *= sqsfi; + c1->sqabs[i170] *= sqsfi; + c1->sqexs[i170] *= sqsfi; + fprintf(output, " SPHERE %2d\n", i); + if (c1->nshl[i170] != 1) { + fprintf(output, " SIZE=%15.7lE\n", c2->vsz[i170]); + } else { + fprintf( + output, + " SIZE=%15.7lE, REFRACTIVE INDEX=(%15.7lE,%15.7lE)\n", + c2->vsz[i170], + c2->vkt[i170].real(), + c2->vkt[i170].imag() + ); + } + fprintf(output, " ----- SCS ----- ABS ----- EXS ----- ALBEDS --\n"); + fprintf( + output, + " %14.7lE%15.7lE%15.7lE%15.7lE\n", + c1->sscs[i170], c1->sabs[i170], + c1->sexs[i170], albeds + ); + fprintf(output, " ---- SCS/GS -- ABS/GS -- EXS/GS ---\n"); + fprintf( + output, + " %14.7lE%15.7lE%15.7lE\n", + c1->sqscs[i170], c1->sqabs[i170], + c1->sqexs[i170] + ); + fprintf(output, " FSAS=%15.7lE%15.7lE\n", c1->fsas[i170].real(), c1->fsas[i170].imag()); + double csch = 2.0 * vk * sqsfi / c1->gcsv[i170]; + s0 = c1->fsas[i170] * exri; + double qschu = csch * s0.imag(); + double pschu = csch * s0.real(); + double s0mag = cs0 * abs(s0); + fprintf( + output, + " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", + qschu, pschu, s0mag + ); + double rapr = c1->sexs[i170] - gaps[i170]; + double cosav = gaps[i170] / c1->sscs[i170]; + fprintf(output, " COSAV=%15.7lE, RAPRS=%15.7lE\n", cosav, rapr); + fprintf(output, " IPO=%2d, TQEk=%15.7lE, TQSk=%15.7lE\n", 1, tqse[0][i170], tqss[0][i170]); + fprintf(output, " IPO=%2d, TQEk=%15.7lE, TQSk=%15.7lE\n", 2, tqse[1][i170], tqss[1][i170]); + tppoan.write(reinterpret_cast<char *>(&(tqse[0][i170])), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&(tqss[0][i170])), sizeof(double)); + double val = tqspe[0][i170].real(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqspe[0][i170].imag(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqsps[0][i170].real(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqsps[0][i170].imag(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&(tqse[1][i170])), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&(tqss[1][i170])), sizeof(double)); + val = tqspe[1][i170].real(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqspe[1][i170].imag(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqsps[1][i170].real(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + val = tqsps[1][i170].imag(); + tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); + } // End if iog[i170] >= i + } // i170 loop + if (nsph != 1) { + fprintf(output, " FSAT=(%15.7lE,%15.7lE)\n", tfsas.real(), tfsas.imag()); + double csch = 2.0 * vk * sqsfi / gcs; + s0 = tfsas * exri; + double qschu = csch * s0.imag(); + double pschu = csch * s0.real(); + double s0mag = cs0 * abs(s0); + fprintf( + output, + " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", + qschu, pschu, s0mag + ); + } + th = th1; + for (int jth486 = 0; jth486 < nth; jth486++) { // OpenMP parallelizable section + int jth = jth486 + 1; + ph = ph1; + for (int jph484 = 0; jph484 < nph; jph484++) { + int jph = jph484 + 1; + bool goto182 = (nk == 1) && (jxi > 1); + if (!goto182) { + upvmp(th, ph, 0, cost, sint, cosp, sinp, u, upmp, unmp); + } + if (gconf->meridional_type >= 0) { + wmamp(0, cost, sint, cosp, sinp, gconf->in_pol, gconf->l_max, 0, nsph, argi, u, upmp, unmp, c1); + for (int i183 = 0; i183 < nsph; i183++) { + double rapr = c1->sexs[i183] - gaps[i183]; + frx = rapr * u[0]; + fry = rapr * u[1]; + frz = rapr * u[2]; + } + jw = 1; + } + double thsl = ths1; + double phsph = 0.0; + for (int jths482 = 0; jths482 < nths; jths482++) { + int jths = jths482 + 1; + double ths = thsl; + int icspnv = 0; + if (gconf->meridional_type > 1) ths = th + thsca; + if (gconf->meridional_type >= 1) { + phsph = 0.0; + if ((ths < 0.0) || (ths > 180.0)) phsph = 180.0; + if (ths < 0.0) ths *= -1.0; + if (ths > 180.0) ths = 360.0 - ths; + if (phsph != 0.0) icspnv = 1; + } + double phs = phs1; + for (int jphs480 = 0; jphs480 < nphs; jphs480++) { + int jphs = jphs480 + 1; + if (gconf->meridional_type >= 1) { + phs = ph + phsph; + if (phs >= 360.0) phs -= 360.0; } - complex<double> **tqspe, **tqsps; - double **tqse, **tqss; - tqse = new double*[2]; - tqss = new double*[2]; - tqspe = new std::complex<double>*[2]; - tqsps = new std::complex<double>*[2]; - for (int ti = 0; ti < 2; ti++) { - tqse[ti] = new double[2](); - tqss[ti] = new double[2](); - tqspe[ti] = new std::complex<double>[2](); - tqsps[ti] = new std::complex<double>[2](); + bool goto190 = (nks == 1) && ((jxi > 1) || (jth > 1) || (jph > 1)); + if (!goto190) { + upvmp(ths, phs, icspnv, costs, sints, cosps, sinps, us, upsmp, unsmp); + if (gconf->meridional_type >= 0) { + wmamp(2, costs, sints, cosps, sinps, gconf->in_pol, gconf->l_max, 0, nsph, args, us, upsmp, unsmp, c1); + } } - double frx = 0.0, fry = 0.0, frz = 0.0; - double cfmp, cfsp, sfmp, sfsp; - complex<double> *vint = new complex<double>[16]; - int jw; - int nsph = gconf->number_of_spheres; - C1 *c1 = new C1(nsph, gconf->l_max, sconf->nshl_vec, sconf->iog_vec); - for (int i = 0; i < nsph; i++) { - c1->ros[i] = sconf->radii_of_spheres[i]; + if (nkks != 0 || jxi == 1) { + upvsp(u, upmp, unmp, us, upsmp, unsmp, up, un, ups, uns, duk, isq, ibf, scan, cfmp, sfmp, cfsp, sfsp); + if (gconf->meridional_type < 0) { + wmasp( + cost, sint, cosp, sinp, costs, sints, cosps, sinps, + u, up, un, us, ups, uns, isq, ibf, gconf->in_pol, + gconf->l_max, 0, nsph, argi, args, c1 + ); + } + for (int i193 = 0; i193 < 3; i193++) { + un[i193] = unmp[i193]; + uns[i193] = unsmp[i193]; + } + } + if (gconf->meridional_type < 0) jw = 1; + tppoan.write(reinterpret_cast<char *>(&th), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&ph), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&ths), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&phs), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&scan), sizeof(double)); + if (jw != 0) { + jw = 0; + tppoan.write(reinterpret_cast<char *>(&(u[0])), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&(u[1])), sizeof(double)); + tppoan.write(reinterpret_cast<char *>(&(u[2])), sizeof(double)); } - C2 *c2 = new C2(nsph, 5, gconf->npnt, gconf->npntts); - argi = new double[1]; - args = new double[1]; - gaps = new double[2]; - FILE *output = fopen((output_path + "/c_OSPH").c_str(), "w"); - fprintf(output, " READ(IR,*)NSPH,LM,INPOL,NPNT,NPNTTS,ISAM\n"); - fprintf( - output, - " %5d%5d%5d%5d%5d%5d\n", - gconf->number_of_spheres, - gconf->l_max, - gconf->in_pol, - gconf->npnt, - gconf->npntts, - gconf->meridional_type - ); - fprintf(output, " READ(IR,*)TH,THSTP,THLST,THS,THSSTP,THSLST\n"); - fprintf( - output, - " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", - gconf->in_theta_start, - gconf->in_theta_step, - gconf->in_theta_end, - gconf->sc_theta_start, - gconf->sc_theta_step, - gconf->sc_theta_end - ); - fprintf(output, " READ(IR,*)PH,PHSTP,PHLST,PHS,PHSSTP,PHSLST\n"); fprintf( - output, - " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", - gconf->in_phi_start, - gconf->in_phi_step, - gconf->in_phi_end, - gconf->sc_phi_start, - gconf->sc_phi_step, - gconf->sc_phi_end - ); - fprintf(output, " READ(IR,*)JWTM\n"); + output, + "********** JTH =%3d, JPH =%3d, JTHS =%3d, JPHS =%3d ********************\n", + jth, jph, jths, jphs + ); fprintf( - output, - " %5d\n", - gconf->jwtm - ); - fprintf(output, " READ(ITIN)NSPHT\n"); - fprintf(output, " READ(ITIN)(IOG(I),I=1,NSPH)\n"); - fprintf(output, " READ(ITIN)EXDC,WP,XIP,IDFC,NXI\n"); - fprintf(output, " READ(ITIN)(XIV(I),I=1,NXI)\n"); - fprintf(output, " READ(ITIN)NSHL(I),ROS(I)\n"); - fprintf(output, " READ(ITIN)(RCF(I,NS),NS=1,NSH)\n \n"); - double sml = 1.0e-3; - int nth = 0, nph = 0; - if (gconf->in_theta_step != 0.0) - nth = int((gconf->in_theta_end - gconf->in_theta_start) / gconf->in_theta_step + sml); - nth += 1; - if (gconf->in_phi_step != 0.0) - nph = int((gconf->in_phi_end - gconf->in_phi_start) / gconf->in_phi_step + sml); - nph += 1; - int nths = 0, nphs = 0; - double thsca; - if (gconf->meridional_type > 1) { // ISAM > 1, fixed scattering angle - nths = 1; - thsca = gconf->sc_theta_start - gconf->in_theta_start; - } else { //ISAM <= 1 - if (gconf->in_theta_step != 0.0) - nths = int((gconf->sc_theta_end - gconf->sc_theta_start) / gconf->sc_theta_step + sml); - nths += 1; - if (gconf->meridional_type == 1) { // ISAM = 1 - nphs = 1; - } else { // ISAM < 1 - if (gconf->sc_phi_step != 0.0) - nphs = int((gconf->sc_phi_end - gconf->sc_phi_start) / gconf->sc_phi_step + sml); - nphs += 1; - } - } - int nk = nth * nph; - int nks = nths * nphs; - int nkks = nk * nks; - double th1 = gconf->in_theta_start; - double ph1 = gconf->in_phi_start; - double ths1 = gconf->sc_theta_start; - double phs1 = gconf->sc_phi_start; - const double half_pi = acos(0.0); - const double pi = 2.0 * half_pi; - double gcs = 0.0; - for (int i116 = 0; i116 < nsph; i116++) { - int i = i116 + 1; - int iogi = c1->iog[i116]; - if (iogi >= i) { - double gcss = pi * c1->ros[i116] * c1->ros[i116]; - c1->gcsv[i116] = gcss; - int nsh = c1->nshl[i116]; - for (int j115 = 0; j115 < nsh; j115++) { - c1->rc[i116][j115] = sconf->rcf[i116][j115] * c1->ros[i116]; - } - } - gcs += c1->gcsv[iogi]; - } - double ****zpv = new double***[gconf->l_max]; //[gconf->l_max][3][2][2]; // Matrix: dim[LM x 3 x 2 x 2] - for (int zi = 0; zi < gconf->l_max; zi++) { - zpv[zi] = new double**[3]; - for (int zj = 0; zj < 3; zj++) { - zpv[zi][zj] = new double*[2]; - for (int zk = 0; zk < 2; zk++) { - zpv[zi][zj][zk] = new double[2](); - } - } - } - thdps(gconf->l_max, zpv); - double exri = sqrt(sconf->exdc); - fprintf(output, " REFR. INDEX OF EXTERNAL MEDIUM=%15.7lE\n", exri); - fstream tppoan; - string tppoan_name = output_path + "/c_TPPOAN_sph"; - tppoan.open(tppoan_name.c_str(), ios::binary|ios::out); - if (tppoan.is_open()) { - int imode = 10; - tppoan.write(reinterpret_cast<char *>(&imode), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&(gconf->meridional_type)), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&(gconf->in_pol)), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&(sconf->number_of_scales)), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&nth), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&nph), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&nths), sizeof(int)); - tppoan.write(reinterpret_cast<char *>(&nphs), sizeof(int)); - - for (int nsi = 0; nsi < nsph; nsi++) - tppoan.write(reinterpret_cast<char *>(&(sconf->iog_vec[nsi])), sizeof(int)); - if (gconf->in_pol == 0) fprintf(output, " LIN\n"); - else fprintf(output, " CIRC\n"); - fprintf(output, " \n"); - double wn = sconf->wp / 3.0e8; - double sqsfi = 1.0; - double vk, vkarg; - if (sconf->idfc < 0) { - vk = sconf->xip * wn; - fprintf(output, " VK=%15.7lE, XI IS SCALE FACTOR FOR LENGTHS\n", vk); - fprintf(output, " \n"); - } - for (int jxi488 = 0; jxi488 < sconf->number_of_scales; jxi488++) { - printf("INFO: running scale iteration...\n"); - int jxi = jxi488 + 1; - fprintf(output, "========== JXI =%3d ====================\n", jxi); - double xi = sconf->scale_vec[jxi488]; - if (sconf->idfc >= 0) { - vk = xi * wn; - vkarg = vk; - fprintf(output, " VK=%15.7lE, XI=%15.7lE\n", xi, vk); - } else { // IDFC < 0 - vkarg = xi * vk; - sqsfi = 1.0 / (xi * xi); - fprintf(output, " XI=%15.7lE\n", xi); - } - tppoan.write(reinterpret_cast<char *>(&vk), sizeof(double)); - for (int i132 = 0; i132 < nsph; i132++) { - int i = i132 + 1; - int iogi = sconf->iog_vec[i132]; - if (iogi != i) { - for (int l123 = 0; l123 < gconf->l_max; l123++) { - c1->rmi[l123][i132] = c1->rmi[l123][iogi - 1]; - c1->rei[l123][i132] = c1->rei[l123][iogi - 1]; - } - continue; // i132 - } - int nsh = sconf->nshl_vec[i132]; - int ici = (nsh + 1) / 2; - if (sconf->idfc == 0) { - for (int ic = 0; ic < ici; ic++) - c2->dc0[ic] = sconf->dc0_matrix[ic][i132][0]; // WARNING: IDFC=0 is not tested! - } else { // IDFC != 0 - if (jxi == 1) { - for (int ic = 0; ic < ici; ic++) { - c2->dc0[ic] = sconf->dc0_matrix[ic][i132][jxi488]; - } - } - } - if (nsh % 2 == 0) c2->dc0[ici] = sconf->exdc; - int jer = 0; - int lcalc = 0; - dme( - gconf->l_max, i, gconf->npnt, gconf->npntts, vkarg, - sconf->exdc, exri, c1, c2, jer, lcalc, arg - ); - if (jer != 0) { - fprintf(output, " STOP IN DME\n"); - fprintf(output, " AT %1d LCALC=%3d TOO SMALL WITH ARG=%15.7lE+i(%15.7lE)\n", jer, lcalc, arg.real(), arg.imag()); - tppoan.close(); - fclose(output); - return; - } - } // i132 - if (sconf->idfc >= 0 and nsph == 1 and jxi == gconf->jwtm) { - // This is the condition that writes the transition matrix to output. - int is = 1111; - fstream ttms; - string ttms_name = output_path + "/c_TTMS_sph"; - ttms.open(ttms_name.c_str(), ios::binary | ios::out); - if (ttms.is_open()) { - ttms.write(reinterpret_cast<char *>(&is), sizeof(int)); - ttms.write(reinterpret_cast<char *>(&(gconf->l_max)), sizeof(int)); - ttms.write(reinterpret_cast<char *>(&vk), sizeof(double)); - ttms.write(reinterpret_cast<char *>(&exri), sizeof(double)); - for (int lmi = 0; lmi < gconf->l_max; lmi++) { - complex<double> element1 = -1.0 / c1->rmi[0][lmi]; - complex<double> element2 = -1.0 / c1->rei[0][lmi]; - ttms.write(reinterpret_cast<char *>(&element1), sizeof(complex<double>)); - ttms.write(reinterpret_cast<char *>(&element2), sizeof(complex<double>)); - } - ttms.write(reinterpret_cast<char *>(&(sconf->radii_of_spheres[0])), sizeof(double)); - ttms.close(); - } else { // Failed to open output file. Should never happen. - printf("ERROR: could not open TTMS file.\n"); - tppoan.close(); - } - } - double cs0 = 0.25 * vk * vk * vk / half_pi; - //printf("DEBUG: cs0 = %lE\n", cs0); - sscr0(tfsas, nsph, gconf->l_max, vk, exri, c1); - //printf("DEBUG: TFSAS = (%lE,%lE)\n", tfsas.real(), tfsas.imag()); - double sqk = vk * vk * sconf->exdc; - aps(zpv, gconf->l_max, nsph, c1, sqk, gaps); - rabas(gconf->in_pol, gconf->l_max, nsph, c1, tqse, tqspe, tqss, tqsps); - for (int i170 = 0; i170 < nsph; i170++) { - int i = i170 + 1; - if (c1->iog[i170] >= i) { - double albeds = c1->sscs[i170] / c1->sexs[i170]; - c1->sqscs[i170] *= sqsfi; - c1->sqabs[i170] *= sqsfi; - c1->sqexs[i170] *= sqsfi; - fprintf(output, " SPHERE %2d\n", i); - if (c1->nshl[i170] != 1) { - fprintf(output, " SIZE=%15.7lE\n", c2->vsz[i170]); - } else { - fprintf( - output, - " SIZE=%15.7lE, REFRACTIVE INDEX=(%15.7lE,%15.7lE)\n", - c2->vsz[i170], - c2->vkt[i170].real(), - c2->vkt[i170].imag() - ); - } - fprintf(output, " ----- SCS ----- ABS ----- EXS ----- ALBEDS --\n"); - fprintf( - output, - " %14.7lE%15.7lE%15.7lE%15.7lE\n", - c1->sscs[i170], c1->sabs[i170], - c1->sexs[i170], albeds - ); - fprintf(output, " ---- SCS/GS -- ABS/GS -- EXS/GS ---\n"); - fprintf( - output, - " %14.7lE%15.7lE%15.7lE\n", - c1->sqscs[i170], c1->sqabs[i170], - c1->sqexs[i170] - ); - fprintf(output, " FSAS=%15.7lE%15.7lE\n", c1->fsas[i170].real(), c1->fsas[i170].imag()); - double csch = 2.0 * vk * sqsfi / c1->gcsv[i170]; - s0 = c1->fsas[i170] * exri; - double qschu = csch * s0.imag(); - double pschu = csch * s0.real(); - double s0mag = cs0 * abs(s0); - fprintf( - output, - " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", - qschu, pschu, s0mag - ); - double rapr = c1->sexs[i170] - gaps[i170]; - double cosav = gaps[i170] / c1->sscs[i170]; - fprintf(output, " COSAV=%15.7lE, RAPRS=%15.7lE\n", cosav, rapr); - fprintf(output, " IPO=%2d, TQEk=%15.7lE, TQSk=%15.7lE\n", 1, tqse[0][i170], tqss[0][i170]); - fprintf(output, " IPO=%2d, TQEk=%15.7lE, TQSk=%15.7lE\n", 2, tqse[1][i170], tqss[1][i170]); - tppoan.write(reinterpret_cast<char *>(&(tqse[0][i170])), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&(tqss[0][i170])), sizeof(double)); - double val = tqspe[0][i170].real(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqspe[0][i170].imag(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqsps[0][i170].real(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqsps[0][i170].imag(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&(tqse[1][i170])), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&(tqss[1][i170])), sizeof(double)); - val = tqspe[1][i170].real(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqspe[1][i170].imag(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqsps[1][i170].real(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - val = tqsps[1][i170].imag(); - tppoan.write(reinterpret_cast<char *>(&val), sizeof(double)); - } // End if iog[i170] >= i - } // i170 loop - if (nsph != 1) { - fprintf(output, " FSAT=(%15.7lE,%15.7lE)\n", tfsas.real(), tfsas.imag()); - double csch = 2.0 * vk * sqsfi / gcs; - s0 = tfsas * exri; - double qschu = csch * s0.imag(); - double pschu = csch * s0.real(); - double s0mag = cs0 * abs(s0); - fprintf( - output, - " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", - qschu, pschu, s0mag - ); - } - th = th1; - for (int jth486 = 0; jth486 < nth; jth486++) { // OpenMP parallelizable section - int jth = jth486 + 1; - ph = ph1; - for (int jph484 = 0; jph484 < nph; jph484++) { - int jph = jph484 + 1; - bool goto182 = (nk == 1) && (jxi > 1); - if (!goto182) { - upvmp(th, ph, 0, cost, sint, cosp, sinp, u, upmp, unmp); - } - if (gconf->meridional_type >= 0) { - wmamp(0, cost, sint, cosp, sinp, gconf->in_pol, gconf->l_max, 0, nsph, argi, u, upmp, unmp, c1); - for (int i183 = 0; i183 < nsph; i183++) { - double rapr = c1->sexs[i183] - gaps[i183]; - frx = rapr * u[0]; - fry = rapr * u[1]; - frz = rapr * u[2]; - } - jw = 1; - } - double thsl = ths1; - double phsph = 0.0; - for (int jths482 = 0; jths482 < nths; jths482++) { - int jths = jths482 + 1; - double ths = thsl; - int icspnv = 0; - if (gconf->meridional_type > 1) ths = th + thsca; - if (gconf->meridional_type >= 1) { - phsph = 0.0; - if ((ths < 0.0) || (ths > 180.0)) phsph = 180.0; - if (ths < 0.0) ths *= -1.0; - if (ths > 180.0) ths = 360.0 - ths; - if (phsph != 0.0) icspnv = 1; - } - double phs = phs1; - for (int jphs480 = 0; jphs480 < nphs; jphs480++) { - int jphs = jphs480 + 1; - if (gconf->meridional_type >= 1) { - phs = ph + phsph; - if (phs >= 360.0) phs -= 360.0; - } - bool goto190 = (nks == 1) && ((jxi > 1) || (jth > 1) || (jph > 1)); - if (!goto190) { - upvmp(ths, phs, icspnv, costs, sints, cosps, sinps, us, upsmp, unsmp); - if (gconf->meridional_type >= 0) { - wmamp(2, costs, sints, cosps, sinps, gconf->in_pol, gconf->l_max, 0, nsph, args, us, upsmp, unsmp, c1); - } - } - if (nkks != 0 || jxi == 1) { - upvsp(u, upmp, unmp, us, upsmp, unsmp, up, un, ups, uns, duk, isq, ibf, scan, cfmp, sfmp, cfsp, sfsp); - if (gconf->meridional_type < 0) { - wmasp( - cost, sint, cosp, sinp, costs, sints, cosps, sinps, - u, up, un, us, ups, uns, isq, ibf, gconf->in_pol, - gconf->l_max, 0, nsph, argi, args, c1 - ); - } - for (int i193 = 0; i193 < 3; i193++) { - un[i193] = unmp[i193]; - uns[i193] = unsmp[i193]; - } - } - if (gconf->meridional_type < 0) jw = 1; - tppoan.write(reinterpret_cast<char *>(&th), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&ph), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&ths), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&phs), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&scan), sizeof(double)); - if (jw != 0) { - jw = 0; - tppoan.write(reinterpret_cast<char *>(&(u[0])), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&(u[1])), sizeof(double)); - tppoan.write(reinterpret_cast<char *>(&(u[2])), sizeof(double)); - } - fprintf( - output, - "********** JTH =%3d, JPH =%3d, JTHS =%3d, JPHS =%3d ********************\n", - jth, jph, jths, jphs - ); - fprintf( - output, - " TIDG=%10.3lE, PIDG=%10.3lE, TSDG=%10.3lE, PSDG=%10.3lE\n", - th, ph, ths, phs - ); - fprintf(output, " SCAND=%10.3lE\n", scan); - fprintf(output, " CFMP=%15.7lE, SFMP=%15.7lE\n", cfmp, sfmp); - fprintf(output, " CFSP=%15.7lE, SFSP=%15.7lE\n", cfsp, sfsp); - if (gconf->meridional_type >= 0) { - fprintf(output, " UNI=(%12.5lE,%12.5lE,%12.5lE)\n", un[0], un[1], un[2]); - fprintf(output, " UNS=(%12.5lE,%12.5lE,%12.5lE)\n", uns[0], uns[1], uns[2]); - } else { - fprintf(output, " UN=(%12.5lE,%12.5lE,%12.5lE)\n", un[0], un[1], un[2]); - } - sscr2(nsph, gconf->l_max, vk, exri, c1); - for (int ns226 = 0; ns226 < nsph; ns226++) { - int ns = ns226 + 1; - fprintf(output, " SPHERE %2d\n", ns); - fprintf( - output, " SAS(1,1)=%15.7lE%15.7lE, SAS(2,1)=%15.7lE%15.7lE\n", - c1->sas[ns226][0][0].real(), c1->sas[ns226][0][0].imag(), - c1->sas[ns226][1][0].real(), c1->sas[ns226][1][0].imag() - ); - fprintf( - output, " SAS(1,2)=%15.7lE%15.7lE, SAS(2,2)=%15.7lE%15.7lE\n", - c1->sas[ns226][0][1].real(), c1->sas[ns226][0][1].imag(), - c1->sas[ns226][1][1].real(), c1->sas[ns226][1][1].imag() - ); - if (jths == 1 && jphs == 1) - fprintf( - output, " Fx=%15.7lE, Fy=%15.7lE, Fz=%15.7lE\n", - frx, fry, frz - ); - for (int i225 = 0; i225 < 16; i225++) vint[i225] = c1->vints[ns226][i225]; - mmulc(vint, cmullr, cmul); - fprintf(output, " MULS\n "); - for (int imul = 0; imul < 4; imul++) { - for (int jmul = 0; jmul < 4; jmul++) { - fprintf(output, "%15.7lE", cmul[imul][jmul]); - } - if (imul < 3) fprintf(output, "\n "); - else fprintf(output, "\n"); - } - fprintf(output, " MULSLR\n "); - for (int imul = 0; imul < 4; imul++) { - for (int jmul = 0; jmul < 4; jmul++) { - fprintf(output, "%15.7lE", cmullr[imul][jmul]); - } - if (imul < 3) fprintf(output, "\n "); - else fprintf(output, "\n"); - } - for (int vi = 0; vi < 16; vi++) { - double value = vint[vi].real(); - tppoan.write(reinterpret_cast<char *>(&value), sizeof(double)); - value = vint[vi].imag(); - tppoan.write(reinterpret_cast<char *>(&value), sizeof(double)); - } - for (int imul = 0; imul < 4; imul++) { - for (int jmul = 0; jmul < 4; jmul++) { - tppoan.write(reinterpret_cast<char *>(&(cmul[imul][jmul])), sizeof(double)); - } - } - } // ns226 loop - if (gconf->meridional_type < 1) phs += gconf->sc_phi_step; - } // jphs480 loop - if (gconf->meridional_type <= 1) thsl += gconf->sc_theta_step; - } // jths482 loop - ph += gconf->in_phi_step; - } // jph484 loop on elevation - th += gconf->in_theta_step; - } // jth486 loop on azimuth - printf("INFO: done scale.\n"); - } //jxi488 loop on scales - tppoan.close(); - } else { // In case TPPOAN could not be opened. Should never happen. - printf("ERROR: failed to open TPPOAN file.\n"); - } - fclose(output); - delete c1; - delete c2; - for (int zi = gconf->l_max - 1; zi > -1; zi--) { - for (int zj = 0; zj < 3; zj++) { - for (int zk = 0; zk < 2; zk++) { - delete[] zpv[zi][zj][zk]; - } - delete[] zpv[zi][zj]; - } - delete[] zpv[zi]; - } - delete[] zpv; - delete[] duk; - delete[] u; - delete[] us; - delete[] un; - delete[] uns; - delete[] up; - delete[] ups; - delete[] upmp; - delete[] upsmp; - delete[] unmp; - delete[] unsmp; - delete[] vint; - delete[] argi; - delete[] args; - delete[] gaps; - for (int i = 3; i > -1; i--) { - delete[] cmul[i]; - delete[] cmullr[i]; - } - delete[] cmul; - delete[] cmullr; - for (int ti = 1; ti > -1; ti--) { - delete[] tqse[ti]; - delete[] tqss[ti]; - delete[] tqspe[ti]; - delete[] tqsps[ti]; + output, + " TIDG=%10.3lE, PIDG=%10.3lE, TSDG=%10.3lE, PSDG=%10.3lE\n", + th, ph, ths, phs + ); + fprintf(output, " SCAND=%10.3lE\n", scan); + fprintf(output, " CFMP=%15.7lE, SFMP=%15.7lE\n", cfmp, sfmp); + fprintf(output, " CFSP=%15.7lE, SFSP=%15.7lE\n", cfsp, sfsp); + if (gconf->meridional_type >= 0) { + fprintf(output, " UNI=(%12.5lE,%12.5lE,%12.5lE)\n", un[0], un[1], un[2]); + fprintf(output, " UNS=(%12.5lE,%12.5lE,%12.5lE)\n", uns[0], uns[1], uns[2]); + } else { + fprintf(output, " UN=(%12.5lE,%12.5lE,%12.5lE)\n", un[0], un[1], un[2]); } - delete[] tqse; - delete[] tqss; - delete[] tqspe; - delete[] tqsps; - printf("Finished: output written to %s.\n", (output_path + "/c_OSPH").c_str()); - } else { // NSPH mismatch between geometry and scatterer configurations. - throw UnrecognizedConfigurationException( - "Inconsistent geometry and scatterer configurations." - ); + sscr2(nsph, gconf->l_max, vk, exri, c1); + for (int ns226 = 0; ns226 < nsph; ns226++) { + int ns = ns226 + 1; + fprintf(output, " SPHERE %2d\n", ns); + fprintf( + output, " SAS(1,1)=%15.7lE%15.7lE, SAS(2,1)=%15.7lE%15.7lE\n", + c1->sas[ns226][0][0].real(), c1->sas[ns226][0][0].imag(), + c1->sas[ns226][1][0].real(), c1->sas[ns226][1][0].imag() + ); + fprintf( + output, " SAS(1,2)=%15.7lE%15.7lE, SAS(2,2)=%15.7lE%15.7lE\n", + c1->sas[ns226][0][1].real(), c1->sas[ns226][0][1].imag(), + c1->sas[ns226][1][1].real(), c1->sas[ns226][1][1].imag() + ); + if (jths == 1 && jphs == 1) + fprintf( + output, " Fx=%15.7lE, Fy=%15.7lE, Fz=%15.7lE\n", + frx, fry, frz + ); + for (int i225 = 0; i225 < 16; i225++) vint[i225] = c1->vints[ns226][i225]; + mmulc(vint, cmullr, cmul); + fprintf(output, " MULS\n "); + for (int imul = 0; imul < 4; imul++) { + for (int jmul = 0; jmul < 4; jmul++) { + fprintf(output, "%15.7lE", cmul[imul][jmul]); + } + if (imul < 3) fprintf(output, "\n "); + else fprintf(output, "\n"); + } + fprintf(output, " MULSLR\n "); + for (int imul = 0; imul < 4; imul++) { + for (int jmul = 0; jmul < 4; jmul++) { + fprintf(output, "%15.7lE", cmullr[imul][jmul]); + } + if (imul < 3) fprintf(output, "\n "); + else fprintf(output, "\n"); + } + for (int vi = 0; vi < 16; vi++) { + double value = vint[vi].real(); + tppoan.write(reinterpret_cast<char *>(&value), sizeof(double)); + value = vint[vi].imag(); + tppoan.write(reinterpret_cast<char *>(&value), sizeof(double)); + } + for (int imul = 0; imul < 4; imul++) { + for (int jmul = 0; jmul < 4; jmul++) { + tppoan.write(reinterpret_cast<char *>(&(cmul[imul][jmul])), sizeof(double)); + } + } + } // ns226 loop + if (gconf->meridional_type < 1) phs += gconf->sc_phi_step; + } // jphs480 loop + if (gconf->meridional_type <= 1) thsl += gconf->sc_theta_step; + } // jths482 loop + ph += gconf->in_phi_step; + } // jph484 loop on elevation + th += gconf->in_theta_step; + } // jth486 loop on azimuth + printf("INFO: done scale.\n"); + } //jxi488 loop on scales + tppoan.close(); + } else { // In case TPPOAN could not be opened. Should never happen. + printf("ERROR: failed to open TPPOAN file.\n"); + } + fclose(output); + delete c1; + delete c2; + for (int zi = gconf->l_max - 1; zi > -1; zi--) { + for (int zj = 0; zj < 3; zj++) { + for (int zk = 0; zk < 2; zk++) { + delete[] zpv[zi][zj][zk]; } - delete sconf; - delete gconf; + delete[] zpv[zi][zj]; + } + delete[] zpv[zi]; + } + delete[] zpv; + delete[] duk; + delete[] u; + delete[] us; + delete[] un; + delete[] uns; + delete[] up; + delete[] ups; + delete[] upmp; + delete[] upsmp; + delete[] unmp; + delete[] unsmp; + delete[] vint; + delete[] argi; + delete[] args; + delete[] gaps; + for (int i = 3; i > -1; i--) { + delete[] cmul[i]; + delete[] cmullr[i]; + } + delete[] cmul; + delete[] cmullr; + for (int ti = 1; ti > -1; ti--) { + delete[] tqse[ti]; + delete[] tqss[ti]; + delete[] tqspe[ti]; + delete[] tqsps[ti]; + } + delete[] tqse; + delete[] tqss; + delete[] tqspe; + delete[] tqsps; + printf("Finished: output written to %s.\n", (output_path + "/c_OSPH").c_str()); + } else { // NSPH mismatch between geometry and scatterer configurations. + throw UnrecognizedConfigurationException( + "Inconsistent geometry and scatterer configurations." + ); + } + delete sconf; + delete gconf; }