Running AM³ with the native C++
AM³ is natively written in C++, and can be compiled and run without using the Python interface. The Python interface does not compromise on performance or flexibility, because it simply maps into Python the underlying C++ functions. To users who do not intend to customize AM³, we therefore recommend utilizing the Python interface, which is more flexible, easier to use, and does not require compilation on a project-by-project basis.
When working with C++ it is necessary to first compile the AM³ C++ library, and then your project, by using a Makefile or CMake script. You then write a C++ script with your source simulation, accompanied by a Makefile or CMake script with instructions to link the AM³ library and compile your code. We provide an example in docs/examples/cplusplus.
C++ script example
In your C++ script, make sure to first include all AM³ header files. The class subjects should be declared according to C++ syntax. You can then set up the solver, define the physical parameters, run the simulation, and print the results to an output file:
#include "AM3/AM3Arrays.h"
#include "AM3/HadronicSynchrotron.h"
#include "AM3/PairProduction.h"
#include "AM3/Acceleration.h"
#include "AM3/AM3.h"
#include "AM3/PhysicsHandler.h"
#include "AM3/Synchrotron.h"
#include "AM3/BetheHeitler.h"
#include "AM3/Injection.h"
#include "AM3/PionDecay.h"
#include "AM3/consts.h"
#include "AM3/Escape.h"
#include "AM3/InverseCompton.h"
#include "AM3/RunParams.h"
#include "AM3/global_defs.h"
#include "AM3/Expansion.h"
#include "AM3/MuonDecay.h"
#include "AM3/SimulationManager.h"
#include "AM3/math.h"
#include "AM3/HadronicInverseCompton.h"
#include "AM3/PhotoPion.h"
#include "AM3/ProtonProton.h"
#include "AM3/Solver.h"
#include <iostream>
using namespace std;
int main()
{
// refer to https://am3.readthedocs.io/en/latest/examples/blazar_detailed_example.html# for a detailed description of the functions
AM3 am3;
am3.set_estimate_max_energies(0);
am3.set_process_parse_sed(1);
am3.set_process_hadronic(1);
am3.set_process_merge_positrons_into_electrons(0);
am3.set_process_escape(1);
am3.set_process_expansion(0);
am3.set_process_adiabatic_cooling(1);
am3.set_process_electron_syn(1);
am3.set_process_ssa(1);
am3.set_process_proton_syn(1);
am3.set_process_quantum_syn(0);
am3.set_process_electron_compton(1);
am3.set_process_proton_compton(1);
am3.set_process_compton_photon_energy_loss(0);
am3.set_process_muon_syn(0);
am3.set_process_pion_syn(0);
am3.set_process_muon_compton(0);
am3.set_process_pion_compton(0);
am3.set_process_pion_decay(1);
am3.set_process_muon_decay(1);
am3.set_process_annihilation(1);
am3.set_optimize_annihilation_pair_emission(1);
am3.set_process_bethe_heitler(1);
am3.set_optimize_bethe_heitler_outgoing_pairs_grid(1);
am3.set_optimize_bethe_heitler_incoming_protons_min(1e12);
am3.set_optimize_bethe_heitler_target_photon_max(1e6);
am3.set_process_photopion(1);
am3.set_optimize_photopion_target_photon_grid(1);
am3.set_optimize_photopion_target_photon_max(1e6);
am3.init_kernels();
am3.set_mag_field(1.0);
am3.set_escape_timescale(1e17 / 3e10);
am3.set_solver_time_step(1e-1 * am3.get_escape_timescale());
double volume = 4 * 3.14 / 3 * pow(1e17,3);
double elec_emin = 1e8;
double elec_emax = 1e11;
double eindex = 2.02;
double elum = 1.84e+41;
double proton_emin = 1e10;
double proton_emax = 1e17;
double pindex = 1.0;
double plum = 6.29e+43;
cout<<"Set particle injections"<<endl;
am3.clear_particle_densities();
am3.set_powerlaw_injection_parameters_electrons(volume, elum, elec_emin, elec_emin, elec_emax, eindex, eindex, 1.0);
am3.set_powerlaw_injection_parameters_protons(volume, plum, proton_emin, proton_emin, proton_emax, pindex, pindex, 1.0);
double time = 0;
am3.evolve_step();
time += am3.get_solver_time_step();
return 0;
}
Compiling the AM³ C++ library
To compile your AM³ C++ library, you can use a CMake script like the one we provide in the AM³ root directory.
Make sure to install cmake, as well as the required Eigen and GSL libraries:
$ apt update && apt install -y g++ cmake libeigen3-dev libgsl-dev
Then navigate to your AM³ root directory and run
$ cmake -S . -B build -DPYTHON=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=~/.local/am3
$ cmake --build build -- -j 2
$ cmake --install build
The AM³ C++ library should now be installed.
Compiling your C++ project
Finally, to compile and run your C++ simulation, you need a script like the one above, and a Cmake script to link it to the pre-compiled AM³ library. Place both in the same directory (we provide an example of a CMake script in docs/examples/cplusplus), navigate to that directory, and run
$ CMAKE_PREFIX_PATH=~/.local/am3 cmake -S . -B build
$ cmake --build build
The first command writes a build/Makefile, and the second command runs the makefile and compiles your executable, in this case build/TestAM3withCpp. You can then run your project with
$ ./build/TestAM3withCpp