Skip to content
Snippets Groups Projects
Commit 9c447a2d authored by Giacomo Mulas's avatar Giacomo Mulas
Browse files

Merge branch 'sphere' into 'master'

Sphere

See merge request giacomo.mulas/np_tmcode!6
parents f6a3008c 8aeb080d
Branches
Tags
No related merge requests found
......@@ -3,3 +3,4 @@ build/cluster/*
build/sphere/*
build/trapping/*
doc/build/*
SUBDIRS := cluster sphere trapping
BUILDDIR=../build
SRCDIR=$(PWD)
BUILDDIR=$(SRCDIR)/../build
DOCSDIR=$(SRCDIR)/../doc
all: $(SUBDIRS)
docs:
cd $(DOCSDIR)/src; doxygen config.dox
$(SUBDIRS):
$(MAKE) -C $@
......@@ -15,5 +20,7 @@ wipe:
rm -f $(BUILDDIR)/cluster/*
rm -f $(BUILDDIR)/sphere/*
rm -f $(BUILDDIR)/trapping/*
if [ -d $(DOCSDIR)/build/html ]; then rm -r $(DOCSDIR)/build/html; fi
if [ -d $(DOCSDIR)/build/latex ]; then rm -r $(DOCSDIR)/build/latex; fi
.PHONY: all $(SUBDIRS)
......@@ -7,3 +7,27 @@ This directory collects the source code of the original programs and the develop
The original code is contained in the folders named `cluster`, `sphere` and `trapping`. Each folder contains a `Makefile` to compile either the whole program set or the single programs. A global `Makefile`, which contains instructions to build all the original source code, is available directly in the `src` folder.
In all cases, build commands executed through `make` will output the object files and the linked binaries in the proper folders under the build directory.
## FORTRAN code setup and execution (requires `gfortran` and GNU `make`)
1. cd to the `src` folder
2. run `make`
> make
3. cd to the `build/sphere` folder
4. run `sph` following the instructions given in `build\README.md`
## C++ code setup and execution (requires `g++` and GNU `make`)
1. cd to the `src` folder
2. run `make np_sphere`
> make np_sphere
3. cd to the `build/sphere` folder
4. run `np_sphere`
> ./np_sphere
5. check the consistency between the text files named `OSPH` and `c_OSPH`
/*! \file Commons.h
*
* \brief C++ porting of common data structures.
*
* Many functions of the original FORTRAN code share complex data blocks in
* form of COMMON blocks. This poses the limit of freezing the structure of
* the data blocks in the code, therefore implying the necessity to modify
* the code to adapt it to the input and to recompile before running. C++,
* on the contrary, offers the possibility to represent the necessary data
* structures as classes that can dinamically instantiate the shared information
* in the most convenient format for the current configuration. This approach
* adds an abstraction layer that lifts the need to modify and recompile the
* code depending on the input.
*
*/
#ifndef SRC_INCLUDE_COMMONS_
#define SRC_INCLUDE_COMMONS_
#include <complex>
/*! \brief Representation of the FORTRAN C1 common blocks.
*
* C1 common blocks are used to store vector field expansions and geometric
* properties, such as sphere sizes, positions and cross-sections. These are
* used by functions such as `aps`, `diel`, `pwma`, `rabas`, `sscr0`, `sscr2`,
* `wmamp`, `wmasp` and `dme`. QUESTION: correct?
*
* Due to the necessity to share the class contents with many functions that
* need to read and update various fields, all shared members of C1 are declared
* public (i.e., the class is just a structure with more advanced constructor
* and destroyer). Further development may go in the direction of creating
* a better encapsulation, either by unpacking the contents (recommended) or
* by creating public methods to access protected fields (standard way, but not
* recommended for HPC applications).
*/
class C1 {
protected:
//! \brief Number of spheres.
int nsph;
//! \brief Maximum order of field expansion.
int lm;
//! \brief NLMMT. QUESTION: definition?
int nlmmt;
public:
//! \brief QUESTION: definition?
std::complex<double> **rmi;
//! \brief QUESTION: definition?
std::complex<double> **rei;
//! \brief QUESTION: definition?
std::complex<double> **w;
//! \brief QUESTION: definition?
std::complex<double> *fsas;
//! \brief QUESTION: definition?
std::complex<double> **vints;
//! \brief QUESTION: definition?
double *sscs;
//! \brief QUESTION: definition?
double *sexs;
//! \brief QUESTION: definition?
double *sabs;
//! \brief QUESTION: definition?
double *sqscs;
//! \brief QUESTION: definition?
double *sqexs;
//! \brief QUESTION: definition?
double *sqabs;
//! \brief QUESTION: definition?
double *gcsv;
//! \brief Vector of sphere X coordinates.
double *rxx;
//! \brief Vector of sphere X coordinates.
double *ryy;
//! \brief Vector of sphere X coordinates.
double *rzz;
//! \brief Vector of sphere radii.
double *ros;
//! \brief Matrix of spherical layer break radii. QUESTION: correct?
double **rc;
//! \brief Vector of spherical component identifiers.
int *iog;
//! \brief Vector of numbers of spherical layers.
int *nshl;
//! \brief QUESTION: definition?
std::complex<double> ***sas;
/*! \brief C1 instance constructor.
*
* \param ns: `int` Number of spheres.
* \param l_max: `int` Maximum order of field expansion.
*/
C1(int ns, int l_max);
//! \brief C1 instance destroyer.
~C1();
};
/*! \brief Representation of the FORTRAN C2 blocks.
*
*/
class C2 {
//! \brief Number of spheres.
int nsph;
//! \brief Number of required orders.
int nhspo;
public:
//! \brief QUESTION: definition?
std::complex<double> *ris;
//! \brief QUESTION: definition?
std::complex<double> *dlri;
//! \brief QUESTION: definition?
std::complex<double> *dc0;
//! \brief QUESTION: definition?
std::complex<double> *vkt;
//! Vector of scaled sizes. QUESTION: correct?
double *vsz;
/*! \brief C2 instance constructor.
*
* \param ns: `int` Number of spheres.
* \param nl: `int`
* \param npnt: `int`
* \param npntts: `int`
*/
C2(int ns, int nl, int npnt, int npntts);
//! \brief C2 instance destroyer.
~C2();
};
#endif
/*! \file Configuration.h
*/
#ifndef INCLUDE_CONFIGURATION_H_
#define INCLUDE_CONFIGURATION_H_
#include <complex>
#include <exception>
#include <string>
/**
* \brief Exception for open file error handlers.
*/
class OpenConfigurationFileException: public std::exception {
protected:
//! \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 message.
*/
virtual const char* what() const throw() {
std::string message = "Error opening configuration file: " + file_name;
return message.c_str();
}
};
/**
* \brief Exception for unrecognized configuration data sets.
*/
class UnrecognizedConfigurationException: public std::exception {
protected:
//! 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 A class to represent the configuration of the scattering geometry.
*
* GeometryConfiguration is a class designed to store the necessary configuration
* data to describe the scattering geometry, including the distribution of the
* particle components, the orientation of the incident and scattered radiation
* fields and their polarization properties.
*/
class GeometryConfiguration {
//! Temporary work-around to allow sphere() peeking in.
friend void sphere();
protected:
//! \brief Number of spherical components.
int number_of_spheres;
//! \brief Maximum expansion order of angular momentum.
int l_max;
//! \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 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,
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
);
/*! \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 A class to represent scatterer configuration objects.
*
* ScattererConfiguration is a class designed to store the necessary configuration
* data to describe the scatterer properties.
*/
class ScattererConfiguration {
//! Temporary work-around to allow sphere() peeking in.
friend void sphere();
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;
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 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 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 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);
};
#endif
/*! \file List.h
*/
#ifndef LIST_OUT_OF_BOUNDS_EXCEPTION
#define LIST_OUT_OF_BOUNDS_EXCEPTION 1
#endif
#ifndef INCLUDE_LIST_H_
#define INCLUDE_LIST_H_
#include <exception>
#include <string>
/**
* \brief Exception for out of bounds List requests.
*/
class ListOutOfBoundsException: public std::exception {
protected:
//! \brief Minimum index defined in the List.
int min_index;
//! \brief Maximum index defined in the List.
int max_index;
//! \brief List index requested by user.
int requested_index;
public:
/**
* \brief Exception instance constructor.
*
* \param requested: `int` The index that was requested.
* \param min: `int` The minimum index allowed by the list.
* \param max: `int` The maximum index allowed by the list.
*/
ListOutOfBoundsException(int requested, int min, int max) {
min_index = min;
max_index = max;
requested_index = requested;
}
/**
* \brief Exception message.
*/
virtual const char* what() const throw() {
std::string message = "Error: requested index ";
message += requested_index;
message += " is out of range [";
message += min_index;
message += ", ";
message += (max_index - 1);
message += "]";
return message.c_str();
}
};
/**
* \brief A class to represent dynamic lists.
......@@ -16,7 +58,7 @@
*
* For this reason, the best use of List objects is to collect all the
* desired members and then, once the element number is known, to convert
* the List to C array, by calling List.to_array(). This function returns
* the List to C array, by calling `List.to_array()`. This function returns
* a contiguous array of type T[SIZE] that can be used for indexed access.
*/
template<class T> class List {
......@@ -33,18 +75,19 @@ template<class T> class List {
public:
/*! \brief List constructor.
*
* Use the constructor List<T>([int length]) to create a new list with a given
* Use the constructor `List<T>([int length])` to create a new list with a given
* size. If the required size is not known in advance, it is recommended
* to create a List with SIZE=1 (this is the default behavior) and then
* to append the elements dynamically, using List.append(ELEMENT) (where
* to append the elements dynamically, using `List.append(ELEMENT)` (where
* ELEMENT needs to be a value of type T, corresponding to the class
* template specialization). Note that, due to the default behavior, the
* following calls are equivalent and they both produce an integer List
* with size equal to 1:
*
* a = List<int>(1);
*
* b = List<int>();
* \code{.cpp}
* List<int> a = List<int>(1);
* List<int> b = List<int>();
* \endcode
*
* \param length: `int` The size of the list to be constructed [OPTIONAL, default=1].
*/
......@@ -52,7 +95,7 @@ template<class T> class List {
size = length;
first = new element;
first->p_prev = NULL;
element *current = first;
current = first;
element *p_prev = first;
for (int i = 1; i < size; i++) {
current = new element;
......@@ -62,6 +105,8 @@ template<class T> class List {
last = current;
}
/*! \brief Destroy a List instance.
*/
~List() {
current = last;
element *old;
......@@ -72,14 +117,14 @@ template<class T> class List {
}
}
/*! \brief Append an element at the end of the list.
/*! \brief Append an element at the end of the List.
*
* To dynamically create a list whose size is not known in advance,
* elements can be appended in an iterative way. Note that element
* manipulation is much more effective in a C array than in a List
* object. For this reason, after the List has been created, it is
* strongly advised to convert it to a C array by calling the function
* List.to_array().
* `List.to_array()`.
*
* \param value: `T` The value of the element to be appended.
*/
......@@ -99,22 +144,22 @@ template<class T> class List {
*
* \param index: `int` The index of the element to be retrieved. 0 for first.
* \return value `T` The value of the element at the requested position.
* \throws LIST_OUT_OF_BOUNDS_EXCEPTION: Raised if the index is out of bounds.
* \throws ListOutOfBoundsException: Raised if the index is out of bounds.
*/
T get(int index) {
if (index < 0 || index > size - 1) {
throw LIST_OUT_OF_BOUNDS_EXCEPTION;
throw ListOutOfBoundsException(index, 0, size - 1);
}
current = last;
for (int i = size - 1; i > index; i--) current = current->p_prev;
return current->value;
}
/*! \brief Get the number of elements in the list.
/*! \brief Get the number of elements in the List.
*
* Get the number of elements currently stored in the list.
* Get the number of elements currently stored in the List.
*
* \return size `int` The size of the list.
* \return size `int` The size of the List.
*/
int length() {
return size;
......@@ -127,11 +172,11 @@ template<class T> class List {
*
* \param index: `int` The index of the element to be set. 0 for first.
* \param value: `int` The value to store in the pointed element.
* \throws LIST_OUT_OF_BOUNDS_EXCEPTION: Raised if the index is out of bounds.
* \throws ListOutOfBoundsException: Raised if the index is out of bounds.
*/
void set(int index, T value) {
if (index < 0 || index > size - 1) {
throw LIST_OUT_OF_BOUNDS_EXCEPTION;
throw ListOutOfBoundsException(index, 0, size - 1);
}
current = last;
for (int i = size - 1; i > index; i--) current = current->p_prev;
......@@ -145,7 +190,7 @@ template<class T> class List {
* resulting object is not contiguosly stored in memory. As a result,
* access to specific elements in the middle of the list is not very
* effective, because the list needs to be walked every time up to
* the desired position. In order to avoid this, List.to_array() makes
* the desired position. In order to avoid this, `List.to_array()` makes
* a conversion from List to C array, returning a contiguous object,
* where indexed access can be used.
*
......@@ -161,3 +206,5 @@ template<class T> class List {
return array;
}
};
#endif
/*! \file Parsers.h
*/
#ifndef INCLUDE_PARSERS_H_
#define INCLUDE_PARSERS_H_
#ifndef FILE_NOT_FOUND_ERROR
//! Error code if a file is not found.
#define FILE_NOT_FOUND_ERROR 21
#endif
/*! \brief Load a text file as a sequence of strings in memory.
*
* The configuration of the field expansion code in FORTRAN uses
* shared memory access and file I/O operations managed by different
* functions. Although this approach could be theoretically replicated,
* it is more convenient to handle input and output to distinct files
* using specific functions. load_file() helps in the task of handling
* input such as configuration files or text data structures that need
* to be loaded entirely. The function performs a line-by line scan of
* the input file and returns an array of strings that can be later
* parsed and ingested by the concerned code blocks. An optional pointer
* to integer allows the function to keep track of the number of file
* lines that were read, if needed.
*
* \param file_name: `string` The path of the file to be read.
* \param count: `int*` Pointer to an integer recording the number of
* read lines [OPTIONAL, default=NULL].
* \return array_lines `string*` An array of strings, one for each input
* file line.
*/
std::string *load_file(std::string file_name, int *count);
#endif /* INCLUDE_PARSERS_H_ */
This diff is collapsed.
/*! \file Commons.cpp
*
*/
#include "../include/Commons.h"
using namespace std;
C1::C1(int ns, int l_max) {
nlmmt = 2 * (l_max * (l_max + 2));
nsph = ns;
lm = l_max;
rmi = new complex<double>*[lm];
rei = new complex<double>*[lm];
for (int ri = 0; ri < lm; ri++) {
rmi[ri] = new complex<double>[nsph];
rei[ri] = new complex<double>[nsph];
}
w = new complex<double>*[nlmmt];
for (int wi = 0; wi < nlmmt; wi++) w[wi] = new complex<double>[4];
vints = new complex<double>*[nsph];
rc = new double*[nsph];
for (int vi = 0; vi < nsph; vi++) {
rc[vi] = new double[lm];
vints[vi] = new complex<double>[16];
}
fsas = new complex<double>[nsph];
sscs = new double[nsph];
sexs = new double[nsph];
sabs = new double[nsph];
sqscs = new double[nsph];
sqexs = new double[nsph];
sqabs = new double[nsph];
gcsv = new double[nsph];;
rxx = new double[nsph];
ryy = new double[nsph];
rzz = new double[nsph];
ros = new double[nsph];
iog = new int[nsph];
nshl = new int[nsph];
sas = new complex<double>**[nsph];
for (int si = 0; si < nsph; si++) {
sas[si] = new complex<double>*[2];
sas[si][0] = new complex<double>[2];
sas[si][1] = new complex<double>[2];
}
}
C1::~C1() {
delete[] rmi;
delete[] rei;
for (int wi = 1; wi <= nlmmt; wi++) delete[] w[wi];
for (int vi = 1; vi <= nsph; vi++) {
delete[] rc[nsph - vi];
delete[] vints[nsph - vi];
}
for (int si = 1; si <= nsph; si++) {
delete[] sas[nsph - si][1];
delete[] sas[nsph - si][0];
}
delete[] fsas;
delete[] sscs;
delete[] sexs;
delete[] sabs;
delete[] sqscs;
delete[] sqexs;
delete[] sqabs;
delete[] gcsv;
delete[] rxx;
delete[] ryy;
delete[] rzz;
delete[] ros;
delete[] iog;
delete[] nshl;
}
C2::C2(int ns, int nl, int npnt, int npntts) {
nsph = ns;
int max_n = (npnt > npntts) ? npnt : npntts;
nhspo = 2 * max_n - 1;
ris = new complex<double>[nhspo];
dlri = new complex<double>[nhspo];
vkt = new complex<double>[nsph];
dc0 = new complex<double>[nl];
vsz = new double[nsph];
}
C2::~C2() {
delete[] ris;
delete[] dlri;
delete[] vkt;
delete[] dc0;
delete[] vsz;
}
This diff is collapsed.
/*! \file Parsers.cpp
*/
#include <fstream>
#include <string>
#include "../include/List.h"
#include "../include/Parsers.h"
std::string *load_file(std::string file_name, int *count = 0) {
std::fstream input_file(file_name.c_str(), std::ios::in);
List<std::string> file_lines = List<std::string>();
std::string line;
if (input_file.is_open()) {
getline(input_file, line);
file_lines.set(0, line);
while (getline(input_file, line)) {
file_lines.append(line);
}
input_file.close();
} else {
throw FILE_NOT_FOUND_ERROR;
}
std::string *array_lines = file_lines.to_array();
if (count != 0) *count = file_lines.length();
return array_lines;
}
/*! \file np_sphere.cpp
*/
#include <cstdio>
#include <string>
#include "include/Configuration.h"
using namespace std;
extern void sphere();
/*! \brief Main program entry point.
*
* This is the starting point of the execution flow. Here we may choose
* how to configure the code, e.g. by loading a legacy configuration file
* or some otherwise formatted configuration data set. The code can be
* linked to a luncher script or to a GUI oriented application that performs
* the configuration and runs the main program.
*/
int main(int argc, char **argv) {
sphere();
return 0;
}
......@@ -2,8 +2,11 @@ BUILDDIR=../../build/sphere
FC=gfortran
FCFLAGS=-std=legacy -O3
LFLAGS=
CXX=g++
CXXFLAGS=-O0 -ggdb -pg -coverage
CXXLFLAGS=
all: edfb sph
all: edfb sph np_sphere
edfb: edfb.o
$(FC) $(FCFLAGS) -o $(BUILDDIR)/edfb $(BUILDDIR)/edfb.o $(LFLAGS)
......@@ -11,6 +14,24 @@ edfb: edfb.o
sph: sph.o
$(FC) $(FCFLAGS) -o $(BUILDDIR)/sph $(BUILDDIR)/sph.o $(LFLAGS)
np_sphere: $(BUILDDIR)/np_sphere.o $(BUILDDIR)/Commons.o $(BUILDDIR)/Configuration.o $(BUILDDIR)/Parsers.o $(BUILDDIR)/sphere.o
$(CXX) $(CXXFLAGS) $(CXXLFLAGS) -o $(BUILDDIR)/np_sphere $(BUILDDIR)/np_sphere.o $(BUILDDIR)/Commons.o $(BUILDDIR)/Configuration.o $(BUILDDIR)/Parsers.o $(BUILDDIR)/sphere.o
$(BUILDDIR)/np_sphere.o:
$(CXX) $(CXXFLAGS) -c ../np_sphere.cpp -o $(BUILDDIR)/np_sphere.o
$(BUILDDIR)/Commons.o:
$(CXX) $(CXXFLAGS) -c ../libnptm/Commons.cpp -o $(BUILDDIR)/Commons.o
$(BUILDDIR)/Configuration.o:
$(CXX) $(CXXFLAGS) -c ../libnptm/Configuration.cpp -o $(BUILDDIR)/Configuration.o
$(BUILDDIR)/Parsers.o:
$(CXX) $(CXXFLAGS) -c ../libnptm/Parsers.cpp -o $(BUILDDIR)/Parsers.o
$(BUILDDIR)/sphere.o:
$(CXX) $(CXXFLAGS) -c sphere.cpp -o $(BUILDDIR)/sphere.o
clean:
rm -f $(BUILDDIR)/*.o
......
......@@ -83,9 +83,9 @@ CCC DIMENSION DC0M(NSPH,NSHL-NTL),XIV(NXI)
6991 FORMAT('========== JXI =',I3,' ====================')
6992 FORMAT('********** JTH =',I3,', JPH =',I3,
1', JTHS =',I3,', JPHS =',I3,' ********************')
IR=5
IW=6
IT=7
IR=25
IW=26
IT=27
ITIN=17
CCC
CCC OTHER COMMENTS IN FILE GLOBALCOMS
......@@ -270,6 +270,7 @@ C
CS0=0.25D0*VK*VK*VK/PIGH
CALL SSCR0(TFSAS,NSPH,LM,VK,EXRI)
PRINT *,"DEBUG: TFSAS =", TFSAS
SQK=VK*VK*EXDC
CALL APS(ZPV,LM,NSPH,IOG,RMI,REI,SQK,GAPS)
CALL RABAS(INPOL,LM,NSPH,IOG,RMI,REI,TQSE,TQSPE,TQSS,TQSPS)
......@@ -455,11 +456,19 @@ CCC 1TQSE(2,NSPH),TQSPE(2,NSPH),TQSS(2,NSPH),TQSPS(2,NSPH)
TQSPE(2,I)=TQSPE(2,I)*PIG2
TQSPS(1,I)=TQSPS(1,I)*PIG2
TQSPS(2,I)=TQSPS(2,I)*PIG2
PRINT *,"DEBUG: TQSPE(1,",I,") =",TQSPE(1,I)
PRINT *,"DEBUG: TQSPE(2,",I,") =",TQSPE(2,I)
PRINT *,"DEBUG: TQSPS(1,",I,") =",TQSPS(1,I)
PRINT *,"DEBUG: TQSPS(2,",I,") =",TQSPS(2,I)
GO TO 80
75 TQSE(1,I)=TQSE(1,I)*PIG2
TQSE(2,I)=TQSE(2,I)*PIG2
TQSS(1,I)=TQSS(1,I)*PIG2
TQSS(2,I)=TQSS(2,I)*PIG2
PRINT *,"DEBUG: TQSE(1,",I,") =",TQSE(1,I)
PRINT *,"DEBUG: TQSE(2,",I,") =",TQSE(2,I)
PRINT *,"DEBUG: TQSS(1,",I,") =",TQSS(1,I)
PRINT *,"DEBUG: TQSS(2,",I,") =",TQSS(2,I)
80 CONTINUE
RETURN
END
......@@ -575,6 +584,7 @@ CCC 1TQSE(2,NSPH),TQSPE(2,NSPH),TQSS(2,NSPH),TQSPS(2,NSPH)
PIGFSQ=6.4D+1*DACOS(C0)**2
CFSQ=4.0D0/(PIGFSQ*CCS*CCS)
NLMM=LM*(LM+2)
C PRINT *,"DEBUG: in SSCR2 W(1,1) =",W(1,1)
DO 14 I=1,NSPH
IOGI=IOG(I)
IF(IOGI.LT.I)GO TO 14
......@@ -586,14 +596,30 @@ CCC 1TQSE(2,NSPH),TQSPE(2,NSPH),TQSS(2,NSPH),TQSPS(2,NSPH)
DO 10 L=1,LM
RM=1.0D0/RMI(L,I)
RE=1.0D0/REI(L,I)
C PRINT *,"DEBUG: RM =",RM
C PRINT *,"DEBUG: RE =",RE
LTPO=L+L+1
DO 10 IM=1,LTPO
K=K+1
KE=K+NLMM
C PRINT *,"DEBUG: W(",K,",3) =",W(K,3)
C PRINT *,"DEBUG: W(",K,",1) =",W(K,1)
C PRINT *,"DEBUG: W(",KE,",3) =",W(KE,3)
C PRINT *,"DEBUG: W(",KE,",1) =",W(KE,1)
S11=S11-W(K,3)*W(K,1)*RM-W(KE,3)*W(KE,1)*RE
C PRINT *,"DEBUG: S11 =",S11
C PRINT *,"DEBUG: W(",K,",4) =",W(K,4)
C PRINT *,"DEBUG: W(",KE,",4) =",W(KE,4)
S21=S21-W(K,4)*W(K,1)*RM-W(KE,4)*W(KE,1)*RE
C PRINT *,"DEBUG: W(",K,",2) =",W(K,2)
C PRINT *,"DEBUG: W(",KE,",2) =",W(KE,2)
S12=S12-W(K,3)*W(K,2)*RM-W(KE,3)*W(KE,2)*RE
10 S22=S22-W(K,4)*W(K,2)*RM-W(KE,4)*W(KE,2)*RE
C PRINT *,"DEBUG: CSAM =",CSAM
C PRINT *,"DEBUG: S11 =",S11
C PRINT *,"DEBUG: S21 =",S21
C PRINT *,"DEBUG: S12 =",S12
C PRINT *,"DEBUG: S22 =",S22
SAS(I,1,1)=S11*CSAM
SAS(I,2,1)=S21*CSAM
SAS(I,1,2)=S12*CSAM
......@@ -644,6 +670,7 @@ CCC 1RMI(LI,NSPH),REI(LI,NSPH),GAPS(NSPH)
1CG1(LMPML,0,L,1)*(SUMM+SUME+SUEM+SUEE))*COFL
30 CONTINUE
GAPS(I)=DREAL(SUM)*COFS
PRINT *,"DEBUG: GAPS(",I,") =",GAPS(I)
40 CONTINUE
RETURN
END
......@@ -664,6 +691,11 @@ CCC DIMENSION ZPV(LM,3,2,2)
ZP=-1.0D0/DSQRT(XD)
ZPV(L,2,1,2)=ZP
ZPV(L,2,2,1)=ZP
IF(ZP.EQ.C0) GOTO 15
C PRINT 9010,L-1,ZP
C PRINT 9011,L-1,ZP
9010 FORMAT("DEBUG: zpv[",I1,"][1][0][1] = ",E15.3)
9011 FORMAT("DEBUG: zpv[",I1,"][1][1][0] = ",E15.3)
15 CONTINUE
IF(LM.EQ.1)GO TO 30
DO 20 L=2,LM
......@@ -672,6 +704,11 @@ CCC DIMENSION ZPV(LM,3,2,2)
ZP=DSQRT(XN/XD)
ZPV(L,1,1,1)=ZP
ZPV(L,1,2,2)=ZP
IF(ZP.EQ.C0) GOTO 20
C PRINT 9012,L-1,ZP
C PRINT 9013,L-1,ZP
9012 FORMAT("DEBUG: zpv[",I1,"][0][0][0] = ",E15.3)
9013 FORMAT("DEBUG: zpv[",I1,"][0][1][1] = ",E15.3)
20 CONTINUE
LMMO=LM-1
DO 25 L=1,LMMO
......@@ -680,6 +717,11 @@ CCC DIMENSION ZPV(LM,3,2,2)
ZP=-DSQRT(XN/XD)
ZPV(L,3,1,1)=ZP
ZPV(L,3,2,2)=ZP
IF(ZP.EQ.C0) GOTO 25
C PRINT 9014,L-1,ZP
C PRINT 9015,L-1,ZP
9014 FORMAT("DEBUG: zpv[",I1,"][2][0][0] = ",E15.3)
9015 FORMAT("DEBUG: zpv[",I1,"][2][1][1] = ",E15.3)
25 CONTINUE
30 CONTINUE
RETURN
......@@ -739,6 +781,10 @@ CCC CG1(LMPML,MU,L,M)=CLGO(1,LMP,L;MU,M-MU,M)
SINT=DSIN(TH)
COSP=DCOS(PH)
SINP=DSIN(PH)
C PRINT *,"DEBUG: cost =",COST
C PRINT *,"DEBUG: sint =",SINT
C PRINT *,"DEBUG: cosp =",COSP
C PRINT *,"DEBUG: sinp =",SINP
U(1)=COSP*SINT
U(2)=SINP*SINT
U(3)=COST
......@@ -782,6 +828,8 @@ CCC NSPEF=1 CALLING WITH IDOT=0, NSPEF=NSPH OTHERWISE
DO 60 N=1,NSPH
60 ARG(N)=-ARG(N)
65 CALL SPHAR(COST,SINT,COSP,SINP,LM,YLM)
C PRINT *,"DEBUG: in WMAMP and calling PWMA with lm =",LM,
C 1"and iis =",IIS
CALL PWMA(UP,UN,YLM,INPOL,LM,IIS)
RETURN
END
......@@ -880,9 +928,11 @@ CCC NSPEF=1 CALLING WITH IDOT=0, NSPEF=NSPH OTHERWISE
55 ARGS(N)=-COSTS*RZZ(N)
60 CONTINUE
75 CALL SPHAR(COST,SINT,COSP,SINP,LM,YLM)
C PRINT *,"DEBUG: in WMASP and calling PWMA"
CALL PWMA(UP,UN,YLM,INPOL,LM,ISQ)
IF(IBF.LT.0)RETURN
CALL SPHAR(COSTS,SINTS,COSPS,SINPS,LM,YLM)
C PRINT *,"DEBUG: in WMASP and calling PWMA with IBF =",IBF
CALL PWMA(UPS,UNS,YLM,INPOL,LM,2)
RETURN
END
......@@ -913,6 +963,7 @@ CCC DIMENSION YLM(NLWM+2)
CM2=.5D0*DCMPLX(UN(1),UN(2))
CP2=.5D0*DCMPLX(UN(1),-UN(2))
CZ2=UN(3)
C PRINT *,"DEBUG: in PWMA YLM(2) =",YLM(2)
DO 20 L=1,LW
LF=L+1
LFTL=LF*L
......@@ -929,26 +980,35 @@ CCC DIMENSION YLM(NLWM+2)
CM=DSQRT(X)
CZ=M
W(K,ISPO)=DCONJG(CP1*CP*YLM(K+2)+CM1*CM*YLM(K)+CZ1*CZ*YLM(K+1))*CL
C IF(ISPO.EQ.1)PRINT *,"DEBUG: W(",K,",",ISPO,") =",W(K,ISPO)
20 W(K,ISPT)=DCONJG(CP2*CP*YLM(K+2)+CM2*CM*YLM(K)+CZ2*CZ*YLM(K+1))*CL
C 20 PRINT *,"DEBUG: W(",K,",",ISPT,") =",W(K,ISPT)
DO 30 K=1,NLWM
I=K+NLWM
W(I,ISPO)=UIM*W(K,ISPT)
C PRINT *,"DEBUG: W(",I,",",ISPO,") =",W(I,ISPO)
30 W(I,ISPT)=-UIM*W(K,ISPO)
C 30 PRINT *,"DEBUG: W(",I,",",ISPT,") =",W(I,ISPT)
IF(INPOL.EQ.0)GO TO 42
DO 40 K=1,NLWM
I=K+NLWM
C1=(W(K,ISPO)+UIM*W(K,ISPT))*SQRTWI
C2=(W(K,ISPO)-UIM*W(K,ISPT))*SQRTWI
W(K,ISPO)=C2
C PRINT *,"DEBUG: W(",K,",",ISPO,") =",W(K,ISPO)
W(I,ISPO)=-C2
C PRINT *,"DEBUG: W(",I,",",ISPO,") =",W(I,ISPO)
W(K,ISPT)=C1
C PRINT *,"DEBUG: W(",K,",",ISPT,") =",W(K,ISPT)
40 W(I,ISPT)=C1
C 40 PRINT *,"DEBUG: W(",I,",",ISPT,") =",W(I,ISPT)
42 IF(ISQ.EQ.0)RETURN
DO 50 I=1,2
IPT=I+2
IPIS=I+IS
DO 50 K=1,NLWMT
50 W(K,IPT)=DCONJG(W(K,IPIS))
C 50 PRINT *,"DEBUG: W(",K,",",IPT,") =",W(K,IPT)
RETURN
END
SUBROUTINE ORUNVE(U1,U2,U3,IORTH,TORTH)
......@@ -1041,7 +1101,9 @@ CCC 2RMF(LI),DRMF(LI),REF(LI),DREF(LI)
CCNC=FBI(LPO)*DFB
CCND=FB(LPO)*DFBI
RMI(L,I)=1.0D0+UIM*(CCNA-CCNB)/(CCNC-CCND)
C PRINT *,"DEBUG: gone 60, RMI(",L,",",I,") =",RMI(L,I)
60 REI(L,I)=1.0D0+UIM*(CRI*CCNA-CCNB)/(CRI*CCNC-CCND)
C 60 PRINT *,"DEBUG: gone 60, REI(",L,",",I,") =",REI(L,I)
RETURN
65 DO 80 L=1,LI
LPO=L+1
......@@ -1076,6 +1138,7 @@ cccccccccccccccccccccc
80 DREF(L)=DY2*SZ+Y2
CRI=(1.0D0,0.0D0)
IF(MOD(NSH,2).NE.0)CRI=DC0(IC)/EXDC
C PRINT *,"DEBUG: going 90, AREX =",AREX
DO 90 L=1,LI
LPO=L+1
LTPO=LPO+L
......@@ -1087,11 +1150,13 @@ cccccccccccccccccccccc
CCNC=RMF(L)*DFB
CCND=DRMF(L)*FB(LPO)*SZ*LTPO
RMI(L,I)=1.0D0+UIM*(CCNA-CCNB)/(CCNC-CCND)
C PRINT *,"DEBUG: gone 90, RMI(",L,",",I,") =",RMI(L,I)
CCNA=REF(L)*DFN
CCNB=DREF(L)*FN(LPO)*SZ*LTPO
CCNC=REF(L)*DFB
CCND=DREF(L)*FB(LPO)*SZ*LTPO
90 REI(L,I)=1.0D0+UIM*(CRI*CCNA-CCNB)/(CRI*CCNC-CCND)
C 90 PRINT *,"DEBUG: gone 90, REI(",L,",",I,") =",REI(L,I)
RETURN
END
SUBROUTINE RKT(NPNTMO,STEP,X,LPO,Y1,Y2,DY1,DY2)
......@@ -1433,13 +1498,18 @@ CCC LL=LM
PI4=DACOS(0.0D0)*8.0D0
PI4IRS=1.0D0/DSQRT(PI4)
X=COSRTH
C PRINT *,"DEBUG: X =",X
Y=DABS(SINRTH)
C PRINT *,"DEBUG: Y =",Y
CLLMO=3.0D0
CLL=1.5D0
YTOL=Y
PLEGN(1)=1.0D0
C PRINT *,"DEBUG: PLEGN( 1 ) =",PLEGN(1)
PLEGN(2)=X*DSQRT(CLLMO)
C PRINT *,"DEBUG: PLEGN( 2 ) =",PLEGN(2)
PLEGN(3)=YTOL*DSQRT(CLL)
C PRINT *,"DEBUG: PLEGN( 3 ) =",PLEGN(3)
SINRMP(1)=SINRPH
COSRMP(1)=COSRPH
IF(LL.LT.2)GO TO 30
......@@ -1459,14 +1529,17 @@ CCC LL=LM
CDM=(LTMO-2)*LS
10 PLEGN(MPOPK)=PLEGN(MPOPK-L)*X*DSQRT(CN/CD)-
1PLEGN(MPOPK-LTMO)*DSQRT(CNM/CDM)
C10 PRINT *,"DEBUG: PLEGN(",MPOPK,") =",PLEGN(MPOPK)
LPK=L+K
CLTPO=LTPO
PLEGN(LPK)=PLEGN(K)*X*DSQRT(CLTPO)
C PRINT *,"DEBUG: PLEGN(",LPK,") =",PLEGN(LPK)
K=LPK+1
CLT=LTPO-1
CLL=CLL*(CLTPO/CLT)
YTOL=YTOL*Y
PLEGN(K)=YTOL*DSQRT(CLL)
C PRINT *,"DEBUG: PLEGN(",K,") =",PLEGN(K)
SINRMP(L)=SINRPH*COSRMP(LMO)+COSRPH*SINRMP(LMO)
20 COSRMP(L)=COSRPH*COSRMP(LMO)-SINRPH*SINRMP(LMO)
30 L=0
......@@ -1475,14 +1548,17 @@ CCC LL=LM
L0Y=K+1
L0P=K/2+1
YLM(L0Y)=PI4IRS*PLEGN(L0P)
C PRINT *, "DEBUG: YLM(",L0Y,") =",YLM(L0Y)
GO TO 45
44 LMP=L0P+M
SAVE=PI4IRS*PLEGN(LMP)
LMY=L0Y+M
YLM(LMY)=SAVE*DCMPLX(COSRMP(M),SINRMP(M))
IF(MOD(M,2).NE.0)YLM(LMY)=-YLM(LMY)
C PRINT *, "DEBUG: YLM(",LMY,") =",YLM(LMY)
LMY=L0Y-M
YLM(LMY)=SAVE*DCMPLX(COSRMP(M),-SINRMP(M))
C PRINT *, "DEBUG: YLM(",LMY,") =",YLM(LMY)
45 IF(M.GE.L)GO TO 47
M=M+1
GO TO 44
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment