/* * 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 . */ #include #include #include "storage.h" #include "catima/catima.h" namespace catima { Data _storage; EnergyTable energy_table(logEmin,logEmax); bool operator==(const DataPoint &a, const DataPoint &b){ if( (a.m == b.m) && (a.p == b.p) && (a.config == b.config)){ return true; } else{ return false; } } #ifdef GSL_INTERPOLATION //////////// Interpolator //////////////////////////////// InterpolatorGSL::InterpolatorGSL(const EnergyTable& x, const std::vector& y, interpolation_t type){ acc = gsl_interp_accel_alloc (); const int num = y.size(); if(type==cspline) spline = gsl_spline_alloc (gsl_interp_cspline, num); else spline = gsl_spline_alloc (gsl_interp_linear, num); gsl_spline_init (spline, x.values, y.data(), num); min= x[0]; max= x[num-1]; } InterpolatorGSL::~InterpolatorGSL(){ gsl_interp_accel_free (acc); gsl_spline_free (spline); } double InterpolatorGSL::eval(double x) const{ if(xmax)x=max; return gsl_spline_eval(spline, x, acc); } double InterpolatorGSL::derivative(double x)const{ if(xmax)x=max; return gsl_spline_eval_deriv (spline, x, acc); } #endif #ifdef STORE_SPLINES const Interpolator& get_range_spline(const DataPoint &data){ return data.range_spline; } const Interpolator& get_range_straggling_spline(const DataPoint &data){ return data.range_straggling_spline; } const Interpolator& get_angular_variance_spline(const DataPoint &data){ return data.angular_variance_spline; } #else Interpolator get_range_spline(const DataPoint &data){ //return Interpolator(energy_table.values,data.range); //return data.range_spline; return Interpolator(energy_table,data.range); } Interpolator get_range_straggling_spline(const DataPoint &data){ //return Interpolator(energy_table.values,data.range_straggling); //return data.range_straggling_spline; return Interpolator(energy_table,data.range_straggling); } Interpolator get_angular_variance_spline(const DataPoint &data){ //return Interpolator(energy_table.values,data.angular_variance); //return data.angular_variance_spline; return Interpolator(energy_table,data.angular_variance); } #endif Data::Data(){ //storage.reserve(max_storage_data); // disabled because of "circular" storage storage.resize(max_storage_data); index = storage.begin(); } Data::~Data(){ } void Data::Add(const Projectile &p, const Material &t, const Config &c){ DataPoint dp(p,t,c); for(auto &e:storage){ if(e==dp)return; } if(index==storage.end())index=storage.begin(); #if(0) *index = dp; index->range = calculate_range(p,t,c); index->range_straggling = calculate_range_straggling(p,t,c); index->angular_variance = calculate_angular_variance(p,t,c); #else *index = calculate_DataPoint(p,t,c); #ifdef STORE_SPLINES //index->range_spline = Interpolator(energy_table.values,index->range); //index->range_straggling_spline = Interpolator(energy_table.values,index->range_straggling); //index->angular_variance_spline = Interpolator(energy_table.values,index->angular_variance); index->range_spline = Interpolator(energy_table, index->range); index->range_straggling_spline = Interpolator(energy_table, index->range_straggling); index->angular_variance_spline = Interpolator(energy_table, index->angular_variance); #endif #endif index++; } DataPoint& Data::Get(const Projectile &p, const Material &t, const Config &c){ for(auto &e:storage){ if( (e.p==p) && (e.m==t) && (e.config==c)){ return e; } } Add(p,t,c); //return storage.back(); return *std::prev(index); } }