Program Listing for File NuMagSANSlib_SANSData.h#

↰ Return to documentation for file (src/OutputData/SANSData/NuMagSANSlib_SANSData.h)

// File         : NuMagSANSlib_SANSData.h
// Author       : Michael Philipp ADAMS, M.Sc.
// Company      : University of Luxembourg
// Department   : Department of Physics and Materials Sciences
// Group        : NanoMagnetism Group
// Group Leader : Prof. Andreas Michels
// Version      : 28 November 2024
// OS           : Linux Ubuntu
// Language     : CUDA C++

#include <iostream>
#include <fstream>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <math.h>
#include <string>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <stdexcept>
#include <math.h>
#include <chrono>
#include <dirent.h>
#include <unistd.h>
#include <filesystem>
#include <iomanip>

#include "NuMagSANSlib_SANSDataStruct.h"
#include "NuMagSANSlib_SANSData2csv.h"
#include "NuMagSANSlib_SANSData2hdf5.h"

using namespace std;

// #################################################################################################################################################
struct ScalingFactors {

    float Nuc_SANS_SF;                      // physical scaling factor for the nuclear SANS cross section
    float Mag_SANS_SF;                      // physical scaling factor for the magnetic SANS cross section
    float NucMag_SANS_SF;                   // physical scaling factor for the nuclear-magnetic SANS cross section
    float CorrelationMatrix_scaling_factor; // physical scaling factor for the Correlation matrizes in fourier space
                                            //  float correlation_function_1D_scaling_factor;
    // float pair_distance_distribution_1D_scaling_factor;
    //  float correlation_function_2D_scaling_factor;
    float CorF_Mag_2D_SF; // physical scaling factor for the magnetic correlation functions 2D

    float Nuc_Corr_SF;
    float Mag_Corr_SF;
    float NucMag_Corr_SF;

    float Nuc_PairDist_SF;
    float Mag_PairDist_SF;
    float NucMag_PairDist_SF;
};

// #################################################################################################################################################
void init_ScalingFactors(ScalingFactors* ScalFactors, InputFileData* InputData, MagnetizationData* MagData,
                         NuclearData* NucData, ScatteringData* SANSData) {

    // physical constants and scaling factors
    float mu_B = 9.2740100783 * 1e-24; // Bohr Magneton in units of Am^2
    float b_H = 2.91 * 1e8;            // Magnetic Scattering length in SI units
    float n_B = 1e-15;                 // nuclear scattering length scaling factor in units of femto meters

    // Total Scattering Volume in m^3
    float V = InputData->Scattering_Volume_V;

    // Micromagnetic properties
    float sx = InputData->cuboid_cell_size_x;     // cell size x in nanometers
    float sy = InputData->cuboid_cell_size_y;     // cell size y in nanometers
    float sz = InputData->cuboid_cell_size_z;     // cell size z in nanometers
    float Ms = InputData->cell_magnetization;     // saturation magnetization in units of A/m
    float mag_moment = Ms * sx * sy * sz * 1e-27; // cell magnetic moment

    // nuclear properties
    float cell_nuclear_sld = InputData->cell_nuclear_sld;     // nuclear scattering length density in units of 1/m^2
    float n_length = cell_nuclear_sld * sx * sy * sz * 1e-27; // nuclear scattering length in units of

    // Total Number of atoms
    unsigned long int W;
    unsigned long int N_avg;
    if (InputData->MagData_activate_flag) {
        W = *MagData->TotalAtomNumber;
        N_avg = *MagData->N_avg;
    } else {
        W = *NucData->TotalAtomNumber;
        N_avg = *NucData->N_avg;
    }

    if (InputData->Fourier_Approach == "atomistic") {

        ScalFactors->Nuc_SANS_SF = ((float)W) * ((float)N_avg) * powf(n_B, 2) / V * 1e-2;
        ScalFactors->Mag_SANS_SF =
            ((float)W) * ((float)N_avg) * powf(mu_B * b_H, 2) / V * 1e-2; // scaling factor for the SANS cross sections
        ScalFactors->NucMag_SANS_SF = ((float)W) * ((float)N_avg) * (n_B * mu_B * b_H) / V * 1e-2;
        ScalFactors->CorrelationMatrix_scaling_factor =
            powf(((float)N_avg) * mu_B, 2) /
            (8.0 * powf(M_PI, 3)); // scaling factor for the Fourier correlation functions

        ScalFactors->Nuc_Corr_SF = ScalFactors->Nuc_SANS_SF * 1e-7;
        ScalFactors->Mag_Corr_SF = ScalFactors->Mag_SANS_SF * 1e-7;
        ScalFactors->NucMag_Corr_SF = ScalFactors->NucMag_SANS_SF * 1e-7;

        ScalFactors->Nuc_PairDist_SF = ScalFactors->Nuc_SANS_SF * 1e-7;
        ScalFactors->Mag_PairDist_SF = ScalFactors->Mag_SANS_SF * 1e-7;
        ScalFactors->NucMag_PairDist_SF = ScalFactors->NucMag_SANS_SF * 1e-7;

        ScalFactors->CorF_Mag_2D_SF = ScalFactors->Mag_SANS_SF * (*SANSData->dr) * (*SANSData->dtheta);

    } else if (InputData->Fourier_Approach == "micromagnetic") {

        ScalFactors->Nuc_SANS_SF = ((float)W) * ((float)N_avg) * powf(n_length, 2) / V * 1e-2;
        ScalFactors->Mag_SANS_SF = ((float)W) * ((float)N_avg) * powf(mag_moment * b_H, 2) / V *
                                   1e-2; // scaling factor for the SANS cross sections
        ScalFactors->NucMag_SANS_SF = ((float)W) * ((float)N_avg) * (n_length * mag_moment * b_H) / V * 1e-2;
        ScalFactors->CorrelationMatrix_scaling_factor =
            powf(((float)N_avg) * mag_moment, 2) /
            (8.0 * powf(M_PI, 3)); // scaling factor for the Fourier correlation functions

        ScalFactors->Nuc_Corr_SF = ScalFactors->Nuc_SANS_SF * 1e-7;
        ScalFactors->Mag_Corr_SF = ScalFactors->Mag_SANS_SF * 1e-7;
        ScalFactors->NucMag_Corr_SF = ScalFactors->NucMag_SANS_SF * 1e-7;

        ScalFactors->Nuc_PairDist_SF = ScalFactors->Nuc_SANS_SF * 1e-7;
        ScalFactors->Mag_PairDist_SF =
            ScalFactors->Mag_SANS_SF * 1e-7; // scaling factor for the pair-distance distribution function
        ScalFactors->NucMag_PairDist_SF = ScalFactors->NucMag_SANS_SF * 1e-7;

        ScalFactors->CorF_Mag_2D_SF = ScalFactors->Mag_SANS_SF * (*SANSData->dr) * (*SANSData->dtheta);
    }

    LogSystem::write("magnetic SANS scaling factor: " + std::to_string(ScalFactors->Mag_SANS_SF));
    LogSystem::write("correlation Matrix scaling factor: " +
                     std::to_string(ScalFactors->CorrelationMatrix_scaling_factor));

    LogSystem::write("nuclear correlation function scaling factor: " + std::to_string(ScalFactors->Nuc_Corr_SF));
    LogSystem::write("magnetic correlation function scaling factor: " + std::to_string(ScalFactors->Mag_Corr_SF));
    LogSystem::write("nuclear correlation function distance scaling factor: " +
                     std::to_string(ScalFactors->NucMag_Corr_SF));

    LogSystem::write("nuclear pair distance scaling factor: " + std::to_string(ScalFactors->Nuc_PairDist_SF));
    LogSystem::write("magnetic pair distance scaling factor: " + std::to_string(ScalFactors->Mag_PairDist_SF));
    LogSystem::write("nuclear magnetic pair distance scaling factor: " +
                     std::to_string(ScalFactors->NucMag_PairDist_SF));

    LogSystem::write("correlation function 2D scaling factor: " + std::to_string(ScalFactors->CorF_Mag_2D_SF));
    LogSystem::write("");
}

// ###########################################################################################################################################
void scale_ScatteringData(ScalingFactors* ScalFactors, ScatteringData* SANSData, InputFileData* InputData) {

    LogSystem::write("");
    LogSystem::write("scale scattering data...");
    LogSystem::write("");

    //  unsigned int L = (InputData->N_q) * (InputData->N_theta);

    for (unsigned long int l = 0; l < (InputData->N_q) * (InputData->N_theta); l++) {

        SANSData->Gxx_real[l] = SANSData->Gxx_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyy_real[l] = SANSData->Gyy_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzz_real[l] = SANSData->Gzz_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gxy_real[l] = SANSData->Gxy_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyx_real[l] = SANSData->Gyx_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gxz_real[l] = SANSData->Gxz_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzx_real[l] = SANSData->Gzx_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyz_real[l] = SANSData->Gyz_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzy_real[l] = SANSData->Gzy_real[l] * ScalFactors->CorrelationMatrix_scaling_factor;

        SANSData->Gxx_imag[l] = SANSData->Gxx_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyy_imag[l] = SANSData->Gyy_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzz_imag[l] = SANSData->Gzz_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gxy_imag[l] = SANSData->Gxy_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyx_imag[l] = SANSData->Gyx_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gxz_imag[l] = SANSData->Gxz_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzx_imag[l] = SANSData->Gzx_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gyz_imag[l] = SANSData->Gyz_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;
        SANSData->Gzy_imag[l] = SANSData->Gzy_imag[l] * ScalFactors->CorrelationMatrix_scaling_factor;

        // basic SANS cross sections
        SANSData->S_Nuc_2D_unpolarized[l] = SANSData->S_Nuc_2D_unpolarized[l] * ScalFactors->Nuc_SANS_SF;
        SANSData->S_Mag_2D_unpolarized[l] = SANSData->S_Mag_2D_unpolarized[l] * ScalFactors->Mag_SANS_SF;
        SANSData->S_Mag_2D_polarized[l] = SANSData->S_Mag_2D_polarized[l] * ScalFactors->Mag_SANS_SF;
        ;
        SANSData->S_NucMag_2D[l] = SANSData->S_NucMag_2D[l] * ScalFactors->NucMag_SANS_SF;
        SANSData->S_Mag_2D_chiral[l] = SANSData->S_Mag_2D_chiral[l] * ScalFactors->Mag_SANS_SF;

        // composed SANS cross sections
        SANSData->S_Mag_2D_spin_flip[l] = SANSData->S_Mag_2D_unpolarized[l] - SANSData->S_Mag_2D_polarized[l];
        SANSData->S_Mag_2D_spin_flip_pm[l] = SANSData->S_Mag_2D_spin_flip[l] + SANSData->S_Mag_2D_chiral[l];
        SANSData->S_Mag_2D_spin_flip_mp[l] = SANSData->S_Mag_2D_spin_flip[l] - SANSData->S_Mag_2D_chiral[l];
        SANSData->S_Mag_2D_non_spin_flip_pp[l] =
            SANSData->S_Nuc_2D_unpolarized[l] + SANSData->S_NucMag_2D[l] + SANSData->S_Mag_2D_polarized[l];
        SANSData->S_Mag_2D_non_spin_flip_mm[l] =
            SANSData->S_Nuc_2D_unpolarized[l] - SANSData->S_NucMag_2D[l] + SANSData->S_Mag_2D_polarized[l];
        SANSData->S_Mag_2D_sanspol_p[l] = SANSData->S_Mag_2D_non_spin_flip_pp[l] + SANSData->S_Mag_2D_spin_flip_pm[l];
        SANSData->S_Mag_2D_sanspol_m[l] = SANSData->S_Mag_2D_non_spin_flip_mm[l] + SANSData->S_Mag_2D_spin_flip_mp[l];
    }

    for (unsigned long int l = 0; l < (InputData->N_q); l++) {

        // basic SANS cross sections
        SANSData->S_Nuc_1D_unpolarized[l] = SANSData->S_Nuc_1D_unpolarized[l] * ScalFactors->Nuc_SANS_SF;
        SANSData->S_Mag_1D_unpolarized[l] = SANSData->S_Mag_1D_unpolarized[l] * ScalFactors->Mag_SANS_SF;
        SANSData->S_Mag_1D_polarized[l] = SANSData->S_Mag_1D_polarized[l] * ScalFactors->Mag_SANS_SF;
        ;
        SANSData->S_NucMag_1D[l] = SANSData->S_NucMag_1D[l] * ScalFactors->NucMag_SANS_SF;
        SANSData->S_Mag_1D_chiral[l] = SANSData->S_Mag_1D_chiral[l] * ScalFactors->Mag_SANS_SF;

        // composed SANS cross sections
        SANSData->S_Mag_1D_spin_flip[l] = SANSData->S_Mag_1D_unpolarized[l] - SANSData->S_Mag_1D_polarized[l];
        SANSData->S_Mag_1D_spin_flip_pm[l] = SANSData->S_Mag_1D_spin_flip[l] + SANSData->S_Mag_1D_chiral[l];
        SANSData->S_Mag_1D_spin_flip_mp[l] = SANSData->S_Mag_1D_spin_flip[l] - SANSData->S_Mag_1D_chiral[l];
        SANSData->S_Mag_1D_non_spin_flip_pp[l] =
            SANSData->S_Nuc_1D_unpolarized[l] + SANSData->S_NucMag_1D[l] + SANSData->S_Mag_1D_polarized[l];
        SANSData->S_Mag_1D_non_spin_flip_mm[l] =
            SANSData->S_Nuc_1D_unpolarized[l] - SANSData->S_NucMag_1D[l] + SANSData->S_Mag_1D_polarized[l];
        SANSData->S_Mag_1D_sanspol_p[l] = SANSData->S_Mag_1D_non_spin_flip_pp[l] + SANSData->S_Mag_1D_spin_flip_pm[l];
        SANSData->S_Mag_1D_sanspol_m[l] = SANSData->S_Mag_1D_non_spin_flip_mm[l] + SANSData->S_Mag_1D_spin_flip_mp[l];
    }

    //  L = (InputData->N_r) * (InputData->N_alpha);

    for (unsigned long int l = 0; l < (InputData->N_r) * (InputData->N_alpha); l++) {

        // basic Correlation Functions
        SANSData->Corr_Nuc_2D_unpolarized[l] = SANSData->Corr_Nuc_2D_unpolarized[l] * ScalFactors->CorF_Mag_2D_SF;
        SANSData->Corr_Mag_2D_unpolarized[l] = SANSData->Corr_Mag_2D_unpolarized[l] * ScalFactors->CorF_Mag_2D_SF;
        SANSData->Corr_Mag_2D_polarized[l] = SANSData->Corr_Mag_2D_polarized[l] * ScalFactors->CorF_Mag_2D_SF;
        SANSData->Corr_NucMag_2D[l] = SANSData->Corr_NucMag_2D[l] * ScalFactors->CorF_Mag_2D_SF;
        SANSData->Corr_Mag_2D_chiral[l] = SANSData->Corr_Mag_2D_chiral[l] * ScalFactors->CorF_Mag_2D_SF;

        // composed SANS cross sections
        SANSData->Corr_Mag_2D_spin_flip[l] = SANSData->Corr_Mag_2D_unpolarized[l] - SANSData->Corr_Mag_2D_polarized[l];
        SANSData->Corr_Mag_2D_spin_flip_pm[l] = SANSData->Corr_Mag_2D_spin_flip[l] + SANSData->Corr_Mag_2D_chiral[l];
        SANSData->Corr_Mag_2D_spin_flip_mp[l] = SANSData->Corr_Mag_2D_spin_flip[l] - SANSData->Corr_Mag_2D_chiral[l];
        SANSData->Corr_Mag_2D_non_spin_flip_pp[l] =
            SANSData->Corr_Nuc_2D_unpolarized[l] + SANSData->Corr_NucMag_2D[l] + SANSData->Corr_Mag_2D_polarized[l];
        SANSData->Corr_Mag_2D_non_spin_flip_mm[l] =
            SANSData->Corr_Nuc_2D_unpolarized[l] - SANSData->Corr_NucMag_2D[l] + SANSData->Corr_Mag_2D_polarized[l];
        SANSData->Corr_Mag_2D_sanspol_p[l] =
            SANSData->Corr_Mag_2D_non_spin_flip_pp[l] + SANSData->Corr_Mag_2D_spin_flip_pm[l];
        SANSData->Corr_Mag_2D_sanspol_m[l] =
            SANSData->Corr_Mag_2D_non_spin_flip_mm[l] + SANSData->Corr_Mag_2D_spin_flip_mp[l];
    }

    for (unsigned long int l = 0; l < (InputData->N_r); l++) {

        // basic pair-distance distribution functions
        SANSData->p_Nuc_unpolarized[l] = SANSData->p_Nuc_unpolarized[l] * ScalFactors->Nuc_PairDist_SF;
        SANSData->p_Mag_unpolarized[l] = SANSData->p_Mag_unpolarized[l] * ScalFactors->Mag_PairDist_SF;
        SANSData->p_Mag_polarized[l] = SANSData->p_Mag_polarized[l] * ScalFactors->Mag_PairDist_SF;
        SANSData->p_NucMag[l] = SANSData->p_NucMag[l] * ScalFactors->NucMag_PairDist_SF;
        SANSData->p_Mag_chiral[l] = SANSData->p_Mag_chiral[l] * ScalFactors->Mag_PairDist_SF;

        // composed pair-distance distribution functions
        SANSData->p_Mag_spin_flip[l] = SANSData->p_Mag_unpolarized[l] - SANSData->p_Mag_polarized[l];
        SANSData->p_Mag_spin_flip_pm[l] = SANSData->p_Mag_spin_flip[l] + SANSData->p_Mag_chiral[l];
        SANSData->p_Mag_spin_flip_mp[l] = SANSData->p_Mag_spin_flip[l] - SANSData->p_Mag_chiral[l];
        SANSData->p_Mag_non_spin_flip_pp[l] =
            SANSData->p_Nuc_unpolarized[l] + SANSData->p_NucMag[l] + SANSData->p_Mag_polarized[l];
        SANSData->p_Mag_non_spin_flip_mm[l] =
            SANSData->p_Nuc_unpolarized[l] - SANSData->p_NucMag[l] + SANSData->p_Mag_polarized[l];
        SANSData->p_Mag_sanspol_p[l] = SANSData->p_Mag_non_spin_flip_pp[l] + SANSData->p_Mag_spin_flip_pm[l];
        SANSData->p_Mag_sanspol_m[l] = SANSData->p_Mag_non_spin_flip_mm[l] + SANSData->p_Mag_spin_flip_mp[l];

        // basic correlation functions
        SANSData->c_Nuc_unpolarized[l] = SANSData->c_Nuc_unpolarized[l] * ScalFactors->Nuc_Corr_SF;
        SANSData->c_Mag_unpolarized[l] = SANSData->c_Mag_unpolarized[l] * ScalFactors->Mag_Corr_SF;
        SANSData->c_Mag_polarized[l] = SANSData->c_Mag_polarized[l] * ScalFactors->Mag_Corr_SF;
        SANSData->c_NucMag[l] = SANSData->c_NucMag[l] * ScalFactors->NucMag_Corr_SF;
        SANSData->c_Mag_chiral[l] = SANSData->c_Mag_chiral[l] * ScalFactors->Mag_Corr_SF;

        // composed corelation functions
        SANSData->c_Mag_spin_flip[l] = SANSData->c_Mag_unpolarized[l] - SANSData->c_Mag_polarized[l];
        SANSData->c_Mag_spin_flip_pm[l] = SANSData->c_Mag_spin_flip[l] + SANSData->c_Mag_chiral[l];
        SANSData->c_Mag_spin_flip_mp[l] = SANSData->c_Mag_spin_flip[l] - SANSData->c_Mag_chiral[l];
        SANSData->c_Mag_non_spin_flip_pp[l] =
            SANSData->c_Nuc_unpolarized[l] + SANSData->c_NucMag[l] + SANSData->c_Mag_polarized[l];
        SANSData->c_Mag_non_spin_flip_mm[l] =
            SANSData->c_Nuc_unpolarized[l] - SANSData->c_NucMag[l] + SANSData->c_Mag_polarized[l];
        SANSData->c_Mag_sanspol_p[l] = SANSData->c_Mag_non_spin_flip_pp[l] + SANSData->c_Mag_spin_flip_pm[l];
        SANSData->c_Mag_sanspol_m[l] = SANSData->c_Mag_non_spin_flip_mm[l] + SANSData->c_Mag_spin_flip_mp[l];
    }
}

// ##########################################################################################################################
void allocate_ScatteringData_RAM(InputFileData* InputData, ScatteringData* SANSData) {

    SANSData->Polarization = (float*)malloc(3 * sizeof(float));
    SANSData->Polarization[0] = InputData->Polarization[0];
    SANSData->Polarization[1] = InputData->Polarization[1];
    SANSData->Polarization[2] = InputData->Polarization[2];

    SANSData->N_q = (unsigned int*)malloc(sizeof(unsigned int));
    SANSData->N_theta = (unsigned int*)malloc(sizeof(unsigned int));
    SANSData->N_r = (unsigned int*)malloc(sizeof(unsigned int));
    SANSData->N_alpha = (unsigned int*)malloc(sizeof(unsigned int));

    *SANSData->N_q = InputData->N_q;
    *SANSData->N_theta = InputData->N_theta;
    *SANSData->N_r = InputData->N_r;
    *SANSData->N_alpha = InputData->N_alpha;

    SANSData->q_min = (float*)malloc(sizeof(float));
    SANSData->q_max = (float*)malloc(sizeof(float));
    SANSData->r_max = (float*)malloc(sizeof(float));
    SANSData->dq = (float*)malloc(sizeof(float));
    SANSData->dtheta = (float*)malloc(sizeof(float));
    SANSData->dr = (float*)malloc(sizeof(float));
    SANSData->dalpha = (float*)malloc(sizeof(float));

    *SANSData->q_min = InputData->q_min;
    *SANSData->q_max = InputData->q_max;
    *SANSData->r_max = InputData->r_max;
    *SANSData->dq = (InputData->q_max - InputData->q_min) / ((float)InputData->N_q - 1.0);
    *SANSData->dr = (InputData->r_max) / ((float)InputData->N_r - 1.0);
    *SANSData->dtheta = (2.0 * M_PI) / ((float)InputData->N_theta - 1.0);
    *SANSData->dalpha = (2.0 * M_PI) / ((float)InputData->N_alpha - 1.0);

    unsigned int L = (InputData->N_q) * (InputData->N_theta);

    SANSData->q_2D = (float*)malloc(L * sizeof(float));
    SANSData->theta_2D = (float*)malloc(L * sizeof(float));
    SANSData->qy_2D = (float*)malloc(L * sizeof(float));
    SANSData->qz_2D = (float*)malloc(L * sizeof(float));

    SANSData->Gxx_real = (float*)malloc(L * sizeof(float));
    SANSData->Gyy_real = (float*)malloc(L * sizeof(float));
    SANSData->Gzz_real = (float*)malloc(L * sizeof(float));
    SANSData->Gxy_real = (float*)malloc(L * sizeof(float));
    SANSData->Gyx_real = (float*)malloc(L * sizeof(float));
    SANSData->Gxz_real = (float*)malloc(L * sizeof(float));
    SANSData->Gzx_real = (float*)malloc(L * sizeof(float));
    SANSData->Gyz_real = (float*)malloc(L * sizeof(float));
    SANSData->Gzy_real = (float*)malloc(L * sizeof(float));

    SANSData->Gxx_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gyy_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gzz_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gxy_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gyx_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gxz_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gzx_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gyz_imag = (float*)malloc(L * sizeof(float));
    SANSData->Gzy_imag = (float*)malloc(L * sizeof(float));

    SANSData->S_Nuc_2D_unpolarized = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_unpolarized = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_polarized = (float*)malloc(L * sizeof(float));
    SANSData->S_NucMag_2D = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_spin_flip = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_chiral = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_spin_flip_pm = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_spin_flip_mp = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_non_spin_flip_pp = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_non_spin_flip_mm = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_sanspol_p = (float*)malloc(L * sizeof(float));
    SANSData->S_Mag_2D_sanspol_m = (float*)malloc(L * sizeof(float));

    SANSData->q_1D = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Nuc_1D_unpolarized = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_unpolarized = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_polarized = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_NucMag_1D = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_spin_flip = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_chiral = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_spin_flip_pm = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_spin_flip_mp = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_non_spin_flip_pp = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_non_spin_flip_mm = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_sanspol_p = (float*)malloc((InputData->N_q) * sizeof(float));
    SANSData->S_Mag_1D_sanspol_m = (float*)malloc((InputData->N_q) * sizeof(float));

    for (unsigned int i = 0; i < InputData->N_q; i++) {

        SANSData->q_1D[i] = InputData->q_min + i * (*SANSData->dq);
        SANSData->S_Nuc_1D_unpolarized[i] = 0.0;
        SANSData->S_Mag_1D_unpolarized[i] = 0.0;
        SANSData->S_Mag_1D_polarized[i] = 0.0;
        SANSData->S_NucMag_1D[i] = 0.0;
        SANSData->S_Mag_1D_spin_flip[i] = 0.0;
        SANSData->S_Mag_1D_chiral[i] = 0.0;
        SANSData->S_Mag_1D_spin_flip_pm[i] = 0.0;
        SANSData->S_Mag_1D_spin_flip_mp[i] = 0.0;
        SANSData->S_Mag_1D_non_spin_flip_pp[i] = 0.0;
        SANSData->S_Mag_1D_non_spin_flip_mm[i] = 0.0;
        SANSData->S_Mag_1D_sanspol_p[i] = 0.0;
        SANSData->S_Mag_1D_sanspol_m[i] = 0.0;

        for (unsigned int j = 0; j < InputData->N_theta; j++) {

            SANSData->q_2D[j + i * (InputData->N_theta)] = SANSData->q_1D[i];
            SANSData->theta_2D[j + i * (InputData->N_theta)] = j * (*SANSData->dtheta);
            SANSData->qy_2D[j + i * (InputData->N_theta)] = SANSData->q_1D[i] * sinf(j * (*SANSData->dtheta));
            SANSData->qz_2D[j + i * (InputData->N_theta)] = SANSData->q_1D[i] * cosf(j * (*SANSData->dtheta));

            SANSData->Gxx_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyy_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzz_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gxy_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyx_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gxz_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzx_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyz_real[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzy_real[j + i * (InputData->N_theta)] = 0.0;

            SANSData->Gxx_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyy_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzz_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gxy_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyx_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gxz_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzx_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gyz_imag[j + i * (InputData->N_theta)] = 0.0;
            SANSData->Gzy_imag[j + i * (InputData->N_theta)] = 0.0;

            SANSData->S_Nuc_2D_unpolarized[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_unpolarized[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_NucMag_2D[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_polarized[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_spin_flip[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_chiral[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_spin_flip_pm[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_spin_flip_mp[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_non_spin_flip_pp[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_non_spin_flip_mm[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_sanspol_p[j + i * (InputData->N_theta)] = 0.0;
            SANSData->S_Mag_2D_sanspol_m[j + i * (InputData->N_theta)] = 0.0;
        }
    }

    L = (InputData->N_r) * (InputData->N_alpha);

    SANSData->r_2D = (float*)malloc(L * sizeof(float));
    SANSData->alpha_2D = (float*)malloc(L * sizeof(float));
    SANSData->ry_2D = (float*)malloc(L * sizeof(float));
    SANSData->rz_2D = (float*)malloc(L * sizeof(float));

    SANSData->Corr_Nuc_2D_unpolarized = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_unpolarized = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_polarized = (float*)malloc(L * sizeof(float));
    SANSData->Corr_NucMag_2D = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_spin_flip = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_chiral = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_spin_flip_mp = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_spin_flip_pm = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_non_spin_flip_pp = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_non_spin_flip_mm = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_sanspol_p = (float*)malloc(L * sizeof(float));
    SANSData->Corr_Mag_2D_sanspol_m = (float*)malloc(L * sizeof(float));

    SANSData->r_1D = (float*)malloc((InputData->N_r) * sizeof(float));

    SANSData->p_Nuc_unpolarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_unpolarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_polarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_NucMag = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_chiral = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_spin_flip = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_spin_flip_pm = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_spin_flip_mp = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_non_spin_flip_pp = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_non_spin_flip_mm = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_sanspol_p = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->p_Mag_sanspol_m = (float*)malloc((InputData->N_r) * sizeof(float));

    SANSData->c_Nuc_unpolarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_unpolarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_polarized = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_NucMag = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_chiral = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_spin_flip = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_spin_flip_pm = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_spin_flip_mp = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_non_spin_flip_pp = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_non_spin_flip_mm = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_sanspol_p = (float*)malloc((InputData->N_r) * sizeof(float));
    SANSData->c_Mag_sanspol_m = (float*)malloc((InputData->N_r) * sizeof(float));

    for (unsigned int i = 0; i < InputData->N_r; i++) {

        SANSData->r_1D[i] = i * (*SANSData->dr);
        SANSData->p_Nuc_unpolarized[i] = 0.0;
        SANSData->p_Mag_unpolarized[i] = 0.0;
        SANSData->p_Mag_polarized[i] = 0.0;
        SANSData->p_NucMag[i] = 0.0;
        SANSData->p_Mag_chiral[i] = 0.0;
        SANSData->p_Mag_spin_flip[i] = 0.0;
        SANSData->p_Mag_spin_flip_pm[i] = 0.0;
        SANSData->p_Mag_spin_flip_mp[i] = 0.0;
        SANSData->p_Mag_non_spin_flip_pp[i] = 0.0;
        SANSData->p_Mag_non_spin_flip_mm[i] = 0.0;
        SANSData->p_Mag_sanspol_p[i] = 0.0;
        SANSData->p_Mag_sanspol_m[i] = 0.0;

        SANSData->c_Nuc_unpolarized[i] = 0.0;
        SANSData->c_Mag_unpolarized[i] = 0.0;
        SANSData->c_Mag_polarized[i] = 0.0;
        SANSData->c_NucMag[i] = 0.0;
        SANSData->c_Mag_chiral[i] = 0.0;
        SANSData->c_Mag_spin_flip[i] = 0.0;
        SANSData->c_Mag_spin_flip_pm[i] = 0.0;
        SANSData->c_Mag_spin_flip_mp[i] = 0.0;
        SANSData->c_Mag_non_spin_flip_pp[i] = 0.0;
        SANSData->c_Mag_non_spin_flip_mm[i] = 0.0;
        SANSData->c_Mag_sanspol_p[i] = 0.0;
        SANSData->c_Mag_sanspol_m[i] = 0.0;

        for (unsigned int j = 0; j < InputData->N_alpha; j++) {

            SANSData->r_2D[j + i * (InputData->N_alpha)] = i * (*SANSData->dr);
            SANSData->alpha_2D[j + i * (InputData->N_alpha)] = j * (*SANSData->dalpha);
            SANSData->ry_2D[j + i * (InputData->N_alpha)] = SANSData->r_1D[i] * sinf(j * (*SANSData->dalpha));
            SANSData->rz_2D[j + i * (InputData->N_alpha)] = SANSData->r_1D[i] * cosf(j * (*SANSData->dalpha));

            SANSData->Corr_Nuc_2D_unpolarized[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_unpolarized[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_polarized[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_NucMag_2D[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_spin_flip[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_chiral[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_spin_flip_mp[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_spin_flip_pm[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_non_spin_flip_pp[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_non_spin_flip_mm[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_sanspol_p[j + i * (InputData->N_alpha)] = 0.0;
            SANSData->Corr_Mag_2D_sanspol_m[j + i * (InputData->N_alpha)] = 0.0;
        }
    }
}

// ####################################################################################################################################
void allocate_ScatteringData_GPU(ScatteringData* SANSData, ScatteringData* SANSData_gpu) {

    cudaMalloc(&SANSData_gpu->Polarization, 3 * sizeof(float));
    cudaMemcpy(SANSData_gpu->Polarization, SANSData->Polarization, 3 * sizeof(float), cudaMemcpyHostToDevice);

    cudaMalloc(&SANSData_gpu->N_q, sizeof(unsigned int));
    cudaMalloc(&SANSData_gpu->N_theta, sizeof(unsigned int));
    cudaMalloc(&SANSData_gpu->N_r, sizeof(unsigned int));
    cudaMalloc(&SANSData_gpu->N_alpha, sizeof(unsigned int));

    cudaMemcpy(SANSData_gpu->N_q, SANSData->N_q, sizeof(unsigned int), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->N_theta, SANSData->N_theta, sizeof(unsigned int), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->N_r, SANSData->N_r, sizeof(unsigned int), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->N_alpha, SANSData->N_alpha, sizeof(unsigned int), cudaMemcpyHostToDevice);

    cudaMalloc(&SANSData_gpu->q_min, sizeof(float));
    cudaMalloc(&SANSData_gpu->q_max, sizeof(float));
    cudaMalloc(&SANSData_gpu->r_max, sizeof(float));

    cudaMemcpy(SANSData_gpu->q_min, SANSData->q_min, sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->q_max, SANSData->q_max, sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->r_max, SANSData->r_max, sizeof(float), cudaMemcpyHostToDevice);

    cudaMalloc(&SANSData_gpu->dq, sizeof(float));
    cudaMalloc(&SANSData_gpu->dtheta, sizeof(float));
    cudaMalloc(&SANSData_gpu->dr, sizeof(float));
    cudaMalloc(&SANSData_gpu->dalpha, sizeof(float));

    cudaMemcpy(SANSData_gpu->dq, SANSData->dq, sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->dtheta, SANSData->dtheta, sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->dr, SANSData->dr, sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->dalpha, SANSData->dalpha, sizeof(float), cudaMemcpyHostToDevice);

    unsigned int L = (*SANSData->N_q) * (*SANSData->N_theta);

    cudaMalloc(&SANSData_gpu->q_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->theta_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->qy_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->qz_2D, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->Gxx_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyy_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzz_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gxy_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyx_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gxz_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzx_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyz_real, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzy_real, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->Gxx_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyy_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzz_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gxy_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyx_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gxz_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzx_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gyz_imag, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Gzy_imag, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->S_Nuc_2D_unpolarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_unpolarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_NucMag_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_polarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_spin_flip, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_chiral, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_spin_flip_pm, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_spin_flip_mp, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_non_spin_flip_pp, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_non_spin_flip_mm, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_sanspol_p, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_2D_sanspol_m, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->q_1D, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Nuc_1D_unpolarized, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_unpolarized, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_NucMag_1D, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_polarized, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_spin_flip, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_chiral, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_spin_flip_pm, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_spin_flip_mp, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_non_spin_flip_pp, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_non_spin_flip_mm, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_sanspol_p, (*SANSData->N_q) * sizeof(float));
    cudaMalloc(&SANSData_gpu->S_Mag_1D_sanspol_m, (*SANSData->N_q) * sizeof(float));

    cudaMemcpy(SANSData_gpu->q_2D, SANSData->q_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->theta_2D, SANSData->theta_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->qy_2D, SANSData->qy_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->qz_2D, SANSData->qz_2D, L * sizeof(float), cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->Gxx_real, SANSData->Gxx_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyy_real, SANSData->Gyy_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzz_real, SANSData->Gzz_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gxy_real, SANSData->Gxy_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyx_real, SANSData->Gyx_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gxz_real, SANSData->Gxz_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzx_real, SANSData->Gzx_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyz_real, SANSData->Gyz_real, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzy_real, SANSData->Gzy_real, L * sizeof(float), cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->Gxx_imag, SANSData->Gxx_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyy_imag, SANSData->Gyy_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzz_imag, SANSData->Gzz_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gxy_imag, SANSData->Gxy_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyx_imag, SANSData->Gyx_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gxz_imag, SANSData->Gxz_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzx_imag, SANSData->Gzx_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gyz_imag, SANSData->Gyz_imag, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Gzy_imag, SANSData->Gzy_imag, L * sizeof(float), cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->S_Nuc_2D_unpolarized, SANSData->S_Nuc_2D_unpolarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_unpolarized, SANSData->S_Mag_2D_unpolarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_NucMag_2D, SANSData->S_NucMag_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_polarized, SANSData->S_Mag_2D_polarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_spin_flip, SANSData->S_Mag_2D_spin_flip, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_chiral, SANSData->S_Mag_2D_chiral, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_spin_flip_pm, SANSData->S_Mag_2D_spin_flip_pm, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_spin_flip_mp, SANSData->S_Mag_2D_spin_flip_mp, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_non_spin_flip_pp, SANSData->S_Mag_2D_non_spin_flip_pp, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_non_spin_flip_mm, SANSData->S_Mag_2D_non_spin_flip_mm, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_sanspol_p, SANSData->S_Mag_2D_sanspol_p, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_2D_sanspol_m, SANSData->S_Mag_2D_sanspol_m, L * sizeof(float),
               cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->q_1D, SANSData->q_1D, (*SANSData->N_q) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Nuc_1D_unpolarized, SANSData->S_Nuc_1D_unpolarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_unpolarized, SANSData->S_Mag_1D_unpolarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_NucMag_1D, SANSData->S_NucMag_1D, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_polarized, SANSData->S_Mag_1D_polarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_spin_flip, SANSData->S_Mag_1D_spin_flip, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_chiral, SANSData->S_Mag_1D_chiral, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_spin_flip_pm, SANSData->S_Mag_1D_spin_flip_pm, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_spin_flip_mp, SANSData->S_Mag_1D_spin_flip_mp, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_non_spin_flip_pp, SANSData->S_Mag_1D_non_spin_flip_pp,
               (*SANSData->N_q) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_non_spin_flip_mm, SANSData->S_Mag_1D_non_spin_flip_mm,
               (*SANSData->N_q) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_sanspol_p, SANSData->S_Mag_1D_sanspol_p, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->S_Mag_1D_sanspol_m, SANSData->S_Mag_1D_sanspol_m, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyHostToDevice);

    L = (*SANSData->N_r) * (*SANSData->N_alpha);

    cudaMalloc(&SANSData_gpu->r_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->alpha_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->ry_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->rz_2D, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->Corr_Nuc_2D_unpolarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_unpolarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_polarized, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_NucMag_2D, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_spin_flip, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_chiral, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_spin_flip_mp, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_spin_flip_pm, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_non_spin_flip_pp, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_non_spin_flip_mm, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_sanspol_p, L * sizeof(float));
    cudaMalloc(&SANSData_gpu->Corr_Mag_2D_sanspol_m, L * sizeof(float));

    cudaMalloc(&SANSData_gpu->p_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_unpolarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_polarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_NucMag, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_chiral, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_spin_flip, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_sanspol_p, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->p_Mag_sanspol_m, (*SANSData->N_r) * sizeof(float));

    cudaMalloc(&SANSData_gpu->c_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_unpolarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_polarized, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_NucMag, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_chiral, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_spin_flip, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_sanspol_p, (*SANSData->N_r) * sizeof(float));
    cudaMalloc(&SANSData_gpu->c_Mag_sanspol_m, (*SANSData->N_r) * sizeof(float));

    cudaMalloc(&SANSData_gpu->r_1D, (*SANSData->N_r) * sizeof(float));

    cudaMemcpy(SANSData_gpu->r_2D, SANSData->r_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->alpha_2D, SANSData->alpha_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->ry_2D, SANSData->ry_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->rz_2D, SANSData->rz_2D, L * sizeof(float), cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->Corr_Nuc_2D_unpolarized, SANSData->Corr_Nuc_2D_unpolarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_unpolarized, SANSData->Corr_Mag_2D_unpolarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_polarized, SANSData->Corr_Mag_2D_polarized, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_NucMag_2D, SANSData->Corr_NucMag_2D, L * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_spin_flip, SANSData->Corr_Mag_2D_spin_flip, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_chiral, SANSData->Corr_Mag_2D_chiral, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_spin_flip_mp, SANSData->Corr_Mag_2D_spin_flip_mp, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_spin_flip_pm, SANSData->Corr_Mag_2D_spin_flip_pm, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_non_spin_flip_pp, SANSData->Corr_Mag_2D_non_spin_flip_pp, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_non_spin_flip_mm, SANSData->Corr_Mag_2D_non_spin_flip_mm, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_sanspol_p, SANSData->Corr_Mag_2D_sanspol_p, L * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->Corr_Mag_2D_sanspol_m, SANSData->Corr_Mag_2D_sanspol_m, L * sizeof(float),
               cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->p_Nuc_unpolarized, SANSData->p_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_unpolarized, SANSData->p_Mag_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_polarized, SANSData->p_Mag_polarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_NucMag, SANSData->p_NucMag, (*SANSData->N_r) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_spin_flip, SANSData->p_Mag_spin_flip, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_chiral, SANSData->p_Mag_chiral, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_spin_flip_pm, SANSData->p_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_spin_flip_mp, SANSData->p_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_non_spin_flip_pp, SANSData->p_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_non_spin_flip_mm, SANSData->p_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_sanspol_p, SANSData->p_Mag_sanspol_p, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->p_Mag_sanspol_m, SANSData->p_Mag_sanspol_m, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->c_Nuc_unpolarized, SANSData->c_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_unpolarized, SANSData->c_Mag_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_polarized, SANSData->c_Mag_polarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_NucMag, SANSData->c_NucMag, (*SANSData->N_r) * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_spin_flip, SANSData->c_Mag_spin_flip, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_chiral, SANSData->c_Mag_chiral, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_spin_flip_pm, SANSData->c_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_spin_flip_mp, SANSData->c_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_non_spin_flip_pp, SANSData->c_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_non_spin_flip_mm, SANSData->c_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_sanspol_p, SANSData->c_Mag_sanspol_p, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaMemcpy(SANSData_gpu->c_Mag_sanspol_m, SANSData->c_Mag_sanspol_m, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyHostToDevice);

    cudaMemcpy(SANSData_gpu->r_1D, SANSData->r_1D, (*SANSData->N_r) * sizeof(float), cudaMemcpyHostToDevice);

    cudaMalloc(&SANSData_gpu, sizeof(ScatteringData));
    cudaMemcpy(SANSData_gpu, SANSData, sizeof(ScatteringData), cudaMemcpyHostToDevice);
}

// ###########################################################################################################################################
void init_ScatteringData(InputFileData* InputData, ScatteringData* SANSData, ScatteringData* SANSData_gpu) {

    allocate_ScatteringData_RAM(InputData, SANSData);
    allocate_ScatteringData_GPU(SANSData, SANSData_gpu);
}

// ###########################################################################################################################################
void copyGPU2RAM_ScatteringData(ScatteringData* SANSData, ScatteringData* SANSData_gpu) {

    cudaDeviceSynchronize();

    LogSystem::write("");
    LogSystem::write("copy SANSdata from GPU to RAM...");
    LogSystem::write("");

    unsigned int L = (*SANSData->N_q) * (*SANSData->N_theta);

    cudaMemcpy(SANSData->qy_2D, SANSData_gpu->qy_2D, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->qz_2D, SANSData_gpu->qz_2D, L * sizeof(float), cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->Gxx_real, SANSData_gpu->Gxx_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyy_real, SANSData_gpu->Gyy_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzz_real, SANSData_gpu->Gzz_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gxy_real, SANSData_gpu->Gxy_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyx_real, SANSData_gpu->Gyx_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gxz_real, SANSData_gpu->Gxz_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzx_real, SANSData_gpu->Gzx_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyz_real, SANSData_gpu->Gyz_real, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzy_real, SANSData_gpu->Gzy_real, L * sizeof(float), cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->Gxx_imag, SANSData_gpu->Gxx_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyy_imag, SANSData_gpu->Gyy_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzz_imag, SANSData_gpu->Gzz_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gxy_imag, SANSData_gpu->Gxy_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyx_imag, SANSData_gpu->Gyx_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gxz_imag, SANSData_gpu->Gxz_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzx_imag, SANSData_gpu->Gzx_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gyz_imag, SANSData_gpu->Gyz_imag, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Gzy_imag, SANSData_gpu->Gzy_imag, L * sizeof(float), cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->S_Nuc_2D_unpolarized, SANSData_gpu->S_Nuc_2D_unpolarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_unpolarized, SANSData_gpu->S_Mag_2D_unpolarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_NucMag_2D, SANSData_gpu->S_NucMag_2D, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_polarized, SANSData_gpu->S_Mag_2D_polarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_spin_flip, SANSData_gpu->S_Mag_2D_spin_flip, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_chiral, SANSData_gpu->S_Mag_2D_chiral, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_spin_flip_pm, SANSData_gpu->S_Mag_2D_spin_flip_pm, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_spin_flip_mp, SANSData_gpu->S_Mag_2D_spin_flip_mp, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_non_spin_flip_pp, SANSData_gpu->S_Mag_2D_non_spin_flip_pp, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_non_spin_flip_mm, SANSData_gpu->S_Mag_2D_non_spin_flip_mm, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_sanspol_p, SANSData_gpu->S_Mag_2D_sanspol_p, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_2D_sanspol_m, SANSData_gpu->S_Mag_2D_sanspol_m, L * sizeof(float),
               cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->S_Nuc_1D_unpolarized, SANSData_gpu->S_Nuc_1D_unpolarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_unpolarized, SANSData_gpu->S_Mag_1D_unpolarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_NucMag_1D, SANSData_gpu->S_NucMag_1D, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_polarized, SANSData_gpu->S_Mag_1D_polarized, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_spin_flip, SANSData_gpu->S_Mag_1D_spin_flip, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_chiral, SANSData_gpu->S_Mag_1D_chiral, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_spin_flip_pm, SANSData_gpu->S_Mag_1D_spin_flip_pm, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_spin_flip_mp, SANSData_gpu->S_Mag_1D_spin_flip_mp, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_non_spin_flip_pp, SANSData_gpu->S_Mag_1D_non_spin_flip_pp,
               (*SANSData->N_q) * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_non_spin_flip_mm, SANSData_gpu->S_Mag_1D_non_spin_flip_mm,
               (*SANSData->N_q) * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_sanspol_p, SANSData_gpu->S_Mag_1D_sanspol_p, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->S_Mag_1D_sanspol_m, SANSData_gpu->S_Mag_1D_sanspol_m, (*SANSData->N_q) * sizeof(float),
               cudaMemcpyDeviceToHost);

    L = (*SANSData->N_r) * (*SANSData->N_alpha);

    cudaMemcpy(SANSData->Corr_Nuc_2D_unpolarized, SANSData_gpu->Corr_Nuc_2D_unpolarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_unpolarized, SANSData_gpu->Corr_Mag_2D_unpolarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_polarized, SANSData_gpu->Corr_Mag_2D_polarized, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_NucMag_2D, SANSData_gpu->Corr_NucMag_2D, L * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_spin_flip, SANSData_gpu->Corr_Mag_2D_spin_flip, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_chiral, SANSData_gpu->Corr_Mag_2D_chiral, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_spin_flip_mp, SANSData_gpu->Corr_Mag_2D_spin_flip_mp, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_spin_flip_pm, SANSData_gpu->Corr_Mag_2D_spin_flip_pm, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_non_spin_flip_pp, SANSData_gpu->Corr_Mag_2D_non_spin_flip_pp, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_non_spin_flip_mm, SANSData_gpu->Corr_Mag_2D_non_spin_flip_mm, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_sanspol_p, SANSData_gpu->Corr_Mag_2D_sanspol_p, L * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->Corr_Mag_2D_sanspol_m, SANSData_gpu->Corr_Mag_2D_sanspol_m, L * sizeof(float),
               cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->p_Nuc_unpolarized, SANSData_gpu->p_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_unpolarized, SANSData_gpu->p_Mag_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_polarized, SANSData_gpu->p_Mag_polarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_NucMag, SANSData_gpu->p_NucMag, (*SANSData->N_r) * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_spin_flip, SANSData_gpu->p_Mag_spin_flip, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_chiral, SANSData_gpu->p_Mag_chiral, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_spin_flip_pm, SANSData_gpu->p_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_spin_flip_mp, SANSData_gpu->p_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_non_spin_flip_pp, SANSData_gpu->p_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->p_Mag_non_spin_flip_mm, SANSData_gpu->p_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);

    cudaMemcpy(SANSData->c_Nuc_unpolarized, SANSData_gpu->c_Nuc_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_unpolarized, SANSData_gpu->c_Mag_unpolarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_polarized, SANSData_gpu->c_Mag_polarized, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_NucMag, SANSData_gpu->c_NucMag, (*SANSData->N_r) * sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_spin_flip, SANSData_gpu->c_Mag_spin_flip, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_chiral, SANSData_gpu->c_Mag_chiral, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_spin_flip_pm, SANSData_gpu->c_Mag_spin_flip_pm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_spin_flip_mp, SANSData_gpu->c_Mag_spin_flip_mp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_non_spin_flip_pp, SANSData_gpu->c_Mag_non_spin_flip_pp, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_non_spin_flip_mm, SANSData_gpu->c_Mag_non_spin_flip_mm, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_sanspol_p, SANSData_gpu->c_Mag_sanspol_p, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
    cudaMemcpy(SANSData->c_Mag_sanspol_m, SANSData_gpu->c_Mag_sanspol_m, (*SANSData->N_r) * sizeof(float),
               cudaMemcpyDeviceToHost);
}

void free_ScatteringData(ScatteringData* SANSData, ScatteringData* SANSData_gpu) {

    LogSystem::write("free SANSdata...");

    //  cudaError_t err;

    free(SANSData->Polarization);

    free(SANSData->N_q);
    free(SANSData->N_theta);
    free(SANSData->N_r);
    free(SANSData->N_alpha);

    free(SANSData->q_min);
    free(SANSData->q_max);
    free(SANSData->r_max);
    free(SANSData->dq);
    free(SANSData->dtheta);
    free(SANSData->dr);
    free(SANSData->dalpha);

    free(SANSData->qy_2D);
    free(SANSData->qz_2D);
    free(SANSData->q_2D);
    free(SANSData->theta_2D);

    free(SANSData->ry_2D);
    free(SANSData->rz_2D);
    free(SANSData->r_2D);
    free(SANSData->alpha_2D);

    free(SANSData->q_1D);
    free(SANSData->r_1D);

    free(SANSData->Gxx_real);
    free(SANSData->Gyy_real);
    free(SANSData->Gzz_real);
    free(SANSData->Gxy_real);
    free(SANSData->Gyx_real);
    free(SANSData->Gxz_real);
    free(SANSData->Gzx_real);
    free(SANSData->Gyz_real);
    free(SANSData->Gzy_real);

    free(SANSData->Gxx_imag);
    free(SANSData->Gyy_imag);
    free(SANSData->Gzz_imag);
    free(SANSData->Gxy_imag);
    free(SANSData->Gyx_imag);
    free(SANSData->Gxz_imag);
    free(SANSData->Gzx_imag);
    free(SANSData->Gyz_imag);
    free(SANSData->Gzy_imag);

    free(SANSData->S_Nuc_2D_unpolarized);
    free(SANSData->S_Mag_2D_unpolarized);
    free(SANSData->S_NucMag_2D);
    free(SANSData->S_Mag_2D_polarized);
    free(SANSData->S_Mag_2D_spin_flip);
    free(SANSData->S_Mag_2D_chiral);
    free(SANSData->S_Mag_2D_spin_flip_pm);
    free(SANSData->S_Mag_2D_spin_flip_mp);
    free(SANSData->S_Mag_2D_non_spin_flip_pp);
    free(SANSData->S_Mag_2D_non_spin_flip_mm);
    free(SANSData->S_Mag_2D_sanspol_p);
    free(SANSData->S_Mag_2D_sanspol_m);

    free(SANSData->Corr_Nuc_2D_unpolarized);
    free(SANSData->Corr_Mag_2D_unpolarized);
    free(SANSData->Corr_Mag_2D_polarized);
    free(SANSData->Corr_NucMag_2D);
    free(SANSData->Corr_Mag_2D_spin_flip);
    free(SANSData->Corr_Mag_2D_chiral);
    free(SANSData->Corr_Mag_2D_spin_flip_mp);
    free(SANSData->Corr_Mag_2D_spin_flip_pm);
    free(SANSData->Corr_Mag_2D_non_spin_flip_pp);
    free(SANSData->Corr_Mag_2D_non_spin_flip_mm);
    free(SANSData->Corr_Mag_2D_sanspol_p);
    free(SANSData->Corr_Mag_2D_sanspol_m);

    free(SANSData->S_Nuc_1D_unpolarized);
    free(SANSData->S_Mag_1D_unpolarized);
    free(SANSData->S_NucMag_1D);
    free(SANSData->S_Mag_1D_polarized);
    free(SANSData->S_Mag_1D_chiral);
    free(SANSData->S_Mag_1D_spin_flip);
    free(SANSData->S_Mag_1D_spin_flip_pm);
    free(SANSData->S_Mag_1D_spin_flip_mp);
    free(SANSData->S_Mag_1D_non_spin_flip_pp);
    free(SANSData->S_Mag_1D_non_spin_flip_mm);
    free(SANSData->S_Mag_1D_sanspol_p);
    free(SANSData->S_Mag_1D_sanspol_m);

    free(SANSData->p_Nuc_unpolarized);
    free(SANSData->p_Mag_unpolarized);
    free(SANSData->p_Mag_polarized);
    free(SANSData->p_NucMag);
    free(SANSData->p_Mag_chiral);
    free(SANSData->p_Mag_spin_flip);
    free(SANSData->p_Mag_spin_flip_pm);
    free(SANSData->p_Mag_spin_flip_mp);
    free(SANSData->p_Mag_non_spin_flip_pp);
    free(SANSData->p_Mag_non_spin_flip_mm);
    free(SANSData->p_Mag_sanspol_p);
    free(SANSData->p_Mag_sanspol_m);

    free(SANSData->c_Nuc_unpolarized);
    free(SANSData->c_Mag_unpolarized);
    free(SANSData->c_Mag_polarized);
    free(SANSData->c_NucMag);
    free(SANSData->c_Mag_chiral);
    free(SANSData->c_Mag_spin_flip);
    free(SANSData->c_Mag_spin_flip_pm);
    free(SANSData->c_Mag_spin_flip_mp);
    free(SANSData->c_Mag_non_spin_flip_pp);
    free(SANSData->c_Mag_non_spin_flip_mm);
    free(SANSData->c_Mag_sanspol_p);
    free(SANSData->c_Mag_sanspol_m);

    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Polarization);
    cudaFree(SANSData_gpu->N_q);
    cudaFree(SANSData_gpu->N_theta);
    cudaFree(SANSData_gpu->N_r);
    cudaFree(SANSData_gpu->N_alpha);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->q_min);
    cudaFree(SANSData_gpu->q_max);
    cudaFree(SANSData_gpu->r_max);
    cudaFree(SANSData_gpu->dq);
    cudaFree(SANSData_gpu->dtheta);
    cudaFree(SANSData_gpu->dr);
    cudaFree(SANSData_gpu->dalpha);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->qy_2D);
    cudaFree(SANSData_gpu->qz_2D);
    cudaFree(SANSData_gpu->q_2D);
    cudaFree(SANSData_gpu->theta_2D);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->ry_2D);
    cudaFree(SANSData_gpu->rz_2D);
    cudaFree(SANSData_gpu->r_2D);
    cudaFree(SANSData_gpu->alpha_2D);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->q_1D);
    cudaFree(SANSData_gpu->r_1D);
    cudaDeviceSynchronize();

    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gxx_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyy_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzz_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gxy_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyx_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gxz_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzx_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyz_real);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzy_real);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->Gxx_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyy_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzz_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gxy_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyx_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gxz_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzx_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gyz_imag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Gzy_imag);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->S_Nuc_2D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_NucMag_2D);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_polarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_spin_flip);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_chiral);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_spin_flip_pm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_spin_flip_mp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_non_spin_flip_pp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_non_spin_flip_mm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_sanspol_p);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_2D_sanspol_m);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->Corr_Nuc_2D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_polarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_NucMag_2D);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_spin_flip);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_chiral);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_spin_flip_mp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_spin_flip_pm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_non_spin_flip_pp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_non_spin_flip_mm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_sanspol_p);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->Corr_Mag_2D_sanspol_m);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->S_Nuc_1D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_NucMag_1D);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_polarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_chiral);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_spin_flip);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_spin_flip_pm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_spin_flip_mp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_non_spin_flip_pp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_non_spin_flip_mm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_sanspol_p);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->S_Mag_1D_sanspol_m);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->p_Nuc_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_polarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_NucMag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_chiral);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_spin_flip);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_spin_flip_pm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_spin_flip_mp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_non_spin_flip_pp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_non_spin_flip_mm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_sanspol_p);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->p_Mag_sanspol_m);
    cudaDeviceSynchronize();

    cudaFree(SANSData_gpu->c_Nuc_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_unpolarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_polarized);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_NucMag);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_chiral);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_spin_flip);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_spin_flip_pm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_spin_flip_mp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_non_spin_flip_pp);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_non_spin_flip_mm);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_sanspol_p);
    cudaDeviceSynchronize();
    cudaFree(SANSData_gpu->c_Mag_sanspol_m);
    cudaDeviceSynchronize();

    LogSystem::write("free SANSdata finished.");
}