#ifdef _MSC_VER //If the compiler is the Visual Studio Compiler #define NOMINMAX //solves a problem with std::max on Windows #pragma warning(disable: 4297) //remove throw warnings #endif #include "common/definitions.h" #include #include #include "common/SpinSystem.h" const bool debug = false; const char* get_version() { return SPINTRUM_VERSION; } void print_software_info() { std::cout<<"Spintrum version "<,VEC,CX_VEC,MAT,CX_MAT> SpinSystemType; struct SpinInfo { CX_MAT jCouplings; CX_VEC gammas; G_MAT multiplicities; }; void devectorizeJCouplings(const long numOfSpins, const double* const jCouplingsInput, CX_MAT& jCouplingsOutput) { if(jCouplingsInput == 0) { jCouplingsOutput.resize(0,0); return; } int i = 0; //element of given array int j = 0; //element of current row int row = 0; while (i < numOfSpins*(numOfSpins-1)/2) { if(j <= row) { j++; continue; } if(j >= numOfSpins) { j = 0; row++; continue; } jCouplingsOutput.at(row,j) = jCouplingsInput[i]; j++; i++; } } extern "C" int InitializeSimulator(double* gammas, double* jCouplings, int* spinMultiplicities, int numOfSpins, bool doPrintOutput, void** SpinSystemObject) { try { print_software_info(); // std::cout<<"Number of spins: "<,VEC,CX_VEC,MAT,CX_MAT>(); Spins->print = doPrintOutput; Spins->init(spinInfo.gammas,spinInfo.jCouplings,spinInfo.multiplicities); *SpinSystemObject = static_cast(Spins); return 0; } catch(std::exception &ex) { std::cout<<"An exception was thrown while trying to initialize the spin system. Exception message is: " << ex.what() << std::endl; return -1; } catch(...) { std::cout<<"An unhandled exception was thrown while trying to initialize the spin system."<< std::endl; return -2; } } extern "C" int DenitializeSimulator(void* SpinSystemObject) { try { delete (static_cast(SpinSystemObject)); return 0; } catch(std::exception &ex) { std::cout<<"An exception was thrown while trying to delete the spin system from memory. Exception message is: " << ex.what() << std::endl; return -1; } catch(...) { std::cout<<"An unhandled exception was thrown while trying to delete the spin system from memory."<< std::endl; return -2; } } extern "C" int SetGammasInSimulator(double* gammas, void* SpinSystemObject) { try { CX_VEC gammasVec((static_cast(SpinSystemObject))->getNumOfSpins(),1); for(int i = 0; i < gammasVec.size(); i++) { gammasVec[i] = gammas[i]; } (static_cast(SpinSystemObject))->setGammas(gammasVec); return 0; } catch(std::exception &ex) { std::cout<<"An exception was thrown while trying to delete the spin system from memory. Exception message is: " << ex.what() << std::endl; return -1; } catch(...) { std::cout<<"An unhandled exception was thrown while trying to delete the spin system from memory."<< std::endl; return -2; } } extern "C" int SetJCouplingsInSimulator(double* jCouplings, void* SpinSystemObject) { try { CX_MAT jCouplingsMat((static_cast(SpinSystemObject))->getNumOfSpins(),(static_cast(SpinSystemObject))->getNumOfSpins()); devectorizeJCouplings((static_cast(SpinSystemObject))->getNumOfSpins(), jCouplings, jCouplingsMat); (static_cast(SpinSystemObject))->setJCouplings(jCouplingsMat); return 0; } catch(std::exception &ex) { std::cout<<"An exception was thrown while trying to delete the spin system from memory. Exception message is: " << ex.what() << std::endl; return -1; } catch(...) { std::cout<<"An unhandled exception was thrown while trying to delete the spin system from memory."<< std::endl; return -2; } } void _do_operation_evolve_time_dependent(SpinOperation* op, SpinSystemType* SpinsPtr, double* outputArray, long ¤tDataPoint) { if(debug) std::cout<<"Printing received data:"<Params_array_count == 0) { throw std::runtime_error("There's no data provided for the time-dependent evolution."); } else { //make sure that all lengths are equal long initialLength = op->Params_array_lengths[0]; for(long i = 1; i < op->Params_array_count; i++) { if(op->Params_array_lengths[i] != initialLength) { throw std::length_error("Data arrays in time-dependent evolution are expected all to be of the same length."); } } } std::vector varsNames(static_cast::size_type>(op->Params_array_count)); std::copy(op->Params_array_names,op->Params_array_names+op->Params_array_count,varsNames.begin()); //copy names to vector CX_MAT evData(op->Params_array_lengths[0],op->Params_array_count); for(long i = 0; i < op->Params_array_count; i++) { std::copy(&op->Params_array[i][0],&op->Params_array[i][op->Params_array_lengths[i]],evData.begin()+evData.rows()*i); } std::set dirString; if(op->Params_int[1]) dirString.insert('x'); if(op->Params_int[2]) dirString.insert('y'); if(op->Params_int[3]) dirString.insert('z'); std::vector tr = SpinsPtr->evolveDensityMatrix(op->Params_real[0],varsNames,evData,static_cast(op->Params_int[0]),dirString); std::copy(std::make_move_iterator(tr.begin()), std::make_move_iterator(tr.end()), outputArray + currentDataPoint); currentDataPoint += op->Params_array_lengths[0]*static_cast(dirString.size()); } long ExecuteOperations(void* SpinSystemObject, void** ops, int numOfOperations, double* output, bool debug) { if(debug) { std::cout<<"Number of operations: "<(SpinSystemObject); long currentDataPoint = 0; //for a simulation with many operations that consecutively fill the output, this keeps track of the current point for(int i = 0; i < numOfOperations; i++) { void** currOperationBytePosition = (static_cast(ops)); long OperationIdentifier = *(static_cast(currOperationBytePosition[i])); if(debug) std::cout<<"Identifier: "<(currOperationBytePosition[i]); SpinsPtr->populate_thermal(op->Params_real[0],op->Params_real[1],op->Params_real[2],op->Params_real[3]); } else if (OperationIdentifier == OPERATION__TIP_SPINS) { SpinOperation* op; op = static_cast(currOperationBytePosition[i]); SpinsPtr->tipSpins(static_cast(op->Params_int[0]),op->Params_real[0]); } else if (OperationIdentifier == OPERATION__SET_HAMILTONIAN) { SpinOperation* op; op = static_cast(currOperationBytePosition[i]); SpinsPtr->calculateHamiltonians(op->Params_real[0],op->Params_real[1],op->Params_real[2]); } else if (OperationIdentifier == OPERATION__EVOLVE_TIME_INDEPENDENT) { SpinOperation* op; op = static_cast(currOperationBytePosition[i]); std::vector trVals = SpinsPtr->solveMagnetization_parallel(op->Params_int[0],static_cast(op->Params_int[1])); std::copy(trVals.begin(), trVals.end(), output + currentDataPoint); currentDataPoint += op->Params_int[0]; } else if (OperationIdentifier == OPERATION__INIT_TIME_INDEPENDENT_EVOLUTION) { SpinOperation* op; op = static_cast(currOperationBytePosition[i]); SpinsPtr->initTimeIndependentEvolution(op->Params_real[0],static_cast(op->Params_int[0])); } else if (OperationIdentifier == OPERATION__EVOLVE_TIME_DEPENDENT) { _do_operation_evolve_time_dependent(static_cast(currOperationBytePosition[i]), SpinsPtr, output, currentDataPoint); } else { std::cout << "Error: An unknown operation was requested... Exiting." << std::endl; exit(1); } } return currentDataPoint; } extern "C" long CreateSignalFromInitializedSimulator(void* SpinSystemObject, void** ops, int numOfOperations, long numOfPoints, double* output) { try { if(debug) { std::cout<<"Number of operations: "<,VEC,CX_VEC,MAT,CX_MAT > Spins(spinInfo.gammas,spinInfo.jCouplings,spinInfo.multiplicities); long processedNumOfPoints = ExecuteOperations(static_cast(&Spins),ops,numOfOperations,output,debug); if (debug) std::cout<