diff --git a/src/include/outputs.h b/src/include/outputs.h index 39887cd096a9f1e79d9da2768228aaecb50dafb5..abea6a6f891c1e318c7c7c244f196cc469a38b48 100644 --- a/src/include/outputs.h +++ b/src/include/outputs.h @@ -467,9 +467,9 @@ public: /*! \brief `ClusterOutputInfo` constructor from HDF5 input. * - * \param hdf5_file_name: `const string &` Path to the HDF5 file to be read. + * \param hdf5_name: `const string &` Path to the HDF5 file to be read. */ - ClusterOutputInfo(const std::string &hdf5_file_name); + ClusterOutputInfo(const std::string &hdf5_name); /*! \brief `ClusterOutputInfo` instance destroyer. */ @@ -479,13 +479,13 @@ public: * * \param sc: `ScattererConfiguration *` Pointer to a `ScattererConfiguration` instance. * \param gc: `GeometryConfiguration *` Pointer to a `GeometryConfiguration` instance. - * \param first_xi: `int` Index of the first scale in output (optional, default is 0). + * \param first_xi: `int` Index of the first scale in output (optional, default is 1). * \param xi_length: `int` Number of scales tobe included in output (optional, default is all). * \return size: `long` Estimated instance size in bytes. */ static long compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, - int first_xi = 0, int xi_length = 0 + int first_xi = 1, int xi_length = 0 ); /*! \brief Get the size of a `ClusterOutputInfo` instance in bytes. @@ -647,7 +647,7 @@ public: int jwtm; //! \brief Vector of scale (wavelength) indices. int *vec_jxi; - //! \brief Vector of error severities (0 - success, 1 - HJV, 2 - DME). + //! \brief Vector of error severities (0 - success, 1 - INDME, 2 - OSPV). short *vec_ier; //! \brief Vector of vacuum wave numbers. double *vec_vk; @@ -897,9 +897,9 @@ public: /*! \brief `InclusionOutputInfo` constructor from HDF5 input. * - * \param hdf5_file_name: `const string &` Path to the HDF5 file to be read. + * \param hdf5_name: `const string &` Path to the HDF5 file to be read. */ - InclusionOutputInfo(const std::string &hdf5_file_name); + InclusionOutputInfo(const std::string &hdf5_name); /*! \brief `InclusionOutputInfo` instance destroyer. */ @@ -909,13 +909,13 @@ public: * * \param sc: `ScattererConfiguration *` Pointer to a `ScattererConfiguration` instance. * \param gc: `GeometryConfiguration *` Pointer to a `GeometryConfiguration` instance. - * \param first_xi: `int` Index of the first scale in output (optional, default is 0). + * \param first_xi: `int` Index of the first scale in output (optional, default is 1). * \param xi_length: `int` Number of scales tobe included in output (optional, default is all). * \return size: `long` Estimated instance size in bytes. */ static long compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, - int first_xi = 0, int xi_length = 0 + int first_xi = 1, int xi_length = 0 ); /*! \brief Get the size of a `ClusterOutputInfo` instance in bytes. @@ -1004,18 +1004,16 @@ protected: public: //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; + //! \brief Number of spheres. + int nsph; //! \brief Maximum field expansion order. int lm; - //! \brief Maximum coefficient matrix dimension. - np_int mxndm; //! \brief Incident polarization flag. int inpol; //! \brief Number of points for transition layer integration. int npnt; //! \brief Number of points for non-transition layer integration. int npntts; - //! \brief Flag for intensity. - int iavm; //! \brief Flag for reference to meridional plane. int isam; //! \brief Flag for dielectric function definition. @@ -1054,18 +1052,106 @@ public: int xi_block_size; //! \brief Index of the wavelength for T-matrix output. int jwtm; + //! \brief Number of sphere types. + int configurations; + //! \brief Highest expansion order achieved in calculations. + int lcalc; + //! \brief Harmonic functions argument. + dcomplex arg; //! \brief Vector of scale (wavelength) indices. int *vec_jxi; - //! \brief Vector of error severities (0 - success, 1 - HJV, 2 - DME). + //! \brief Vector of error severities (0 - success, 1 - DME). short *vec_ier; //! \brief Vector of vacuum wave numbers. double *vec_vk; //! \brief Vector of computed scales. double *vec_xi; - //! \brief Vector of sphere sizes (one for every scale). + //! \brief Vector of sphere sizes (one for every configuration and scale). double *vec_sphere_sizes; - //! \brief Vector of sphere refractive indices (one for every scale). + //! \brief Vector of sphere refractive indices (one for every configuration and scale). dcomplex *vec_sphere_ref_indices; + //! \brief Vector of sphere scattering cross-sections. + double *vec_scs; + //! \brief Vector of sphere absorption cross-sections. + double *vec_abs; + //! \brief Vector of sphere extinction cross-sections. + double *vec_exs; + //! \brief Vector of sphere albedos. + double *vec_albeds; + //! \brief Vector of sphere scattering-to-geometric cross-sections. + double *vec_scsrt; + //! \brief Vector of sphere absorption-to-geometric cross-sections. + double *vec_absrt; + //! \brief Vector of sphere extinction-to-geometric cross-sections. + double *vec_exsrt; + //! \brief Vector of sphere forward scattering amplitudes. + dcomplex *vec_fsas; + //! \brief Vector of sphere QSCHU. + double *vec_qschu; + //! \brief Vector of sphere PSCHU. + double *vec_pschu; + //! \brief Vector of sphere S0MAG. + double *vec_s0mag; + //! \brief Vector of sphere average asymmetry parameter. + double *vec_cosav; + //! \brief Vector of sphere average radiation pressure force (N). + double *vec_raprs; + //! \brief Vector of sphere average extinction torque along incidence direction (parallel polarization). + double *vec_tqek1; + //! \brief Vector of sphere average extinction torque along incidence direction (perpendicular polarization). + double *vec_tqek2; + //! \brief Vector of sphere average scattering torque along incidence direction (parallel polarization). + double *vec_tqsk1; + //! \brief Vector of sphere average scattering torque along incidence direction (perpendicular polarization). + double *vec_tqsk2; + //| \brief Vector of total forward scattering amplitudes. + dcomplex *vec_fsat; + //! \brief Vector of total QSCHU. + double *vec_qschut; + //! \brief Vector of total PSCHU. + double *vec_pschut; + //! \brief Vector of total S0MAG. + double *vec_s0magt; + //! \brief Vector of incidence azimuth directions (one per incidence azimuth). + double *vec_dir_tidg; + //! \brief Vector of incidence elevation directions (one per incidence elevation). + double *vec_dir_pidg; + //! \brief Vector of scattering azimuth directions (one per scattering azimuth). + double *vec_dir_tsdg; + //! \brief Vector of scattering elevation directions (one per scattering elevation). + double *vec_dir_psdg; + //! \brief Vector of scattering angles (one per direction). + double *vec_dir_scand; + //! \brief Control parameter for incidence plane referred to meridional plane (one per direction). + double *vec_dir_cfmp; + //! \brief Control parameter for scattering plane referred to meridional plane (one per direction). + double *vec_dir_sfmp; + //! \brief Control parameter for incidence plane referred to scattering plane (one per direction). + double *vec_dir_cfsp; + //! \brief Control parameter for scattering plane referred to scattering plane (one per direction). + double *vec_dir_sfsp; + //! \brief Components of the unitary vector perpendicular to incidence plane (three per direction). + double *vec_dir_un; + //! \brief Components of the unitary vector perpendicular to scattering plane (three per direction). + double *vec_dir_uns; + //! \brief Vector of sphere differential scattering amplitude with polarization parallel to parallel incidence field. + dcomplex *vec_dir_sas11; + //! \brief Vector of sphere differential scattering amplitude with polarization perpendicular to the parallel incidence field. + dcomplex *vec_dir_sas21; + //! \brief Vector of sphere differential scattering amplitude with polarization perpendicular to perpendicular incidence field. + dcomplex *vec_dir_sas12; + //! \brief Vector of sphere differential scattering amplitude with polarization parallel the perpendicular incidence field. + dcomplex *vec_dir_sas22; + //! \brief Vector of differential radiation pressure force components along the X axis. + double *vec_dir_fx; + //! \brief Vector of differential radiation pressure force components along the Y axis. + double *vec_dir_fy; + //! \brief Vector of differential radiation pressure force components along the Z axis. + double *vec_dir_fz; + //! \brief Vector of sphere Mueller transormation matrices referred to meridional plane. + double *vec_dir_muls; + //! \brief Vector of sphere Mueller transormation matrices referred to scattering plane. + double *vec_dir_mulslr; /*! \brief `SphereOutputInfo` default instance constructor. * @@ -1082,9 +1168,9 @@ public: /*! \brief `SphereOutputInfo` constructor from HDF5 input. * - * \param hdf5_file_name: `const string &` Path to the HDF5 file to be read. + * \param hdf5_name: `const string &` Path to the HDF5 file to be read. */ - SphereOutputInfo(const std::string &hdf5_file_name); + SphereOutputInfo(const std::string &hdf5_name); /*! \brief `InclusionOutputInfo` instance destroyer. */ @@ -1094,13 +1180,13 @@ public: * * \param sc: `ScattererConfiguration *` Pointer to a `ScattererConfiguration` instance. * \param gc: `GeometryConfiguration *` Pointer to a `GeometryConfiguration` instance. - * \param first_xi: `int` Index of the first scale in output (optional, default is 0). + * \param first_xi: `int` Index of the first scale in output (optional, default is 1). * \param xi_length: `int` Number of scales tobe included in output (optional, default is all). * \return size: `long` Estimated instance size in bytes. */ static long compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, - int first_xi = 0, int xi_length = 0 + int first_xi = 1, int xi_length = 0 ); /*! \brief Get the size of a `ClusterOutputInfo` instance in bytes. @@ -1136,7 +1222,7 @@ public: * \param pid: `int` Rank of the process that is transmitting data. * \return result: `int` An exit code (0 for success). */ - int mpireceive(const mixMPI* mpidata, int pid); + int mpireceive(const mixMPI *mpidata, int pid); /*! \brief Send output data to process 0. * diff --git a/src/libnptm/outputs.cpp b/src/libnptm/outputs.cpp index 4d6e61a2fb6273f9e665e038098d6f76ad0a868b..58f40cd5865b1455cd0a0f0b47c2ec099511c241 100644 --- a/src/libnptm/outputs.cpp +++ b/src/libnptm/outputs.cpp @@ -288,9 +288,9 @@ ClusterOutputInfo::ClusterOutputInfo( vec_dir_mulclr = new double[16 * ndirs * xi_block_size](); } -ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_file_name) { +ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_name) { unsigned int flags = H5F_ACC_RDONLY; - HDFFile *hdf_file = new HDFFile(hdf5_file_name, flags); + HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; if (status == 0) { @@ -696,7 +696,7 @@ ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_file_name) { delete hdf_file; } else { if (hdf_file != NULL) delete hdf_file; - UnrecognizedFormatException ex("Error: " + hdf5_file_name + " not recognized as a valid HDF5 file!"); + UnrecognizedFormatException ex("Error: " + hdf5_name + " not recognized as a valid HDF5 file!"); throw ex; } } @@ -961,6 +961,7 @@ long ClusterOutputInfo::compute_size() { int ClusterOutputInfo::insert(const ClusterOutputInfo &rhs) { int result = 0; + result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; result += (rhs.isam == isam) ? 0 : 1; @@ -2355,9 +2356,10 @@ int ClusterOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int result = 0; - int chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; + int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; + MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_isam, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); @@ -2369,6 +2371,7 @@ int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { MPI_Recv(&chk_exri, 1, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_idfc, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_configs, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + result += (chk_nsph == nsph) ? 0 : 1; result += (chk_inpol == inpol) ? 0 : 1; result += (chk_iavm == iavm) ? 0 : 1; result += (chk_isam == isam) ? 0 : 1; @@ -2559,6 +2562,7 @@ int ClusterOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; // Send output metadata for configuration cross-check + MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&iavm, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&isam, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); @@ -2932,9 +2936,9 @@ InclusionOutputInfo::InclusionOutputInfo( vec_dir_mulllr = new double[16 * ndirs * xi_block_size](); } -InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_file_name) { +InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_name) { unsigned int flags = H5F_ACC_RDONLY; - HDFFile *hdf_file = new HDFFile(hdf5_file_name, flags); + HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; if (status == 0) { @@ -3060,18 +3064,24 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_file_name) { status = hdf_file->read("VEC_FSAS22", str_type, vec_fsas22); vec_fsas12 = new dcomplex[xi_block_size]; status = hdf_file->read("VEC_FSAS12", str_type, vec_fsas12); - str_type = "FLOAT64_(" + to_string(_num_theta) + ")"; - vec_dir_tidg = new double[_num_theta]; - status = hdf_file->read("VEC_DIR_TIDG", str_type, vec_dir_tidg); - str_type = "FLOAT64_(" + to_string(_num_phi) + ")"; - vec_dir_pidg = new double[_num_phi]; - status = hdf_file->read("VEC_DIR_PIDG", str_type, vec_dir_pidg); - str_type = "FLOAT64_(" + to_string(_num_thetas) + ")"; - vec_dir_tsdg = new double[_num_thetas]; - status = hdf_file->read("VEC_DIR_TSDG", str_type, vec_dir_tsdg); - str_type = "FLOAT64_(" + to_string(_num_phis) + ")"; - vec_dir_psdg = new double[_num_phis]; - status = hdf_file->read("VEC_DIR_PSDG", str_type, vec_dir_psdg); + // Initialize directions (they are scale-independent) + double cti = th, cpi = ph, cts = ths, cps = phs; + for (int di = 0; di < _num_theta; di++) { + vec_dir_tidg[di] = cti; + cti += thstp; + } + for (int di = 0; di < _num_thetas; di++) { + vec_dir_tsdg[di] = cts; + cts += thsstp; + } + for (int di = 0; di < _num_phi; di++) { + vec_dir_pidg[di] = cpi; + cpi += phstp; + } + for (int di = 0; di < _num_phis; di++) { + vec_dir_psdg[di] = cps; + cps += phsstp; + } str_type = "FLOAT64_(" + to_string(ndirs) + ")"; vec_dir_scand = new double[ndirs]; status = hdf_file->read("VEC_DIR_SCAND", str_type, vec_dir_scand); @@ -3236,7 +3246,7 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_file_name) { delete hdf_file; } else { if (hdf_file != NULL) delete hdf_file; - UnrecognizedFormatException ex("Error: " + hdf5_file_name + " not recognized as a valid HDF5 file!"); + UnrecognizedFormatException ex("Error: " + hdf5_name + " not recognized as a valid HDF5 file!"); throw ex; } } @@ -3420,6 +3430,7 @@ long InclusionOutputInfo::compute_size( int InclusionOutputInfo::insert(const InclusionOutputInfo &rhs) { int result = 0; + result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; result += (rhs.isam == isam) ? 0 : 1; @@ -3776,22 +3787,6 @@ int InclusionOutputInfo::write_hdf5(const std::string &file_name) { rec_name_list->append("VEC_FSAS22"); rec_type_list->append(str_type); rec_ptr_list->append(vec_fsas22); - str_type = "FLOAT64_(" + to_string(_num_theta) + ")"; - rec_name_list->append("VEC_DIR_TIDG"); - rec_type_list->append(str_type); - rec_ptr_list->append(vec_dir_tidg); - str_type = "FLOAT64_(" + to_string(_num_phi) + ")"; - rec_name_list->append("VEC_DIR_PIDG"); - rec_type_list->append(str_type); - rec_ptr_list->append(vec_dir_pidg); - str_type = "FLOAT64_(" + to_string(_num_thetas) + ")"; - rec_name_list->append("VEC_DIR_TSDG"); - rec_type_list->append(str_type); - rec_ptr_list->append(vec_dir_tsdg); - str_type = "FLOAT64_(" + to_string(_num_phis) + ")"; - rec_name_list->append("VEC_DIR_PSDG"); - rec_type_list->append(str_type); - rec_ptr_list->append(vec_dir_psdg); str_type = "FLOAT64_(" + to_string(ndirs) + ")"; rec_name_list->append("VEC_DIR_SCAND"); rec_type_list->append(str_type); @@ -4481,9 +4476,10 @@ int InclusionOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { int result = 0; - int chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; + int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; + MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_isam, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); @@ -4495,6 +4491,7 @@ int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { MPI_Recv(&chk_exri, 1, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_idfc, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_configs, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + result += (chk_nsph == nsph) ? 0 : 1; result += (chk_inpol == inpol) ? 0 : 1; result += (chk_iavm == iavm) ? 0 : 1; result += (chk_isam == isam) ? 0 : 1; @@ -4638,6 +4635,7 @@ int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; // Send output metadata for configuration cross-check + MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&iavm, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&isam, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); @@ -4775,3 +4773,1130 @@ int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { } #endif // MPI_VERSION // >>> END OF InclusionOutputInfo CLASS IMPLEMENTATION <<< + +// >>> SphereOutputInfo CLASS IMPLEMENTATION <<< +SphereOutputInfo::SphereOutputInfo( + ScattererConfiguration *sc, GeometryConfiguration *gc, + const mixMPI *mpidata, int first_xi, int xi_length +) { + _first_xi = first_xi; + nsph = gc->number_of_spheres; + lm = gc->l_max; + inpol = gc->in_pol; + npnt = gc->npnt; + npntts = gc->npntts; + isam = gc->isam; + idfc = sc->idfc; + th = gc->in_theta_start; + thstp = gc->in_theta_step; + thlst = gc->in_theta_end; + _num_theta = (thstp == 0.0) ? 1 : 1 + (int)((thlst - th) / thstp); + ths = gc->sc_theta_start; + thsstp = gc->sc_theta_step; + thslst = gc->sc_theta_end; + _num_thetas = (thsstp == 0.0) ? 1 : 1 + (int)((thslst - ths) / thsstp); + ph = gc->in_phi_start; + phstp = gc->in_phi_step; + phlst = gc->in_phi_end; + _num_phi = (phstp == 0.0) ? 1 : 1 + (int)((phlst - ph) / phstp); + phs = gc->sc_phi_start; + phsstp = gc->sc_phi_step; + phslst = gc->sc_phi_end; + _num_phis = (phsstp == 0.0) ? 1 : 1 + (int)((phslst - phs) / phsstp); + ndirs = _num_theta * _num_thetas * _num_phi * _num_phis; + configurations = sc->configurations; + double exdc = sc->exdc; + exri = sqrt(exdc); + nxi = sc->number_of_scales; + xi_block_size = (xi_length == 0) ? nxi : xi_length; + jwtm = gc->jwtm; + lcalc = 0; + arg = 0.0 + I * 0.0; + vec_jxi = new int[xi_block_size](); + vec_ier = new short[xi_block_size](); + vec_vk = new double[xi_block_size](); + vec_xi = new double[xi_block_size](); + vec_sphere_sizes = new double[configurations * xi_block_size](); + vec_sphere_ref_indices = new dcomplex[configurations * xi_block_size](); + vec_scs = new double[configurations * xi_block_size](); + vec_abs = new double[configurations * xi_block_size](); + vec_exs = new double[configurations * xi_block_size](); + vec_albeds = new double[configurations * xi_block_size](); + vec_scsrt = new double[configurations * xi_block_size](); + vec_absrt = new double[configurations * xi_block_size](); + vec_exsrt = new double[configurations * xi_block_size](); + vec_fsas = new dcomplex[configurations * xi_block_size](); + vec_qschu = new double[configurations * xi_block_size](); + vec_pschu = new double[configurations * xi_block_size](); + vec_s0mag = new double[configurations * xi_block_size](); + vec_cosav = new double[configurations * xi_block_size](); + vec_raprs = new double[configurations * xi_block_size](); + vec_tqek1 = new double[configurations * xi_block_size](); + vec_tqek2 = new double[configurations * xi_block_size](); + vec_tqsk1 = new double[configurations * xi_block_size](); + vec_tqsk2 = new double[configurations * xi_block_size](); + if (nsph == 1) { + vec_fsat = NULL; + vec_qschut = NULL; + vec_pschut = NULL; + vec_s0magt = NULL; + } else { + vec_fsat = new dcomplex[xi_block_size](); + vec_qschut = new double[xi_block_size](); + vec_pschut = new double[xi_block_size](); + vec_s0magt = new double[xi_block_size](); + } + vec_dir_tidg = new double[_num_theta](); + vec_dir_pidg = new double[_num_phi](); + vec_dir_tsdg = new double[_num_thetas](); + vec_dir_psdg = new double[_num_phis](); + vec_dir_scand = new double[ndirs](); + vec_dir_cfmp = new double[ndirs](); + vec_dir_cfsp = new double[ndirs](); + vec_dir_sfmp = new double[ndirs](); + vec_dir_sfsp = new double[ndirs](); + vec_dir_un = new double[3 * ndirs](); + vec_dir_uns = new double[3 * ndirs](); + vec_dir_sas11 = new dcomplex[nsph * ndirs * xi_block_size](); + vec_dir_sas21 = new dcomplex[nsph * ndirs * xi_block_size](); + vec_dir_sas12 = new dcomplex[nsph * ndirs * xi_block_size](); + vec_dir_sas22 = new dcomplex[nsph * ndirs * xi_block_size](); + vec_dir_fx = new double[nsph * _num_theta * _num_phi * xi_block_size](); + vec_dir_fy = new double[nsph * _num_theta * _num_phi * xi_block_size](); + vec_dir_fz = new double[nsph * _num_theta * _num_phi * xi_block_size](); + vec_dir_muls = new double[16 * nsph * ndirs * xi_block_size](); + vec_dir_mulslr = new double[16 * nsph * ndirs * xi_block_size](); + // Initialize directions (they are scale-independent) + double cti = th, cpi = ph, cts = ths, cps = phs; + for (int di = 0; di < _num_theta; di++) { + vec_dir_tidg[di] = cti; + cti += thstp; + } + for (int di = 0; di < _num_thetas; di++) { + vec_dir_tsdg[di] = cts; + cts += thsstp; + } + for (int di = 0; di < _num_phi; di++) { + vec_dir_pidg[di] = cpi; + cpi += phstp; + } + for (int di = 0; di < _num_phis; di++) { + vec_dir_psdg[di] = cps; + cps += phsstp; + } +} + +SphereOutputInfo::SphereOutputInfo(const std::string &hdf5_name) { + // DA QUI ; TODO: AGGIUSTARE TUTTE LE DIMENSIONI LEGATE A configurations + unsigned int flags = H5F_ACC_RDONLY; + HDFFile *hdf_file = new HDFFile(hdf5_name, flags); + herr_t status = hdf_file->get_status(); + string str_name, str_type; + if (status == 0) { + status = hdf_file->read("NSPH", "INT32_(1)", &nsph); + status = hdf_file->read("LM", "INT32_(1)", &lm); + status = hdf_file->read("INPOL", "INT32_(1)", &inpol); + status = hdf_file->read("NPNT", "INT32_(1)", &npnt); + status = hdf_file->read("NPNTTS", "INT32_(1)", &npntts); + status = hdf_file->read("ISAM", "INT32_(1)", &isam); + status = hdf_file->read("JWTM", "INT32_(1)", &jwtm); + status = hdf_file->read("TH_START", "FLOAT64_(1)", &th); + status = hdf_file->read("TH_STEP", "FLOAT64_(1)", &thstp); + status = hdf_file->read("TH_END", "FLOAT64_(1)", &thlst); + _num_theta = (thstp == 0.0) ? 1 : 1 + int((thlst - th) / thstp); + status = hdf_file->read("THS_START", "FLOAT64_(1)", &ths); + status = hdf_file->read("THS_STEP", "FLOAT64_(1)", &thsstp); + status = hdf_file->read("THS_END", "FLOAT64_(1)", &thslst); + _num_thetas = (thsstp == 0.0) ? 1 : 1 + int((thslst - ths) / thsstp); + status = hdf_file->read("PH_START", "FLOAT64_(1)", &ph); + status = hdf_file->read("PH_STEP", "FLOAT64_(1)", &phstp); + status = hdf_file->read("PH_END", "FLOAT64_(1)", &phlst); + _num_phi = (phstp == 0.0) ? 1 : 1 + int((phlst - ph) / phstp); + status = hdf_file->read("PHS_START", "FLOAT64_(1)", &phs); + status = hdf_file->read("PHS_STEP", "FLOAT64_(1)", &phsstp); + status = hdf_file->read("PHS_END", "FLOAT64_(1)", &phslst); + _num_phis = (phsstp == 0.0) ? 1 : 1 + int((phslst - phs) / phsstp); + ndirs = _num_theta * _num_thetas * _num_phi * _num_phis; + status = hdf_file->read("EXRI", "FLOAT64_(1)", &exri); + status = hdf_file->read("NUM_CONF", "FLOAT64_(1)", &configurations); + status = hdf_file->read("IDFC", "INT32_(1)", &idfc); + status = hdf_file->read("XI1", "INT32_(1)", &_first_xi); + status = hdf_file->read("NXI", "INT32_(1)", &xi_block_size); + nxi = (_first_xi == 1) ? xi_block_size : xi_block_size + _first_xi; + lcalc = 0; + arg = 0.0 + I * 0.0; + str_type = "INT32_(" + to_string(xi_block_size) + ")"; + vec_jxi = new int[xi_block_size]; + status = hdf_file->read("VEC_JXI", str_type, vec_jxi); + str_type = "INT16_(" + to_string(xi_block_size) + ")"; + vec_ier = new short[xi_block_size]; + status = hdf_file->read("VEC_IER", str_type, vec_ier); + str_type = "FLOAT64_(" + to_string(xi_block_size) + ")"; + vec_vk = new double[xi_block_size]; + status = hdf_file->read("VEC_VK", str_type, vec_vk); + vec_xi = new double[xi_block_size]; + status = hdf_file->read("VEC_VK", str_type, vec_xi); + str_type = "FLOAT64_(" + to_string(configurations * xi_block_size) + ")"; + vec_sphere_sizes = new double[xi_block_size]; + status = hdf_file->read("VEC_SPH_SIZES", str_type, vec_sphere_sizes); + str_type = "FLOAT64_(" + to_string(2 * configurations * xi_block_size) + ")"; + vec_sphere_ref_indices = new dcomplex[xi_block_size]; + status = hdf_file->read("VEC_SPH_REFRI", str_type, vec_sphere_ref_indices); + str_type = "FLOAT64_(" + to_string(configurations * xi_block_size) + ")"; + vec_scs = new double[xi_block_size]; + status = hdf_file->read("VEC_SCS", str_type, vec_scs); + vec_abs = new double[xi_block_size]; + status = hdf_file->read("VEC_ABS", str_type, vec_abs); + vec_exs = new double[xi_block_size]; + status = hdf_file->read("VEC_EXS", str_type, vec_exs); + vec_albeds = new double[xi_block_size]; + status = hdf_file->read("VEC_ALBEDS", str_type, vec_albeds); + vec_scsrt = new double[xi_block_size]; + status = hdf_file->read("VEC_SCSRT", str_type, vec_scsrt); + vec_absrt = new double[xi_block_size]; + status = hdf_file->read("VEC_ABSRT", str_type, vec_absrt); + vec_exsrt = new double[xi_block_size]; + status = hdf_file->read("VEC_EXSRT", str_type, vec_exsrt); + str_type = "FLOAT64_(" + to_string(2 * configurations * xi_block_size) + ")"; + vec_fsas = new dcomplex[xi_block_size]; + status = hdf_file->read("VEC_FSAS", str_type, vec_fsas); + str_type = "FLOAT64_(" + to_string(configurations * xi_block_size) + ")"; + vec_qschu = new double[xi_block_size]; + status = hdf_file->read("VEC_QSCHU", str_type, vec_qschu); + vec_pschu = new double[xi_block_size]; + status = hdf_file->read("VEC_PSCHU", str_type, vec_pschu); + vec_s0mag = new double[xi_block_size]; + status = hdf_file->read("VEC_S0MAG", str_type, vec_s0mag); + vec_cosav = new double[xi_block_size]; + status = hdf_file->read("VEC_COSAV", str_type, vec_cosav); + vec_raprs = new double[xi_block_size]; + status = hdf_file->read("VEC_RAPRS", str_type, vec_raprs); + vec_tqek1 = new double[xi_block_size]; + status = hdf_file->read("VEC_TQEK1", str_type, vec_tqek1); + vec_tqek2 = new double[xi_block_size]; + status = hdf_file->read("VEC_TQEK2", str_type, vec_tqek2); + vec_tqsk1 = new double[xi_block_size]; + status = hdf_file->read("VEC_TQSK1", str_type, vec_tqsk1); + vec_tqsk2 = new double[xi_block_size]; + status = hdf_file->read("VEC_TQSK2", str_type, vec_tqsk2); + if (nsph != 1) { + str_type = "FLOAT64_(" + to_string(2 * xi_block_size) + ")"; + vec_fsat = new dcomplex[xi_block_size]; + status = hdf_file->read("VEC_FSAT", str_type, vec_fsat); + str_type = "FLOAT64_(" + to_string(xi_block_size) + ")"; + vec_qschut = new double[xi_block_size]; + status = hdf_file->read("VEC_QSCHUT", str_type, vec_qschut); + vec_pschut = new double[xi_block_size]; + status = hdf_file->read("VEC_PSCHUT", str_type, vec_pschut); + vec_s0magt = new double[xi_block_size]; + status = hdf_file->read("VEC_S0MAGT", str_type, vec_s0magt); + } else { + vec_fsat = NULL; + vec_qschut = NULL; + vec_pschut = NULL; + vec_s0magt = NULL; + } + // Initialize directions (they are scale-independent) + _num_theta = (thstp == 0.0) ? 1 : 1 + (int)((thlst - th) / thstp); + _num_thetas = (thsstp == 0.0) ? 1 : 1 + (int)((thslst - ths) / thsstp); + _num_phi = (phstp == 0.0) ? 1 : 1 + (int)((phlst - ph) / phstp); + _num_phis = (phsstp == 0.0) ? 1 : 1 + (int)((phslst - phs) / phsstp); + vec_dir_tidg = new double[_num_theta]; + vec_dir_tsdg = new double[_num_thetas]; + vec_dir_pidg = new double[_num_phi]; + vec_dir_psdg = new double[_num_phis]; + double cti = th, cpi = ph, cts = ths, cps = phs; + for (int di = 0; di < _num_theta; di++) { + vec_dir_tidg[di] = cti; + cti += thstp; + } + for (int di = 0; di < _num_thetas; di++) { + vec_dir_tsdg[di] = cts; + cts += thsstp; + } + for (int di = 0; di < _num_phi; di++) { + vec_dir_pidg[di] = cpi; + cpi += phstp; + } + for (int di = 0; di < _num_phis; di++) { + vec_dir_psdg[di] = cps; + cps += phsstp; + } + str_type = "FLOAT64_(" + to_string(ndirs) + ")"; + vec_dir_scand = new double[ndirs]; + status = hdf_file->read("VEC_DIR_SCAND", str_type, vec_dir_scand); + vec_dir_cfmp = new double[ndirs]; + status = hdf_file->read("VEC_DIR_CFMP", str_type, vec_dir_cfmp); + vec_dir_sfmp = new double[ndirs]; + status = hdf_file->read("VEC_DIR_SFMP", str_type, vec_dir_sfmp); + vec_dir_cfsp = new double[ndirs]; + status = hdf_file->read("VEC_DIR_CFSP", str_type, vec_dir_cfsp); + vec_dir_sfsp = new double[ndirs]; + status = hdf_file->read("VEC_DIR_SFSP", str_type, vec_dir_sfsp); + str_type = "FLOAT64_(" + to_string(3 * ndirs) + ")"; + vec_dir_un = new double[3 * ndirs]; + status = hdf_file->read("VEC_DIR_UN", str_type, vec_dir_un); + vec_dir_uns = new double[3 * ndirs]; + status = hdf_file->read("VEC_DIR_UNS", str_type, vec_dir_uns); + str_type = "FLOAT64_(" + to_string(2 * nsph * ndirs * xi_block_size) + ")"; + vec_dir_sas11 = new dcomplex[nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_SAS11", str_type, vec_dir_sas11); + vec_dir_sas21 = new dcomplex[nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_SAS21", str_type, vec_dir_sas21); + vec_dir_sas12 = new dcomplex[nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_SAS12", str_type, vec_dir_sas12); + vec_dir_sas22 = new dcomplex[nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_SAS22", str_type, vec_dir_sas22); + str_type = "FLOAT64_(" + to_string(nsph * _num_theta * _num_phi * xi_block_size) + ")"; + vec_dir_fx = new double[nsph * _num_theta * _num_phi * xi_block_size]; + status = hdf_file->read("VEC_DIR_FX", str_type, vec_dir_fx); + vec_dir_fy = new double[nsph * _num_theta * _num_phi * xi_block_size]; + status = hdf_file->read("VEC_DIR_FY", str_type, vec_dir_fy); + vec_dir_fz = new double[nsph * _num_theta * _num_phi * xi_block_size]; + status = hdf_file->read("VEC_DIR_FZ", str_type, vec_dir_fz); + str_type = "FLOAT64_(" + to_string(16 * nsph * ndirs * xi_block_size) + ")"; + vec_dir_muls = new double[16 * nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_MULS", str_type, vec_dir_muls); + vec_dir_mulslr = new double[16 * nsph * ndirs * xi_block_size]; + status = hdf_file->read("VEC_DIR_MULSLR", str_type, vec_dir_mulslr); + status = hdf_file->close(); + delete hdf_file; + } else { + if (hdf_file != NULL) delete hdf_file; + UnrecognizedFormatException ex("Error: " + hdf5_name + " not recognized as a valid HDF5 file!"); + throw ex; + } +} + +SphereOutputInfo::~SphereOutputInfo() { + delete[] vec_jxi; + delete[] vec_ier; + delete[] vec_vk; + delete[] vec_xi; + delete[] vec_sphere_sizes; + delete[] vec_sphere_ref_indices; + delete[] vec_scs; + delete[] vec_abs; + delete[] vec_exs; + delete[] vec_albeds; + delete[] vec_scsrt; + delete[] vec_absrt; + delete[] vec_exsrt; + delete[] vec_fsas; + delete[] vec_qschu; + delete[] vec_pschu; + delete[] vec_s0mag; + delete[] vec_cosav; + delete[] vec_raprs; + delete[] vec_tqek1; + delete[] vec_tqek2; + delete[] vec_tqsk1; + delete[] vec_tqsk2; + if (nsph != 1) { + delete[] vec_fsat; + delete[] vec_qschut; + delete[] vec_pschut; + delete[] vec_s0magt; + } + delete[] vec_dir_tidg; + delete[] vec_dir_pidg; + delete[] vec_dir_tsdg; + delete[] vec_dir_psdg; + delete[] vec_dir_scand; + delete[] vec_dir_cfmp; + delete[] vec_dir_cfsp; + delete[] vec_dir_sfmp; + delete[] vec_dir_sfsp; + delete[] vec_dir_un; + delete[] vec_dir_uns; + delete[] vec_dir_sas11; + delete[] vec_dir_sas21; + delete[] vec_dir_sas12; + delete[] vec_dir_sas22; + delete[] vec_dir_fx; + delete[] vec_dir_fy; + delete[] vec_dir_fz; + delete[] vec_dir_muls; + delete[] vec_dir_mulslr; +} + +long SphereOutputInfo::compute_size( + ScattererConfiguration *sc, GeometryConfiguration *gc, + int first_xi, int xi_length +) { + // Size of the configuration set + long result = 18 * sizeof(int); + result += 12 * sizeof(double); + result += 47 * sizeof(long); + result += sizeof(dcomplex); + // Get configuration parameters + int _nsph = gc->number_of_spheres; + double _th = gc->in_theta_start; + double _thstp = gc->in_theta_step; + double _thlst = gc->in_theta_end; + int num_theta = (_thstp == 0.0) ? 1 : 1 + (int)((_thlst - _th) / _thstp); + double _ths = gc->sc_theta_start; + double _thsstp = gc->sc_theta_step; + double _thslst = gc->sc_theta_end; + int num_thetas = (_thsstp == 0.0) ? 1 : 1 + (int)((_thslst - _ths) / _thsstp); + double _ph = gc->in_phi_start; + double _phstp = gc->in_phi_step; + double _phlst = gc->in_phi_end; + int num_phi = (_phstp == 0.0) ? 1 : 1 + (int)((_phlst - _ph) / _phstp); + double _phs = gc->sc_phi_start; + double _phsstp = gc->sc_phi_step; + double _phslst = gc->sc_phi_end; + int num_phis = (_phsstp == 0.0) ? 1 : 1 + (int)((_phslst - _phs) / _phsstp); + int _ndirs = num_theta * num_thetas * num_phi * num_phis; + int _nxi = sc->number_of_scales; + int _xi_block_size = (xi_length == 0) ? _nxi : xi_length; + int _nconf = sc->configurations; + // Size of the data set + result += _xi_block_size * (sizeof(short) + sizeof(int)); + result += 2 * _xi_block_size * sizeof(double); + result += 16 * _nconf * _xi_block_size * sizeof(double); + result += 2 * _nconf * _xi_block_size * sizeof(dcomplex); + result += (num_theta + num_thetas + num_phi + num_phis) * sizeof(double); + result += 11 * _ndirs * sizeof(double); + result += 4 * _nsph * _ndirs * _xi_block_size * sizeof(dcomplex); + result += 3 * _nsph * num_theta * num_phi * sizeof(double); + result += 32 * _nsph * _ndirs * _xi_block_size * sizeof(double); + if (_nsph != 1) { + result += _xi_block_size * sizeof(dcomplex); + result += 3 * _xi_block_size * sizeof(double); + } + return result; +} + +long SphereOutputInfo::compute_size() { + // Size of the configuration set + long result = 18 * sizeof(int); + result += 12 * sizeof(double); + result += 47 * sizeof(long); + result += sizeof(dcomplex); + // Size of the data set + result += xi_block_size * (sizeof(short) + sizeof(int)); + result += 2 * xi_block_size * sizeof(double); + result += 16 * configurations * xi_block_size * sizeof(double); + result += 2 * configurations * xi_block_size * sizeof(dcomplex); + result += (_num_theta + _num_thetas + _num_phi + _num_phis) * sizeof(double); + result += 11 * ndirs * sizeof(double); + result += 4 * nsph * ndirs * xi_block_size * sizeof(dcomplex); + result += 3 * nsph * _num_theta * _num_phi * sizeof(double); + result += 32 * nsph * ndirs * xi_block_size * sizeof(double); + if (nsph != 1) { + result += xi_block_size * sizeof(dcomplex); + result += 3 * xi_block_size * sizeof(double); + } + return result; +} + +int SphereOutputInfo::insert(const SphereOutputInfo &rhs) { + int result = 0; + result += (rhs.nsph == nsph) ? 0 : 1; + result += (rhs.inpol == inpol) ? 0 : 1; + result += (rhs.isam == isam) ? 0 : 1; + result += (rhs._num_theta == _num_theta) ? 0 : 1; + result += (rhs._num_thetas == _num_thetas) ? 0 : 1; + result += (rhs._num_phi == _num_phi) ? 0 : 1; + result += (rhs._num_phis == _num_phis) ? 0 : 1; + result += (rhs.ndirs == ndirs) ? 0 : 1; + result += (rhs.exri == exri) ? 0 : 1; + result += (rhs.idfc == idfc) ? 0 : 1; + result += (rhs.configurations == configurations) ? 0 : 1; + if (result == 0) { + int offset, chunk_size, xi1; + xi1 = rhs._first_xi; + // Insert vectors whose sizes depend on wavelengths + offset = xi1 - _first_xi; + chunk_size = rhs.xi_block_size; + memcpy(vec_jxi + offset, rhs.vec_jxi, chunk_size * sizeof(int)); + memcpy(vec_ier + offset, rhs.vec_ier, chunk_size * sizeof(short)); + memcpy(vec_vk + offset, rhs.vec_vk, chunk_size * sizeof(double)); + memcpy(vec_xi + offset, rhs.vec_xi, chunk_size * sizeof(double)); + if (nsph != 1) { + memcpy(vec_fsat + offset, rhs.vec_fsat, chunk_size * sizeof(dcomplex)); + memcpy(vec_qschut + offset, rhs.vec_qschut, chunk_size * sizeof(double)); + memcpy(vec_pschut + offset, rhs.vec_pschut, chunk_size * sizeof(double)); + memcpy(vec_s0magt + offset, rhs.vec_s0magt, chunk_size * sizeof(double)); + } + + // Insert vectors whose sizes depend on configurations and wavelengths + offset = (xi1 - _first_xi) * configurations; + chunk_size = rhs.xi_block_size * configurations; + memcpy(vec_sphere_sizes + offset, rhs.vec_sphere_sizes, chunk_size * sizeof(double)); + memcpy(vec_sphere_ref_indices + offset, rhs.vec_sphere_ref_indices, chunk_size * sizeof(dcomplex)); + memcpy(vec_scs + offset, rhs.vec_scs, chunk_size * sizeof(double)); + memcpy(vec_abs + offset, rhs.vec_abs, chunk_size * sizeof(double)); + memcpy(vec_exs + offset, rhs.vec_exs, chunk_size * sizeof(double)); + memcpy(vec_albeds + offset, rhs.vec_albeds, chunk_size * sizeof(double)); + memcpy(vec_scsrt + offset, rhs.vec_scsrt, chunk_size * sizeof(double)); + memcpy(vec_absrt + offset, rhs.vec_absrt, chunk_size * sizeof(double)); + memcpy(vec_exsrt + offset, rhs.vec_exsrt, chunk_size * sizeof(double)); + memcpy(vec_fsas + offset, rhs.vec_fsas, chunk_size * sizeof(dcomplex)); + memcpy(vec_qschu + offset, rhs.vec_qschu, chunk_size * sizeof(double)); + memcpy(vec_pschu + offset, rhs.vec_pschu, chunk_size * sizeof(double)); + memcpy(vec_s0mag + offset, rhs.vec_s0mag, chunk_size * sizeof(double)); + memcpy(vec_cosav + offset, rhs.vec_cosav, chunk_size * sizeof(double)); + memcpy(vec_raprs + offset, rhs.vec_raprs, chunk_size * sizeof(double)); + memcpy(vec_tqek1 + offset, rhs.vec_tqek1, chunk_size * sizeof(double)); + memcpy(vec_tqek2 + offset, rhs.vec_tqek2, chunk_size * sizeof(double)); + memcpy(vec_tqsk1 + offset, rhs.vec_tqsk1, chunk_size * sizeof(double)); + memcpy(vec_tqsk2 + offset, rhs.vec_tqsk2, chunk_size * sizeof(double)); + + // Insert vectors whose sizes depend on NSPH, directions and wavelengths + offset = (xi1 - _first_xi) * nsph * ndirs; + chunk_size = rhs.xi_block_size * nsph * ndirs; + memcpy(vec_dir_sas11 + offset, rhs.vec_dir_sas11, chunk_size * sizeof(dcomplex)); + memcpy(vec_dir_sas21 + offset, rhs.vec_dir_sas21, chunk_size * sizeof(dcomplex)); + memcpy(vec_dir_sas12 + offset, rhs.vec_dir_sas12, chunk_size * sizeof(dcomplex)); + memcpy(vec_dir_sas22 + offset, rhs.vec_dir_sas22, chunk_size * sizeof(dcomplex)); + memcpy(vec_dir_muls + 16 * offset, rhs.vec_dir_muls, 16 * chunk_size * sizeof(double)); + memcpy(vec_dir_mulslr + 16 * offset, rhs.vec_dir_mulslr, 16 * chunk_size * sizeof(double)); + + // Insert vectors whose sizes depend on NSPH, incidence directions and wavelengths + offset = (xi1 - _first_xi) * nsph * _num_theta * _num_phi; + chunk_size = rhs.xi_block_size * nsph * _num_theta * _num_phi; + memcpy(vec_dir_fx + offset, rhs.vec_dir_fx, chunk_size * sizeof(double)); + memcpy(vec_dir_fy + offset, rhs.vec_dir_fy, chunk_size * sizeof(double)); + memcpy(vec_dir_fz + offset, rhs.vec_dir_fz, chunk_size * sizeof(double)); + // TODO: fix the vector sizes in HDF5 writer and MPI communicators + } + return result; +} + +int SphereOutputInfo::write(const std::string &output, const std::string &format) { + int result = 0; + if (format.compare("LEGACY") == 0) { + result = write_legacy(output); + } else if (format.compare("HDF5") == 0) { + result = write_hdf5(output); + } else { + string message = "Unknown format mode: \"" + format + "\""; + throw UnrecognizedConfigurationException(message); + } + return result; +} + +int SphereOutputInfo::write_hdf5(const std::string &file_name) { + List<string> *rec_name_list = new List<string>(1); + List<string> *rec_type_list = new List<string>(1); + List<void *> *rec_ptr_list = new List<void *>(1); + string str_type, str_name; + rec_name_list->set(0, "NSPH"); + rec_type_list->set(0, "INT32_(1)"); + rec_ptr_list->set(0, &nsph); + rec_name_list->append("LM"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&lm); + rec_name_list->append("INPOL"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&inpol); + rec_name_list->append("NPNT"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&npnt); + rec_name_list->append("NPNTTS"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&npntts); + rec_name_list->append("ISAM"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&isam); + rec_name_list->append("JWTM"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&jwtm); + rec_name_list->append("TH_START"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&th); + rec_name_list->append("TH_STEP"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&thstp); + rec_name_list->append("TH_END"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&thlst); + rec_name_list->append("THS_START"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&ths); + rec_name_list->append("THS_STEP"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&thsstp); + rec_name_list->append("THS_END"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&thslst); + rec_name_list->append("PH_START"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&ph); + rec_name_list->append("PH_STEP"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&phstp); + rec_name_list->append("PH_END"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&phlst); + rec_name_list->append("PHS_START"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&phs); + rec_name_list->append("PHS_STEP"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&phsstp); + rec_name_list->append("PHS_END"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&phslst); + rec_name_list->append("EXRI"); + rec_type_list->append("FLOAT64_(1)"); + rec_ptr_list->append(&exri); + rec_name_list->append("IDFC"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&idfc); + rec_name_list->set(0, "NUM_CONF"); + rec_type_list->set(0, "INT32_(1)"); + rec_ptr_list->set(0, &configurations); + rec_name_list->append("XI1"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&_first_xi); + rec_name_list->append("NXI"); + rec_type_list->append("INT32_(1)"); + rec_ptr_list->append(&xi_block_size); + rec_name_list->append("VEC_JXI"); + rec_type_list->append("INT32_(" + to_string(xi_block_size) + ")"); + rec_ptr_list->append(vec_jxi); + rec_name_list->append("VEC_IER"); + rec_type_list->append("INT16_(" + to_string(xi_block_size) + ")"); + rec_ptr_list->append(vec_ier); + rec_name_list->append("VEC_VK"); + rec_type_list->append("FLOAT64_(" + to_string(xi_block_size) + ")"); + rec_ptr_list->append(vec_vk); + rec_name_list->append("VEC_XI"); + rec_type_list->append("FLOAT64_(" + to_string(xi_block_size) + ")"); + rec_ptr_list->append(vec_xi); + rec_name_list->append("VEC_SPH_SIZES"); + rec_type_list->append("FLOAT64_(" + to_string(configurations * xi_block_size) + ")"); + rec_ptr_list->append(vec_sphere_sizes); + rec_name_list->append("VEC_SPH_REFRI"); + rec_type_list->append("FLOAT64_(" + to_string(2 * configurations * xi_block_size) + ")"); + rec_ptr_list->append(vec_sphere_ref_indices); + str_type = "FLOAT64_(" + to_string(configurations * xi_block_size) + ")"; + rec_name_list->append("VEC_SCS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_scs); + rec_name_list->append("VEC_ABS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_abs); + rec_name_list->append("VEC_EXS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_exs); + rec_name_list->append("VEC_ALBEDS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_albeds); + rec_name_list->append("VEC_SCSRT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_scsrt); + rec_name_list->append("VEC_ABSRT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_absrt); + rec_name_list->append("VEC_EXSRT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_exsrt); + str_type = "FLOAT64_(" + to_string(2 * configurations * xi_block_size) + ")"; + rec_name_list->append("VEC_FSAS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_fsas); + str_type = "FLOAT64_(" + to_string(configurations * xi_block_size) + ")"; + rec_name_list->append("VEC_QSCHU"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_qschu); + rec_name_list->append("VEC_PSCHU"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_pschu); + rec_name_list->append("VEC_S0MAG"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_s0mag); + rec_name_list->append("VEC_COSAV"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_cosav); + rec_name_list->append("VEC_RAPRS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_raprs); + rec_name_list->append("VEC_TQEK1"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_tqek1); + rec_name_list->append("VEC_TQEK2"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_tqek2); + rec_name_list->append("VEC_TQSK1"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_tqsk1); + rec_name_list->append("VEC_TQSK2"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_tqsk2); + if (nsph != 1) { + str_type = "FLOAT64_(" + to_string(2 * xi_block_size) + ")"; + rec_name_list->append("VEC_FSAT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_fsat); + str_type = "FLOAT64_(" + to_string(xi_block_size) + ")"; + rec_name_list->append("VEC_QSCHUT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_qschut); + rec_name_list->append("VEC_PSCHUT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_pschut); + rec_name_list->append("VEC_S0MAGT"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_s0magt); + } + str_type = "FLOAT64_(" + to_string(ndirs) + ")"; + rec_name_list->append("VEC_DIR_SCAND"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_scand); + rec_name_list->append("VEC_DIR_CFMP"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_cfmp); + rec_name_list->append("VEC_DIR_CFSP"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_cfsp); + rec_name_list->append("VEC_DIR_SFMP"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sfmp); + rec_name_list->append("VEC_DIR_SFSP"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sfsp); + str_type = "FLOAT64_(" + to_string(3 * ndirs) + ")"; + rec_name_list->append("VEC_DIR_UN"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_un); + rec_name_list->append("VEC_DIR_UNS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_uns); + str_type = "FLOAT64_(" + to_string(2 * nsph * ndirs * xi_block_size) + ")"; + rec_name_list->append("VEC_DIR_SAS11"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sas11); + rec_name_list->append("VEC_DIR_SAS21"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sas21); + rec_name_list->append("VEC_DIR_SAS12"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sas12); + rec_name_list->append("VEC_DIR_SAS22"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_sas22); + str_type = "FLOAT64_(" + to_string(nsph * _num_theta * _num_phi * xi_block_size) + ")"; + rec_name_list->append("VEC_DIR_FX"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_fx); + rec_name_list->append("VEC_DIR_FY"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_fy); + rec_name_list->append("VEC_DIR_FZ"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_fz); + str_type = "FLOAT64_(" + to_string(16 * nsph * ndirs * xi_block_size) + ")"; + rec_name_list->append("VEC_DIR_MULS"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_muls); + rec_name_list->append("VEC_DIR_MULSLR"); + rec_type_list->append(str_type); + rec_ptr_list->append(vec_dir_mulslr); + + // Convert the lists to arrays and write them to HDF5 + string *rec_names = rec_name_list->to_array(); + string *rec_types = rec_type_list->to_array(); + void **rec_pointers = rec_ptr_list->to_array(); + const int rec_num = rec_name_list->length(); + FileSchema *schema = new FileSchema(rec_num, rec_types, rec_names); + HDFFile *hdf_file = HDFFile::from_schema(*schema, file_name, H5F_ACC_TRUNC); + for (int ri = 0; ri < rec_num; ri++) + hdf_file->write(rec_names[ri], rec_types[ri], rec_pointers[ri]); + hdf_file->close(); + + // Clean memory + delete rec_name_list; + delete rec_type_list; + delete rec_ptr_list; + delete[] rec_names; + delete[] rec_types; + delete[] rec_pointers; + delete schema; + delete hdf_file; + return 0; +} + +int SphereOutputInfo::write_legacy(const std::string &file_name) { + const dcomplex cc0 = 0.0 + I * 0.0; + int result = 0; + FILE *p_outfile = fopen(file_name.c_str(), "w"); + if (p_outfile != NULL) { + if (vec_jxi[0] == 1) { + fprintf(p_outfile, " READ(IR,*)NSPH,LM,INPOL,NPNT,NPNTTS,ISAM\n"); + fprintf( + p_outfile, " %5d%5d%5d%5d%5d%5d\n", + nsph, lm, inpol, npnt, npntts, isam + ); + fprintf(p_outfile, " READ(IR,*)TH,THSTP,THLST,THS,THSSTP,THSLST\n"); + fprintf( + p_outfile, " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", + th, thstp, thlst, ths, thsstp, thslst + ); + fprintf(p_outfile, " READ(IR,*)PH,PHSTP,PHLST,PHS,PHSSTP,PHSLST\n"); + fprintf( + p_outfile, " %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE %9.3lE\n", + ph, phstp, phlst, phs, phsstp, phslst + ); + fprintf(p_outfile, " READ(IR,*)JWTM\n"); + fprintf(p_outfile, " %5d\n", jwtm); + fprintf(p_outfile, " READ(ITIN)NSPHT\n"); + fprintf(p_outfile, " READ(ITIN)(IOG(I),I=1,NSPH)\n"); + fprintf(p_outfile, " READ(ITIN)EXDC,WP,XIP,IDFC,NXI\n"); + fprintf(p_outfile, " READ(ITIN)(XIV(I),I=1,NXI)\n"); + fprintf(p_outfile, " READ(ITIN)NSHL(I),ROS(I)\n"); + fprintf(p_outfile, " READ(ITIN)(RCF(I,NS),NS=1,NSH)\n \n"); + fprintf(p_outfile, " REFR. INDEX OF EXTERNAL MEDIUM=%15.7lE\n", exri); + if (inpol == 0) fprintf(p_outfile, " LIN\n \n"); + else fprintf(p_outfile, " CIRC\n \n"); + if (idfc < 0) { + fprintf(p_outfile, " VK=%15.7lE, XI IS SCALE FACTOR FOR LENGTHS\n \n", vec_vk[0]); + } + } // End preamble writing + // Wavelength loop + for (int jxi = 0; jxi < xi_block_size; jxi++) { + int done_dirs = 0; + fprintf(p_outfile, "========== JXI =%3d ====================\n", jxi + 1); + if (idfc >= 0) { + fprintf(p_outfile, " VK=%15.7lE, XI=%15.7lE\n", vec_xi[jxi], vec_vk[jxi]); + } else { // IDFC < 0 + fprintf(p_outfile, " XI=%15.7lE\n", vec_xi[jxi]); + } + if (vec_ier[jxi] == 1) { + fprintf(p_outfile, " STOP IN DME\n"); + fprintf( + p_outfile, " AT %1d LCALC=%3d TOO SMALL WITH ARG=%15.7lE+i(%15.7lE)\n", + (int)vec_ier[jxi], lcalc, real(arg), imag(arg) + ); + } + for (int ci = 0; ci < configurations; ci++) { + int cindex = jxi * configurations + ci; + fprintf(p_outfile, " SPHERE %2d\n", ci + 1); + if (vec_sphere_ref_indices[cindex] == cc0) { + fprintf(p_outfile, " SIZE=%15.7lE\n", vec_sphere_sizes[cindex]); + } else { + fprintf( + p_outfile, " SIZE=%15.7lE, REFRACTIVE INDEX=%15.7lE%15.7lE\n", + vec_sphere_sizes[cindex], real(vec_sphere_ref_indices[cindex]), + imag(vec_sphere_ref_indices[cindex]) + ); + } + fprintf(p_outfile, " ----- SCS ----- ABS ----- EXS ----- ALBEDS --\n"); + fprintf( + p_outfile, " %14.7lE%15.7lE%15.7lE%15.7lE\n", + vec_scs[cindex], vec_abs[cindex], vec_exs[cindex], vec_albeds[cindex] + ); + fprintf(p_outfile, " ---- SCS/GS -- ABS/GS -- EXS/GS ---\n"); + fprintf( + p_outfile, " %14.7lE%15.7lE%15.7lE\n", + vec_scsrt[cindex], vec_absrt[cindex], vec_exsrt[cindex] + ); + fprintf( + p_outfile, " FSAS=%15.7lE%15.7lE\n", + real(vec_fsas[cindex]), imag(vec_fsas[cindex]) + ); + fprintf( + p_outfile, " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", + vec_qschu[cindex], vec_pschu[cindex], vec_s0mag[cindex] + ); + fprintf( + p_outfile, " COSAV=%15.7lE, RAPRS=%15.7lE\n", + vec_cosav[cindex], vec_raprs[cindex] + ); + fprintf( + p_outfile, " IPO= 1, TQEk=%15.7lE, TQSk=%15.7lE\n", + vec_tqek1[cindex], vec_tqsk1[cindex] + ); + fprintf( + p_outfile, " IPO= 2, TQEk=%15.7lE, TQSk=%15.7lE\n", + vec_tqek2[cindex], vec_tqsk2[cindex] + ); + } // ci configuration loop + if (nsph != 1) { + fprintf( + p_outfile, " FSAT=(%15.7lE,%15.7lE)\n", + real(vec_fsat[jxi]), imag(vec_fsat[jxi]) + ); + fprintf( + p_outfile, " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", + vec_qschut[jxi], vec_pschut[jxi], vec_s0magt[jxi] + ); + } + for (int jth = 0; jth < _num_theta; jth++) { + for (int jph = 0; jph < _num_phi; jph++) { + for (int jths = 0; jths < _num_thetas; jths++) { + for (int jphs = 0; jphs < _num_phis; jphs++) { + int dir_index = ndirs * jxi + done_dirs; + bool goto190 = (done_dirs == 0) && ((jxi > 0) || (jth > 0) || (jph > 0)); + fprintf( + p_outfile, "********** JTH =%3d, JPH =%3d, JTHS =%3d, JPHS =%3d ********************\n", + jth + 1, jph + 1, jths + 1, jphs + 1 + ); + fprintf( + p_outfile, " TIDG=%10.3lE, PIDG=%10.3lE, TSDG=%10.3lE, PSDG=%10.3lE\n", + th + jth * thstp, + ph + jph * phstp, + ths + jths * thsstp, + phs + jphs * phsstp + ); + fprintf(p_outfile, " SCAND=%10.3lE\n", vec_dir_scand[done_dirs]); + fprintf( + p_outfile, " CFMP=%15.7lE, SFMP=%15.7lE\n", + vec_dir_cfmp[done_dirs], vec_dir_sfmp[done_dirs] + ); + fprintf( + p_outfile, " CFSP=%15.7lE, SFSP=%15.7lE\n", + vec_dir_cfsp[done_dirs], vec_dir_sfsp[done_dirs] + ); + if (isam >= 0) { + fprintf( + p_outfile, " UNI=(%12.5lE,%12.5lE,%12.5lE)\n", + vec_dir_un[3 * done_dirs], + vec_dir_un[3 * done_dirs + 1], + vec_dir_un[3 * done_dirs + 2] + ); + fprintf( + p_outfile, " UNS=(%12.5lE,%12.5lE,%12.5lE)\n", + vec_dir_uns[3 * done_dirs], + vec_dir_uns[3 * done_dirs + 1], + vec_dir_uns[3 * done_dirs + 2] + ); + } else { + fprintf( + p_outfile, " UN=(%12.5lE,%12.5lE,%12.5lE)\n", + vec_dir_un[3 * done_dirs], + vec_dir_un[3 * done_dirs + 1], + vec_dir_un[3 * done_dirs + 2] + ); + } + for (int i = 0; i < nsph; i++) { + int cindex = jxi * nsph * ndirs + nsph * done_dirs + i; + fprintf(p_outfile, " SPHERE %2d\n", i + 1); + fprintf( + p_outfile, " SAS(1,1)=%15.7lE%15.7lE, SAS(2,1)=%15.7lE%15.7lE\n", + real(vec_dir_sas11[cindex]), + imag(vec_dir_sas11[cindex]), + real(vec_dir_sas21[cindex]), + imag(vec_dir_sas21[cindex]) + ); + fprintf( + p_outfile, " SAS(1,2)=%15.7lE%15.7lE, SAS(2,2)=%15.7lE%15.7lE\n", + real(vec_dir_sas12[cindex]), + imag(vec_dir_sas12[cindex]), + real(vec_dir_sas22[cindex]), + imag(vec_dir_sas22[cindex]) + ); + if (jths == 0 && jphs == 0) { + fprintf( + p_outfile, " Fx=%15.7lE, Fy=%15.7lE, Fz=%15.7lE\n", + vec_dir_fx[jxi * nsph * _num_theta * _num_phi + jth * nsph * _num_phi + jph * nsph + i], + vec_dir_fy[jxi * nsph * _num_theta * _num_phi + jth * nsph * _num_phi + jph * nsph + i], + vec_dir_fz[jxi * nsph * _num_theta * _num_phi + jth * nsph * _num_phi + jph * nsph + i] + ); + } + fprintf(p_outfile, " MULS\n"); + for (int j = 0; j < 4; j++) { + int muls_index = 16 * cindex + 4 * j; + fprintf( + p_outfile, " %15.7lE%15.7lE%15.7lE%15.7lE\n", + vec_dir_muls[muls_index], + vec_dir_muls[muls_index + 1], + vec_dir_muls[muls_index + 2], + vec_dir_muls[muls_index + 3] + ); + } // j muls loop + fprintf(p_outfile, " MULSLR\n"); + for (int j = 0; j < 4; j++) { + int muls_index = 16 * cindex + 4 * j; + fprintf( + p_outfile, " %15.7lE%15.7lE%15.7lE%15.7lE\n", + vec_dir_mulslr[muls_index], + vec_dir_mulslr[muls_index + 1], + vec_dir_mulslr[muls_index + 2], + vec_dir_mulslr[muls_index + 3] + ); + } // j mulslr loop + } // i sphere loop + done_dirs++; + } // jphs loop + } // jths loop + } // jph loop + } // jth loop + } // jxi wavelength loop + fclose(p_outfile); + } else { + result = -1; + } + return result; +} + +#ifdef MPI_VERSION +int SphereOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { + int result = 0; + int chk_nsph, chk_inpol, chk_isam, chk_num_theta, chk_num_thetas; + int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; + double chk_exri; + MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_isam, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_num_theta, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_num_thetas, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_num_phi, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_num_phis, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_ndirs, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_exri, 1, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_idfc, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&chk_configs, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + result += (chk_nsph == nsph) ? 0 : 1; + result += (chk_inpol == inpol) ? 0 : 1; + result += (chk_isam == isam) ? 0 : 1; + result += (chk_num_theta == _num_theta) ? 0 : 1; + result += (chk_num_thetas == _num_thetas) ? 0 : 1; + result += (chk_num_phi == _num_phi) ? 0 : 1; + result += (chk_num_phis == _num_phis) ? 0 : 1; + result += (chk_ndirs == ndirs) ? 0 : 1; + result += (chk_exri == exri) ? 0 : 1; + result += (chk_idfc == idfc) ? 0 : 1; + result += (chk_configs == configurations) ? 0 : 1; + if (result == 0) { + int xi1, offset, chunk_size; + MPI_Send(&result, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD); + MPI_Recv(&xi1, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // Receive vectors of single values per scale + MPI_Recv(&chunk_size, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset = xi1 - _first_xi; + MPI_Recv(vec_jxi + offset, chunk_size, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_ier + offset, chunk_size, MPI_SHORT, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_vk + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_xi + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (nsph != 1) { + MPI_Recv(vec_fsat + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_qschut + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_pschut + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_s0magt + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + // Receive vectors whose sizes depend on configurations and wavelengths + MPI_Recv(&chunk_size, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset = (xi1 - _first_xi) * configurations; + MPI_Recv(vec_sphere_sizes + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_sphere_ref_indices + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_scs + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_abs + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_exs + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_albeds + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_scsrt + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_absrt + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_exsrt + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_fsas + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_qschu + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_pschu + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_s0mag + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_cosav + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_raprs + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_tqek1 + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_tqek2 + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_tqsk1 + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_tqsk2 + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + // Receive vectors whose sizes depend on NSPH, directions and wavelengths + MPI_Recv(&chunk_size, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset = (xi1 - _first_xi) * nsph * ndirs; + MPI_Recv(vec_dir_sas11 + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_sas21 + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_sas12 + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_sas22 + offset, chunk_size, MPI_C_DOUBLE_COMPLEX, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_muls + 16 * offset, 16 * chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_mulslr + 16 * offset, 16 * chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + // Receive vectors whose sizes depend on NSPH, incidence directions and wavelengths + MPI_Recv(&chunk_size, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset = (xi1 - _first_xi) * nsph * _num_theta * _num_phi; + MPI_Recv(vec_dir_fx + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_fy + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(vec_dir_fz + offset, chunk_size, MPI_DOUBLE, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + MPI_Send(&result, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD); + } + return result; +} + +int SphereOutputInfo::mpisend(const mixMPI *mpidata) { + int result = 0; + int chunk_size; + // Send output metadata for configuration cross-check + MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&isam, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&_num_theta, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&_num_thetas, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&_num_phi, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&_num_phis, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&ndirs, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&exri, 1, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(&idfc, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&configurations, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + // Wait for process 0 to cross-check the configuration + MPI_Recv(&result, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (result == 0) { + // Process 0 confirmed the consistency of configuration. Send the data. + // Send vectors of single values per scale + MPI_Send(&_first_xi, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(&xi_block_size, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_jxi, xi_block_size, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_ier, xi_block_size, MPI_SHORT, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_vk, xi_block_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_xi, xi_block_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + if (nsph != 1) { + MPI_Send(vec_fsat, xi_block_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_qschut, xi_block_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_pschut, xi_block_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_s0magt, xi_block_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + } + + // Send vectors whose sizes depend on configurations and scales + chunk_size = xi_block_size * configurations; + MPI_Send(&chunk_size, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_sphere_sizes, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_sphere_ref_indices, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_scs, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_abs, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_exs, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_albeds, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_scsrt, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_absrt, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_exsrt, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_fsas, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_qschu, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_pschu, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_s0mag, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_cosav, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_raprs, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_tqek1, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_tqek2, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_tqsk1, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_tqsk2, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + + // Send vectors whose sizes depend on NSPH, directions and wavelengths + chunk_size = xi_block_size * nsph * ndirs; + MPI_Send(&chunk_size, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_sas11, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_sas21, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_sas12, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_sas22, chunk_size, MPI_C_DOUBLE_COMPLEX, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_muls, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_mulslr, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + + // Send vectors whose sizes depend on NSPH, incidence directions and wavelengths + chunk_size = xi_block_size * nsph * _num_theta * _num_phi; + MPI_Send(vec_dir_fx, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_fy, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + MPI_Send(vec_dir_fz, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); + } + return result; +} +#endif // MPI_VERSION +// >>> END OF SphereOutputInfo CLASS IMPLEMENTATION <<< diff --git a/src/sphere/sphere.cpp b/src/sphere/sphere.cpp index 9f8c661698188683e17ea41db885f12f1fd658b3..dafa02def09757897e92c1b8ff336f04388ad1b4 100644 --- a/src/sphere/sphere.cpp +++ b/src/sphere/sphere.cpp @@ -51,6 +51,10 @@ #include "../include/TransitionMatrix.h" #endif +#ifndef INCLUDE_OUTPUTS_H_ +#include "../include/outputs.h" +#endif + using namespace std; /*! \brief C++ implementation of SPH @@ -90,6 +94,7 @@ void sphere(const string& config_file, const string& data_file, const string& ou } int s_nsph = sconf->number_of_spheres; int nsph = gconf->number_of_spheres; + int configurations = sconf->configurations; if (s_nsph == nsph) { int isq, ibf; double *argi, *args, *gaps; @@ -127,6 +132,7 @@ void sphere(const string& config_file, const string& data_file, const string& ou } double frx = 0.0, fry = 0.0, frz = 0.0; double cfmp, cfsp, sfmp, sfsp; + const dcomplex cc0 = 0.0 * I + 0.0; int jw; int l_max = gconf->l_max; ParticleDescriptor *c1 = new ParticleDescriptorSphere(gconf, sconf); @@ -150,48 +156,9 @@ void sphere(const string& config_file, const string& data_file, const string& ou 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", - nsph, - l_max, - in_pol, - npnt, - npntts, - 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", - in_theta_start, - in_theta_step, - in_theta_end, - sc_theta_start, - sc_theta_step, - 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", - in_phi_start, - in_phi_step, - in_phi_end, - sc_phi_start, - sc_phi_step, - sc_phi_end - ); - fprintf(output, " READ(IR,*)JWTM\n"); - fprintf(output, " %5d\n", 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"); + // FILE *output = fopen((output_path + "/c_OSPH").c_str(), "w"); + mixMPI *mpidata = new mixMPI(); // Fake MPI configuration + SphereOutputInfo *p_output = new SphereOutputInfo(sconf, gconf, mpidata); double sml = 1.0e-3; int nth = 0, nph = 0; if (in_theta_step != 0.0) @@ -253,7 +220,6 @@ void sphere(const string& config_file, const string& data_file, const string& ou thdps(l_max, zpv); double exdc = sconf->exdc; double exri = sqrt(exdc); - fprintf(output, " REFR. INDEX OF EXTERNAL MEDIUM=%15.7lE\n", exri); fstream tppoan; string tppoan_name = output_path + "/c_TPPOAN"; tppoan.open(tppoan_name.c_str(), ios::binary|ios::out); @@ -271,9 +237,6 @@ void sphere(const string& config_file, const string& data_file, const string& ou for (int nsi = 0; nsi < nsph; nsi++) tppoan.write(reinterpret_cast<char *>(&(c1->iog[nsi])), sizeof(int)); - if (in_pol == 0) fprintf(output, " LIN\n"); - else fprintf(output, " CIRC\n"); - fprintf(output, " \n"); double wp = sconf->wp; double xip = sconf->xip; double wn = wp / 3.0e8; @@ -283,22 +246,24 @@ void sphere(const string& config_file, const string& data_file, const string& ou int nxi = sconf->number_of_scales; if (idfc < 0) { vk = xip * wn; - fprintf(output, " VK=%15.7lE, XI IS SCALE FACTOR FOR LENGTHS\n", vk); - fprintf(output, " \n"); + p_output->vec_vk[0] = vk; } + int ndirs = nkks; for (int jxi488 = 0; jxi488 < nxi; jxi488++) { + int oindex = 0; int jxi = jxi488 + 1; logger->log("INFO: running scale iteration " + to_string(jxi) + " of " + to_string(nxi) + ".\n"); - fprintf(output, "========== JXI =%3d ====================\n", jxi); double xi = sconf->get_scale(jxi488); if (idfc >= 0) { vk = xi * wn; vkarg = vk; - fprintf(output, " VK=%15.7lE, XI=%15.7lE\n", xi, vk); + p_output->vec_vk[jxi488] = vk; + p_output->vec_xi[jxi488] = xi; } else { // IDFC < 0 vkarg = xi * vk; sqsfi = 1.0 / (xi * xi); - fprintf(output, " XI=%15.7lE\n", xi); + p_output->vec_vk[jxi488] = vk; + p_output->vec_xi[jxi488] = xi; } tppoan.write(reinterpret_cast<char *>(&vk), sizeof(double)); for (int i132 = 0; i132 < nsph; i132++) { @@ -329,10 +294,10 @@ void sphere(const string& config_file, const string& data_file, const string& ou int lcalc = 0; dme(l_max, i, npnt, npntts, vkarg, exdc, exri, c1, 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, real(arg), imag(arg)); + p_output->vec_ier[jxi] = 1; + p_output->lcalc = lcalc; + p_output->arg = arg; tppoan.close(); - fclose(output); delete sconf; delete gconf; delete c1; @@ -398,55 +363,47 @@ void sphere(const string& config_file, const string& data_file, const string& ou double sqk = vk * vk * exdc; aps(zpv, l_max, nsph, c1, sqk, gaps); rabas(in_pol, l_max, nsph, c1, tqse, tqspe, tqss, tqsps); + int last_configuration = 0; for (int i170 = 0; i170 < nsph; i170++) { int i = i170 + 1; if (c1->iog[i170] >= i) { + last_configuration++; + oindex = jxi488 * configurations + last_configuration - 1; 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", c1->vsz[i170]); + p_output->vec_sphere_ref_indices[oindex] = cc0; + p_output->vec_sphere_sizes[oindex] = c1->vsz[i170]; } else { - fprintf( - output, - " SIZE=%15.7lE, REFRACTIVE INDEX=%15.7lE%15.7lE\n", - c1->vsz[i170], - real(c1->vkt[i170]), - imag(c1->vkt[i170]) - ); + p_output->vec_sphere_ref_indices[oindex] = c1->vkt[i170]; + p_output->vec_sphere_sizes[oindex] = c1->vsz[i170]; } - 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", real(c1->fsas[i170]), imag(c1->fsas[i170])); + p_output->vec_scs[oindex] = c1->sscs[i170]; + p_output->vec_abs[oindex] = c1->sabs[i170]; + p_output->vec_exs[oindex] = c1->sexs[i170]; + p_output->vec_albeds[oindex] = albeds; + p_output->vec_scsrt[oindex] = c1->sqscs[i170]; + p_output->vec_absrt[oindex] = c1->sqabs[i170]; + p_output->vec_exsrt[oindex] = c1->sqexs[i170]; + p_output->vec_fsas[oindex] = c1->fsas[i170]; double csch = 2.0 * vk * sqsfi / c1->gcsv[i170]; s0 = c1->fsas[i170] * exri; double qschu = csch * imag(s0); double pschu = csch * real(s0); double s0mag = cs0 * cabs(s0); - fprintf( - output, - " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", - qschu, pschu, s0mag - ); + p_output->vec_qschu[oindex] = qschu; + p_output->vec_pschu[oindex] = pschu; + p_output->vec_s0mag[oindex] = 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]); + p_output->vec_cosav[oindex] = cosav; + p_output->vec_raprs[oindex] = rapr; + p_output->vec_tqek1[oindex] = tqse[0][i170]; + p_output->vec_tqsk1[oindex] = tqss[0][i170]; + p_output->vec_tqek2[oindex] = tqse[1][i170]; + p_output->vec_tqsk2[oindex] = 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 = real(tqspe[0][i170]); @@ -470,19 +427,18 @@ void sphere(const string& config_file, const string& data_file, const string& ou } // End if iog[i170] >= i } // i170 loop if (nsph != 1) { - fprintf(output, " FSAT=(%15.7lE,%15.7lE)\n", real(tfsas), imag(tfsas)); + p_output->vec_fsat[jxi488] = tfsas; double csch = 2.0 * vk * sqsfi / gcs; s0 = tfsas * exri; double qschu = csch * imag(s0); double pschu = csch * real(s0); double s0mag = cs0 * cabs(s0); - fprintf( - output, - " QSCHU=%15.7lE, PSCHU=%15.7lE, S0MAG=%15.7lE\n", - qschu, pschu, s0mag - ); + p_output->vec_qschut[jxi488] = qschu; + p_output->vec_pschut[jxi488] = pschu; + p_output->vec_s0magt[jxi488] = s0mag; } th = th1; + int done_dirs = 0; for (int jth486 = 0; jth486 < nth; jth486++) { // OpenMP parallelizable section int jth = jth486 + 1; ph = ph1; @@ -556,61 +512,51 @@ void sphere(const string& config_file, const string& data_file, const string& ou 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); + p_output->vec_dir_scand[done_dirs] = scan; + p_output->vec_dir_cfmp[done_dirs] = cfmp; + p_output->vec_dir_cfsp[done_dirs] = cfsp; + p_output->vec_dir_sfmp[done_dirs] = sfmp; + p_output->vec_dir_sfsp[done_dirs] = sfsp; if (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]); + p_output->vec_dir_un[3 * done_dirs] = un[0]; + p_output->vec_dir_un[3 * done_dirs + 1] = un[1]; + p_output->vec_dir_un[3 * done_dirs + 2] = un[2]; + p_output->vec_dir_uns[3 * done_dirs] = uns[0]; + p_output->vec_dir_uns[3 * done_dirs + 1] = uns[1]; + p_output->vec_dir_uns[3 * done_dirs + 2] = uns[2]; } else { - fprintf(output, " UN=(%12.5lE,%12.5lE,%12.5lE)\n", un[0], un[1], un[2]); + p_output->vec_dir_un[3 * done_dirs] = un[0]; + p_output->vec_dir_un[3 * done_dirs + 1] = un[1]; + p_output->vec_dir_un[3 * done_dirs + 2] = un[2]; + p_output->vec_dir_uns[3 * done_dirs] = 0.0; + p_output->vec_dir_uns[3 * done_dirs + 1] = 0.0; + p_output->vec_dir_uns[3 * done_dirs + 2] = 0.0; } sscr2(nsph, l_max, vk, exri, c1); + last_configuration = 0; 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", - real(c1->sas[ns226][0][0]), imag(c1->sas[ns226][0][0]), - real(c1->sas[ns226][1][0]), imag(c1->sas[ns226][1][0]) - ); - fprintf( - output, " SAS(1,2)=%15.7lE%15.7lE, SAS(2,2)=%15.7lE%15.7lE\n", - real(c1->sas[ns226][0][1]), imag(c1->sas[ns226][0][1]), - real(c1->sas[ns226][1][1]), imag(c1->sas[ns226][1][1]) - ); - if (jths == 1 && jphs == 1) - fprintf( - output, " Fx=%15.7lE, Fy=%15.7lE, Fz=%15.7lE\n", - frx, fry, frz - ); + oindex = jxi488 * nsph * ndirs + nsph * done_dirs + ns226; + p_output->vec_dir_sas11[oindex] = c1->sas[ns226][0][0]; + p_output->vec_dir_sas21[oindex] = c1->sas[ns226][1][0]; + p_output->vec_dir_sas12[oindex] = c1->sas[ns226][0][1]; + p_output->vec_dir_sas22[oindex] = c1->sas[ns226][1][1]; + p_output->vec_dir_fx[jxi488 * nsph * nth * nph + nsph * nph * (jth - 1) + nsph * (jph - 1) + ns226] = frx; + p_output->vec_dir_fy[jxi488 * nsph * nth * nph + nsph * nph * (jth - 1) + nsph * (jph - 1) + ns226] = fry; + p_output->vec_dir_fz[jxi488 * nsph * nth * nph + nsph * nph * (jth - 1) + nsph * (jph - 1) + ns226] = frz; for (int i225 = 0; i225 < 16; i225++) c1->vint[i225] = c1->vints[ns226][i225]; mmulc(c1->vint, cmullr, cmul); - fprintf(output, " MULS\n "); for (int imul = 0; imul < 4; imul++) { + int muls_index = 16 * jxi488 * nsph * ndirs + 16 * nsph * done_dirs + 4 * imul; for (int jmul = 0; jmul < 4; jmul++) { - fprintf(output, "%15.7lE", cmul[imul][jmul]); + p_output->vec_dir_muls[muls_index + jmul] = cmul[imul][jmul]; } - if (imul < 3) fprintf(output, "\n "); - else fprintf(output, "\n"); } - fprintf(output, " MULSLR\n "); for (int imul = 0; imul < 4; imul++) { + int muls_index = 16 * jxi488 * nsph * ndirs + 16 * nsph * done_dirs + 4 * imul; for (int jmul = 0; jmul < 4; jmul++) { - fprintf(output, "%15.7lE", cmullr[imul][jmul]); + p_output->vec_dir_mulslr[muls_index + jmul] = cmullr[imul][jmul]; } - if (imul < 3) fprintf(output, "\n "); - else fprintf(output, "\n"); } for (int vi = 0; vi < 16; vi++) { double value = real(c1->vint[vi]); @@ -625,6 +571,7 @@ void sphere(const string& config_file, const string& data_file, const string& ou } } // ns226 loop if (meridional_type < 1) phs += sc_phi_step; + done_dirs++; } // jphs480 loop if (meridional_type <= 1) thsl += sc_theta_step; } // jths482 loop @@ -632,13 +579,18 @@ void sphere(const string& config_file, const string& data_file, const string& ou } // jph484 loop on elevation th += in_theta_step; } // jth486 loop on azimuth + p_output->vec_jxi[jxi488] = jxi488 + 1; logger->log("INFO: finished scale iteration " + to_string(jxi) + " of " + to_string(nxi) + ".\n"); } //jxi488 loop on scales tppoan.close(); } else { // In case TPPOAN could not be opened. Should never happen. logger->err("ERROR: failed to open TPPOAN file.\n"); } - fclose(output); + // fclose(output); + p_output->write(output_path + "/c_OSPH.hd5", "HDF5"); + p_output->write(output_path + "/c_OSPH", "LEGACY"); + delete p_output; + delete mpidata; delete c1; for (int zi = l_max - 1; zi > -1; zi--) { for (int zj = 0; zj < 3; zj++) {