1
0
Fork 0
mirror of https://github.com/gwm17/catima.git synced 2024-11-26 20:18:51 -05:00
catima/structures.h

306 lines
9.0 KiB
C
Raw Normal View History

2017-07-25 12:19:11 -04:00
/*
* Author: Andrej Prochazka
* Copyright(C) 2017
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STRUCTURES_H
#define STRUCTURES_H
#include <vector>
#include <array>
#include <initializer_list>
2018-05-01 20:18:50 -04:00
#include "catima/constants.h"
2017-07-25 12:19:11 -04:00
namespace catima{
/**
* Projectile class
* Example usage:
* \code{.cpp}
* Projectile p(12,6);
* p.T = 1000; // setting energy to 1000 MeV/u
* p(1000); // setting energy to 1000 MeV/u
* \endcode
*/
struct Projectile{
double A=0;
double Z=0;
double Q=0;
double T=0;
2019-10-22 14:59:21 -04:00
/// constructor
/// @param a - mass
/// @param z - proton number
/// @param q - charge state
/// @param t - energy in MeV/u
2017-07-25 12:19:11 -04:00
Projectile(double a, double z, double q=0, double t=0):A(a),Z(z),Q(q),T(t){if(q==0)Q=Z;}
2019-10-22 14:59:21 -04:00
Projectile& operator()(double e){T=e;return *this;}
Projectile() = default;
2017-07-25 12:19:11 -04:00
};
bool operator==(const Projectile &a, const Projectile&b);
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
/**
* Target class is used to store constituents of the Material class
* its just to hold A,Z data for individual atoms.
*/
struct Target{
double A=0;
int Z=0;
2017-12-14 09:29:23 -05:00
double stn=1.0;
2017-07-25 12:19:11 -04:00
};
/**
* Material
* class to store Material information
2019-10-22 13:50:34 -04:00
* This class defines the material with which projectile will interact.
2017-07-25 12:19:11 -04:00
* The class store nuclei constituents, density, thickness etc.
*/
class Material{
private:
2020-08-05 12:20:16 -04:00
double rho=1e-5;
2017-07-25 12:19:11 -04:00
double th=0;
double molar_mass=0;
2018-01-29 07:38:54 -05:00
double i_potential=0;
2017-07-25 12:19:11 -04:00
std::vector<Target>atoms;
public:
Material(){};
/**
* constructor to add 1 element into the Material, stn number of the element is set to 1.0
* @param _a - mass number of the atom, is 0 the atomic weight of element _z is taken
* @param _z - proton number of the atom
* @param _rho - density of the material in g/cm3, default 0.0
* @param _th - thickness of the material in g/cm2, default 0.0
*/
2020-08-05 12:20:16 -04:00
Material(double _a, int _z, double _rho=1e-5, double _th=0.0, double _ipot = 0.0);
2017-07-25 12:19:11 -04:00
/**
* constructor to add 1 or multiple element into the Material
* \code{.cpp}
* Maetrial water({
2019-10-22 14:59:21 -04:00
* {1,1,2},
* {16,8,1},
* 1.0, // optional density
* });
2017-07-25 12:19:11 -04:00
* \endcode
*/
2020-08-05 12:20:16 -04:00
Material(std::initializer_list<std::array<double,3>>list,double _density=1e-5, double ipot = 0.0, double mass=0.0);
2019-10-22 13:50:34 -04:00
2017-12-14 09:29:23 -05:00
/**
* calculates internal variables if needed
*/
2017-07-25 12:19:11 -04:00
void calculate();
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
/**
2019-10-22 13:50:34 -04:00
* add atom with mass number _a and proton number _z to the Material
2017-07-25 12:19:11 -04:00
* @param _a - mass number of the atom, is 0 the atomic weight of element _z is taken
* @param _z - proton number of the atom
* @param _stn - stoichiomatric number
*/
void add_element(double _a, int _z, double _stn);
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
/**
* returns i-th element of the Material as a std::pair of Target and corresponding stoichiometric number
* @param i - index of element to return
2017-12-14 09:29:23 -05:00
* @return Target class
*/
Target get_element(int i) const {return atoms[i];};
/**
* return weight fraction of i-th element
* @return weight fraction
2017-07-25 12:19:11 -04:00
*/
2017-12-14 09:29:23 -05:00
double weight_fraction(int i) const {return (atoms[i].stn<1.0)?atoms[i].stn:atoms[i].stn*atoms[i].A/M();};
2017-07-25 12:19:11 -04:00
2018-01-29 12:54:24 -05:00
/**
* return molar fraction of i-th element
* @return molar fraction
*/
double molar_fraction(int i) const {return (atoms[i].stn<1.0)?atoms[i].stn*M()/atoms[i].A:atoms[i].stn;};
2017-07-25 12:19:11 -04:00
/**
* @return number of components in Material
*/
2017-12-14 09:29:23 -05:00
int ncomponents() const {return atoms.size();}
2017-07-25 12:19:11 -04:00
/**
* @return returns Molar Mass of the Material
*/
double M() const {return molar_mass;}
2018-05-01 20:18:50 -04:00
/**
* sets molar mass of the Material
*/
Material& M(double mass){molar_mass=mass; return *this;}
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
/**
* @return returns density in g/cm^3
*/
double density() const {return rho;};
/**
* sets density in g/cm^3
*/
Material& density(double val){rho = val;return *this;};
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
/**
* @return returns thickness in g/cm^2
*/
double thickness() const {return th;};
2020-07-29 19:37:20 -04:00
/**
* @return returns thickness in cm
*/
double thickness_cm() const {return th/rho;};
2017-07-25 12:19:11 -04:00
/**
* sets thickness in g/cm^2
*/
Material& thickness(double val){th = val;return *this;};
2018-05-01 20:18:50 -04:00
/**
* set length in cm, density should be set before
*/
Material& thickness_cm(double l){th = rho*l; return *this;}
2018-01-29 07:38:54 -05:00
/**
* set the mean ionization potential, if non elemental I should be used
*/
Material& I(double val){i_potential = val;return *this;};
2019-10-22 13:50:34 -04:00
2018-01-29 07:38:54 -05:00
/**
* 0 if default elemental potential is used
* @return returns ionisation potential in ev
*/
double I() const {return i_potential;};
2018-05-01 20:18:50 -04:00
/**
* return number density of atoms/molecules per cm3 in 10^23 units
*/
double number_density()const{
return Avogadro*rho/molar_mass;
}
/**
* return number density of atoms of i-th element in 10^23 units
*/
double number_density(int i)const{
2019-10-22 13:50:34 -04:00
if(i>=atoms.size())return 0.0;
2018-05-01 20:18:50 -04:00
return number_density()*molar_fraction(i);
}
/**
* return number density of atoms/molecules per cm2 in 10^23 units
*/
double number_density_cm2()const{
return Avogadro*th/molar_mass;
}
/**
* return number density of atoms per cm2 of i-th element in 10^23 units
*/
double number_density_cm2(int i)const{
if(i>=atoms.size())return 0.0;
return number_density_cm2()*molar_fraction(i);
}
2017-07-25 12:19:11 -04:00
friend bool operator==(const Material &a, const Material&b);
};
bool operator==(const Material &a, const Material&b);
/**
* structure to store results for calculation per Material
*/
struct Result{
double Ein=0.0;
double Eout=0.0;
double Eloss = 0.0;
double range=0.0;
double dEdxi=0.0;
double dEdxo=0.0;
double sigma_E=0.0;
double sigma_a=0.0;
double sigma_r=0.0;
2020-07-29 19:37:20 -04:00
double sigma_x=0.0;
2020-08-04 11:35:33 -04:00
double cov = 0.0;
2019-10-22 13:50:34 -04:00
double tof=0.0;
2018-07-31 11:40:25 -04:00
#ifdef REACTIONS
2018-07-30 19:41:44 -04:00
double sp = 1.0;
#endif
2017-07-25 12:19:11 -04:00
};
/**
2019-10-22 13:50:34 -04:00
* structure to store results for calculation for multiple layers of materials, ie in catima::Layers
2017-07-25 12:19:11 -04:00
*/
struct MultiResult{
std::vector<Result> results;
Result total_result;
};
/**
* Layers
* class to store multiple material layers
*/
2019-10-22 13:50:34 -04:00
class Layers{
2017-07-25 12:19:11 -04:00
private:
std::vector<Material> materials;
public:
2019-10-22 13:50:34 -04:00
Layers() = default;
2017-07-25 12:19:11 -04:00
/**
* @return reference to the std::vector of stored Materials
*/
const std::vector<Material>& get_materials()const{return materials;}
/**
* add Material m to the Layers
2019-10-22 13:50:34 -04:00
* @param m Material
2017-07-25 12:19:11 -04:00
*/
void add(Material m);
2020-08-06 09:47:39 -04:00
/**
* append Layers
* @para, l Layers
*/
void add(const Layers& l);
2017-07-25 12:19:11 -04:00
/**
* @return number of stored Materials
*/
int num()const{return materials.size();};
2019-10-22 13:50:34 -04:00
2020-08-03 19:44:00 -04:00
/**
* @ return total thickness
*/
double thickness() const;
/**
* @ return total thickness in cm
*/
double thickness_cm() const;
2017-07-25 12:19:11 -04:00
Material& operator[](int i){return materials[i];}
friend Layers operator+(const Layers &a, const Layers&b);
2019-10-22 13:50:34 -04:00
2017-07-25 12:19:11 -04:00
friend Layers operator+(const Layers &a, const Material&b);
};
}
#endif