-
Notifications
You must be signed in to change notification settings - Fork 15
Bindings: Fortran
Through a combination of Rust-C/C++ interop and Fortran-C/C++ interop, the RustBCA library can be called from Fortran.
This requires functions to be handled a little differently, so specific functions for Fortran-Rust coupling have been written, and a Fortran wrapper rustbca.f90
is included with appropriate interface statements so that RustBCA library functions can be called relatively simply from Fortran codes.
test_rustbca.f90
is located in the examples
directory. It can be built and tested with the following series of commands:
#Build the library
cargo build --release --lib
#copy test source file to main directory.
cp examples/test_rustbca.f90 .
#Build the RustBCA Fortran wrappers
gfortran -c rustbca.f90 target/release/liblibRustBCA.so
#Build test_rustbca
gfortran test_rustbca.f90 target/release/liblibRustBCA.so
./a.out
The code should output:
Elapsed time in seconds per ion per eV: 8.08222978E-07
Elapsed time in ions per eV per s: 8.22675304E-07
With timing dependent on your specific machine.
The reflect_single_ion
routine takes an incident ion and runs that ion through a single BCA trajectory in a flat, homogeneous, compound target with no recoils (which means no sputtered atoms). The energy and direction of the incident ion are passed by reference and modified in place.
-
num_species_target
(integer(c_int)): number of species in target -
ux
(real(c_double)): x-direction - modified in place after run is complete to new direction -
uy
(real(c_double)): y-direction - modified in place after run is complete to new direction -
uz
(real(c_double)): z-direction - modified in place after run is complete to new direction -
E1
(real(c_double)): Energy (eV) - modified in place after run is complete to new energy; if E = 0, ion was implanted in target, not reflected -
Z1
(real(c_double)): atomic number of incident ion -
m1
(real(c_double)): atomic mass of incident ion (amu) -
Ec1
(real(c_double)): cutoff energy of incident ion (eV) -
Es1
(real(c_double)): surface binding energy of incident ion (eV) -
Z2
(real(c_double), dimension(:)): atomic numbers of target species -
m2
(real(c_double), dimension(:)): atomic masses of target species (amu) -
Ec2
(real(c_double), dimension(:)): cutoff energies of target species (eV) -
Es2
(real(c_double), dimension(:)): surface binding energies of target species (eV) -
Eb2
(real(c_double), dimension(:)): bulk binding energies of target species (eV) -
n2
(real(c_double), dimension(:)): number densities of target species (1/A^3)
The compound_bca_list_fortran
function gives nearly complete access to a homogeneous, flat target BCA simulation with two lines of code. First, the function is called. Note that, in order to overcome a lack of easily sharing structs between Fortran and C, and additionally the inability for functions to output multiple objects in both Fortran and Rust, this function does mutate a single argument as part of the output - the number of emitted particles after the simulation. Note also that the function returns a C pointer - the second line of code is used to convert the C pointer to the output data to a Fortran pointer (which contains size and shape information, so that the resulting Fortran pointer can be accessed like a normal Fortran array).
-
N_ions
(integer(c_int)): number of incident ions -
track_recoils
(logical(c_bool)): whether to generate recoils or not - turn off to disable sputtering -
ux, uy, uz
(real(c_double), dimension(:)): ion direction unit vector -
E1
(real(c_double), dimension(:)): ion energy (eV) -
Z1
(real(c_double), dimension(:)): ion atomic numbers -
m1
(real(c_double), dimension(:)): ion masses (amu) -
Ec1
(real(c_double), dimension(:)): ion cutoff energies (eV) -
Es1
(real(c_double), dimension(:)): ion surface binding energies (eV) -
num_species_target
(integer(c_int)): number of target species -
Z2
(real(c_double), dimension(:)): target atomic numbers -
m2
(real(c_double), dimension(:)): target masses (amu) -
Ec2
(real(c_double), dimension(:)): target cutoff energies (eV) -
Es2
(real(c_double), dimension(:)): target surface binding energies (eV) -
Eb2
(real(c_double), dimension(:)): target bulk binding energies (eV) -
n2
(real(c_double), dimension(:)): target number densities (1/Angstrom^3) -
num_emitted_particles
(integer(c_int)): NOTE: OUTPUT number of emitted particles
- bca_output (real(c_double), dimension(:,6)): Z, m (amu), E (eV), ux, uy, uz
!rustbca.f90 includes interface statements that allow Rust/Fortran interop via C/C++ FFI
use rustbca
use, intrinsic :: iso_binding_c
...
bca_output_c = compound_bca_list_fortran(N_ions, track_recoils, ux, uy, uz, E, &
Z1, m1, Ec1, Es1, &
num_species_target, Z2, m2, Ec2, Es2, Eb2, n2, &
num_emitted_particles)
!Convert the C pointer (which has been forgotten by the Rust library) to a Fortran pointer
call c_f_pointer(bca_output_c, bca_output_f, [num_emitted_particles, 6])