Program Listing for File NuMagSANSlib.h#
↰ Return to documentation for file (src/NuMagSANSlib.h)
// File : NuMagSANSlib.h
// Author : Dr. Michael Philipp ADAMS
// Company : University of Luxembourg
// Department : Department of Physics and Materials Sciences
// Group : NanoMagnetism Group
// Group Leader : Prof. Andreas Michels
// Version : 29 October 2025
// 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>
//#pragma once
#include "NuMagSANSlib_LogFile.h"
#include "NuMagSANSlib_HelperFun.h"
#include "NuMagSANSlib_StringCompare.h"
#include "NuMagSANSlib_ReadWrite.h"
#include "NuMagSANSlib_Directory.h"
#include "NuMagSANSlib_InputFileInterpreter.h"
#include "NuMagSANSlib_MagDataExplorer.h"
#include "NuMagSANSlib_NucDataExplorer.h"
#include "NuMagSANSlib_StructureDataExplorer.h"
#include "NuMagSANSlib_MagData.h"
#include "NuMagSANSlib_NucData.h"
#include "NuMagSANSlib_StructureData.h"
#include "NuMagSANSlib_SANSData.h"
#include "NuMagSANSlib_SpectralData.h"
#include "NuMagSANSlib_gpuKernel.h"
using namespace std;
void NuMagSANS_Calculator(InputFileData* InputData, \
NucDataProperties* NucDataProp,\
MagDataProperties* MagDataProp,\
StructDataProperties* StructDataProp, \
int Data_File_Index){
cudaError_t err;
LogSystem::write("################################################################################");
LogSystem::write("## Run - NuMagSANS #############################################################");
LogSystem::write("################################################################################");
LogSystem::write("");
// start time measurement #################################################################
auto start_total_time = std::chrono::high_resolution_clock::now();
// initialize nuclear data ################################################################
NuclearData NucData, NucData_gpu;
if(InputData->NucData_activate_flag){
init_NuclearData(&NucData, &NucData_gpu, NucDataProp, InputData, Data_File_Index);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// initialize magnetization data ##########################################################
MagnetizationData MagData, MagData_gpu;
if(InputData->MagData_activate_flag){
init_MagnetizationData(&MagData, &MagData_gpu, MagDataProp, InputData, Data_File_Index);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
//disp_MagnetizationData(&MagData);
}
// initialize structure data ##############################################################
StructureData StructData, StructData_gpu;
if(InputData->StructData_activate_flag){
init_StructureData(&StructData, &StructData_gpu, StructDataProp, InputData);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
//disp_StructureData(&StructData);
}
// initialize scattering data #############################################################
ScatteringData SANSData, SANSData_gpu;
init_ScatteringData(InputData, &SANSData, &SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
// initialize spectral data ##############################################################
SpectralData SpecData, SpecData_gpu;
init_SpectralData(InputData, &SANSData, &SpecData, &SpecData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
// initialize scaling factors #############################################################
ScalingFactors ScalFactors;
init_ScalingFactors(&ScalFactors, InputData, &MagData, &NucData, &SANSData);
// compute 2D SANS cross sections #########################################################
int L = (*SANSData.N_q) * (*SANSData.N_theta);
LogSystem::write("total number of Fourier space bins: " + std::to_string(L));
// Pure Magnetic Scattering Calculator without structure data #####################################################################
if(InputData->MagData_activate_flag == 1 && InputData->NucData_activate_flag == 0 && InputData->StructData_activate_flag == 0){
LogSystem::write("run: Atomistic_MagSANS_Kernel_dilute");
Atomistic_MagSANS_Kernel_dilute<<<(L+255)/256, 256>>>(MagData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// Pure Nuclear Scattering Calculator without structure data #######################################################################
if(InputData->MagData_activate_flag == 0 && InputData->NucData_activate_flag == 1 && InputData->StructData_activate_flag == 0){
LogSystem::write("run: Atomistic_NucSANS_Kernel_dilute");
Atomistic_NucSANS_Kernel_dilute<<<(L+255)/256, 256>>>(NucData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// Combined Magnetic and Nuclear Scattering Calculator without structure data ######################################################
if(InputData->MagData_activate_flag == 1 && InputData->NucData_activate_flag == 1 && InputData->StructData_activate_flag == 0){
LogSystem::write("run: Atomistic_NuMagSANS_Kernel_dilute");
Atomistic_NuMagSANS_Kernel_dilute<<<(L+255)/256, 256>>>(NucData_gpu, MagData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// Pure Magnetic Scattering Calculator with structure data #########################################################################
if(InputData->MagData_activate_flag == 1 && InputData->NucData_activate_flag == 0 && InputData->StructData_activate_flag == 1){
LogSystem::write("run: Atomistic_MagSANS_Kernel");
Atomistic_MagSANS_Kernel<<<(L+255)/256, 256>>>(MagData_gpu, StructData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// Pure Nuclear Scattering Calculator with structure data ###########################################################################
if(InputData->MagData_activate_flag == 0 && InputData->NucData_activate_flag == 1 && InputData->StructData_activate_flag == 1){
LogSystem::write("run: Atomistic_NucSANS_Kernel");
Atomistic_NucSANS_Kernel<<<(L+255)/256, 256>>>(NucData_gpu, StructData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// Combined Magnetic and Nuclear Scattering Calculator with structure data #########################################################
if(InputData->MagData_activate_flag == 1 && InputData->NucData_activate_flag == 1 && InputData->StructData_activate_flag == 1){
LogSystem::write("run: Atomistic_NuMagSANS_Kernel");
Atomistic_NuMagSANS_Kernel<<<(L+255)/256, 256>>>(NucData_gpu, MagData_gpu, StructData_gpu, SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// compute azimuthal average 1D ###########################################################
bool compute_1D_azimuthal_average = any_active(InputData->OutFlags.SANS1D);
bool compute_1D_corr = any_active(InputData->OutFlags.Corr1D);
bool compute_1D_pair = any_active(InputData->OutFlags.PairDist1D);
if(compute_1D_azimuthal_average || compute_1D_corr || compute_1D_pair){
LogSystem::write("run: azimuthal averaging");
AzimuthalAverage<<<(L+255)/256, 256>>>(SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// compute 1D pair distance distribution and correlation function #########################
if(compute_1D_corr || compute_1D_pair){
LogSystem::write("run: 1D correlation functions");
DistributionFunctions<<<(L+255), 256>>>(SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// compute 2D correlation functions ######################################################
bool compute_2D_correlation = any_active(InputData->OutFlags.Corr2D);
if(compute_2D_correlation){
LogSystem::write("run: 2D correlation functions");
CorrelationFunction_2D<<<(L+255)/256, 256>>>(SANSData_gpu);
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// compute angular spectral intensities ###################################################
if(InputData->AngularSpec_activate_flag){
LogSystem::write("run: angular spectrum analyzer");
ComputeSpectralDecomposition<<<(L+255)/256, 256>>>(SANSData_gpu, SpecData_gpu);
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
// compute angular spectral amplitudes ####################################################
LogSystem::write("run: angular amplitude spectrum analyzer");
ComputeAngularSpectrumAmplitudes<<<(L+255)/256, 256>>>(SpecData_gpu);
err = cudaGetLastError();
if (err != cudaSuccess) {
LogSystem::write(std::string("kernel launch failed: ") + cudaGetErrorString(err));
}
}
// copy scattering data from GPU to RAM ###################################################
copyGPU2RAM_ScatteringData(&SANSData, &SANSData_gpu);
// scaling of the scattering data on RAM ##################################################
LogSystem::write("scaling of SANSdata...");
scale_ScatteringData(&ScalFactors, &SANSData, InputData);
// write scattering data to csv files #####################################################
write2CSVtable_ScatteringData(InputData, &SANSData, Data_File_Index);
if(InputData->AngularSpec_activate_flag){
// copy spectral data from GPU to RAM #####################################################
copyGPU2RAM_SpectralData(&SpecData, &SpecData_gpu);
// scaling of the spectral data on RAM ####################################################
scale_SpectralData(&ScalFactors, &SpecData, InputData);
// write spectral data to csv files #######################################################
write2CSV_SpectralData(InputData, &SpecData, Data_File_Index);
}
// free memory ############################################################################
LogSystem::write("free memory...");
if(InputData->NucData_activate_flag){
free_NuclearData(&NucData, &NucData_gpu);
}
if(InputData->MagData_activate_flag){
free_MagnetizationData(&MagData, &MagData_gpu);
}
if(InputData->StructData_activate_flag){
free_StructureData(&StructData, &StructData_gpu);
}
// free scattering data
free_ScatteringData(&SANSData, &SANSData_gpu);
// free spectral data
free_SpectralData(&SpecData, &SpecData_gpu);
// print result of time measurement #######################################################
LogSystem::write("");
auto finish_total_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_total_time = finish_total_time - start_total_time;
LogSystem::write("->-> Total Elapsed Time: " + std::to_string(elapsed_total_time.count()) + " s");
LogSystem::write("");
LogSystem::write("################################################################################");
LogSystem::write("## Finished - NuMagSANS ########################################################");
LogSystem::write("################################################################################");
LogSystem::write("");
LogSystem::write("");
}