Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_polynomial1d.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include "GIDI.hpp"
11#include <HAPI.hpp>
12
13/* *********************************************************************************************************//**
14 * This is the function callback used by asXYs1d to evalaute *this* at a domain point. This function is for internal use.
15 *
16 * @param a_smr [in/out]
17 * @param a_xValue [in] The x-value to evaluate the polynomial at.
18 * @param a_yValue [in] A pointer to a double that will contained the polynomial evaluated at *a_xValue*.
19 * @param a_argList [in] A pointer to a list of additional arguments needed.
20 *
21 * @return A nfu_status value.
22 ***********************************************************************************************************/
23
24static nfu_status asXYs1d_callback( LUPI_maybeUnused statusMessageReporting *a_smr, double a_xValue, double *a_yValue, void *a_argList ) {
25
27
28 *a_yValue = polynomial1d->evaluate( a_xValue );;
29 return( nfu_Okay );
30}
31
32namespace GIDI {
33
34namespace Functions {
35
36
37/*! \class Polynomial1d
38 * Class for the GNDS <**polynomial1d**> node.
39 */
40
41/* *********************************************************************************************************//**
42 * @param a_axes [in] The axes to copy for *this*.
43 * @param a_domainMin [in] The minimum value for the domain.
44 * @param a_domainMax [in] The maximum value for the domain.
45 * @param a_coefficients [in] The coefficients representing the polynomial.
46 * @param a_index [in] Currently not used.
47 * @param a_outerDomainValue [in] If embedded in a higher dimensional function, the value of the domain of the next higher dimension.
48 ***********************************************************************************************************/
49
50Polynomial1d::Polynomial1d( Axes const &a_axes, double a_domainMin, double a_domainMax, std::vector<double> const &a_coefficients, int a_index, double a_outerDomainValue ) :
52 m_domainMin( a_domainMin ),
53 m_domainMax( a_domainMax ),
54 m_coefficients( a_coefficients ) {
55
56}
57
58/* *********************************************************************************************************//**
59 * @param a_construction [in] Used to pass user options to the constructor.
60 * @param a_node [in] The **HAPI::Node** to be parsed and used to construct the XYs2d.
61 * @param a_setupInfo [in] Information create my the Protare constructor to help in parsing.
62 * @param a_parent [in] The parent GIDI::Suite.
63 ***********************************************************************************************************/
64
65Polynomial1d::Polynomial1d( Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, Suite *a_parent ) :
66 Function1dForm( a_construction, a_node, a_setupInfo, FormType::polynomial1d, a_parent ),
67 m_domainMin( a_node.attribute( GIDI_domainMinChars ).as_double( ) ),
68 m_domainMax( a_node.attribute( GIDI_domainMaxChars ).as_double( ) ) {
69
70 nf_Buffer<double> coeff;
71 parseValuesOfDoubles( a_construction, a_node.child( GIDI_valuesChars ), a_setupInfo, coeff );
72 m_coefficients = coeff.vector();
73}
74
75/* *********************************************************************************************************//**
76 * The Polynomial1d copy constructor.
77 *
78 * @param a_polynomial1d [in] The Polynomial1d instance to copy.
79 ***********************************************************************************************************/
80
81Polynomial1d::Polynomial1d( Polynomial1d const &a_polynomial1d ) :
82 Function1dForm( a_polynomial1d ),
83 m_domainMin( a_polynomial1d.domainMin( ) ),
84 m_domainMax( a_polynomial1d.domainMax( ) ),
85 m_coefficients( a_polynomial1d.coefficients( ) ) {
86
87}
88
89/* *********************************************************************************************************//**
90 ***********************************************************************************************************/
91
95
96/* *********************************************************************************************************//**
97 * The value of the polynomial at the point *a_x1*.
98 *
99 * @param a_x1 [in] Domain value to evaluate this at.
100 * @return The value of the polynomial at the point **a_x1**.
101 ***********************************************************************************************************/
102
103double Polynomial1d::evaluate( double a_x1 ) const {
104
105 double _value = 0;
106
107 if( a_x1 < m_domainMin ) return( 0.0 );
108 if( a_x1 > m_domainMax ) return( 0.0 );
109
110 for( std::vector<double>::const_reverse_iterator riter = m_coefficients.rbegin( ); riter != m_coefficients.rend( ); ++riter ) {
111 _value = *riter + _value * a_x1;
112 }
113 return( _value );
114}
115
116/* *********************************************************************************************************//**
117 * Evaluates *this* at the X-values in *a_Xs*[*a_offset*:] and adds the results to *a_results*[*a_offset*:].
118 * *a_Xs* and *a_results* must be the same size otherwise a throw is executed.
119 *
120 * @param a_offset [in] The offset in *a_Xs* to start.
121 * @param a_Xs [in] The list of domain values to evaluate *this* at.
122 * @param a_results [in] The list whose values are added to by the Y-values of *this*.
123 * @param a_scaleFactor [in] A factor applied to each evaluation before it is added to *a_results*.
124 ***********************************************************************************************************/
125
126void Polynomial1d::mapToXsAndAdd( std::size_t a_offset, std::vector<double> const &a_Xs, std::vector<double> &a_results, double a_scaleFactor ) const {
127
128 if( a_Xs.size( ) != a_results.size( ) ) throw Exception( "Constant1d::mapToXsAndAdd: a_Xs.size( ) != a_results.size( )." );
129
130 std::size_t index = 0;
131 auto XsIter = a_Xs.begin( );
132
133 for( ; XsIter != a_Xs.end( ); ++XsIter, ++index ) {
134 if( a_offset == index ) break;
135 }
136
137 for( ; XsIter != a_Xs.end( ); ++XsIter, ++index ) {
138 if( *XsIter >= m_domainMin ) break;
139 }
140
141 for( ; XsIter != a_Xs.end( ); ++XsIter, ++index ) {
142 if( *XsIter > m_domainMax ) break;
143 a_results[index] += a_scaleFactor * evaluate( *XsIter );
144 }
145}
146
147/* *********************************************************************************************************//**
148 * This methods returns an XYs1d representation of *this*. The calling function owns the created instance and is responible
149 * for freeing it.
150 *
151 * @param a_asLinlin [in] This argument is not used but retained to make the methods API at same as other asXYs1d functions.
152 * @param a_accuracy [in] The accuracy use to convert the data to lin=lin interpolation if needed.
153 * @param a_lowerEps [in] This argument is not used but retained to make the methods API at same as other asXYs1d functions.
154 * @param a_upperEps [in] This argument is not used but retained to make the methods API at same as other asXYs1d functions.
155 *
156 * @return A pointer to an XYs1d instance that must be freed by the calling function.
157 ***********************************************************************************************************/
158
159XYs1d *Polynomial1d::asXYs1d( LUPI_maybeUnused bool a_asLinlin, double a_accuracy, LUPI_maybeUnused double a_lowerEps, LUPI_maybeUnused double a_upperEps ) const {
160
161 XYs1d *xys1d = nullptr;
162
163 if( m_coefficients.size( ) < 3 ) {
164 double offset = 0.0, slope = 0.0;
165 if( m_coefficients.size( ) > 0 ) {
166 offset = m_coefficients[0];
167 if( m_coefficients.size( ) == 2 ) slope = m_coefficients[1];
168 }
169
170 std::vector<double> xs( 2 );
171 xs[0] = domainMin( );
172 xs[1] = domainMax( );
173
174 std::vector<double> ys( 2 );
175 ys[0] = slope * xs[0] + offset;
176 ys[1] = slope * xs[1] + offset;
177
178 xys1d = new XYs1d( axes( ), ptwXY_interpolationLinLin, xs, ys ); }
179 else {
180 double xs[2] = { domainMin( ), domainMax( ) };
181 ptwXYPoints *ptwXYPoints1 = ptwXY_createFromFunction( nullptr, 2, xs, asXYs1d_callback, const_cast<Polynomial1d *>( this ), a_accuracy, 1, 12 );
182 if( ptwXYPoints1 != nullptr ) xys1d = new XYs1d( axes( ), ptwXYPoints1 );
183 }
184
185 return( xys1d );
186}
187
188/* *********************************************************************************************************//**
189 * Fills the argument *a_writeInfo* with the XML lines that represent *this*. Recursively enters each sub-node.
190 *
191 * @param a_writeInfo [in/out] Instance containing incremental indentation and other information and stores the appended lines.
192 * @param a_indent [in] The amount to indent *this* node.
193 * @param a_embedded [in] If *true*, *this* function is embedded in a higher dimensional function.
194 * @param a_inRegions [in] If *true*, *this* is in a Regions1d container.
195 ***********************************************************************************************************/
196
197void Polynomial1d::toXMLList_func( GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, bool a_embedded, bool a_inRegions ) const {
198
199 std::string indent2 = a_writeInfo.incrementalIndent( a_indent );
200 std::string attributes;
201
202 if( a_embedded ) {
204 else {
205 if( a_inRegions ) {
206 attributes = a_writeInfo.addAttribute( GIDI_indexChars, intToString( index( ) ) ); }
207 else {
208 if( label( ) != "" ) attributes = a_writeInfo.addAttribute( GIDI_labelChars, label( ) );
209 }
210 }
211
214 a_writeInfo.addNodeStarter( a_indent, moniker( ), attributes );
215
216 axes( ).toXMLList( a_writeInfo, indent2 );
217 doublesToXMLList( a_writeInfo, indent2, m_coefficients );
218 a_writeInfo.addNodeEnder( moniker( ) );
219}
220
221} // End namespace Functions.
222
223} // End namespace GIDI.
G4ThreadLocal T * G4GeomSplitter< T >::offset
#define GIDI_valuesChars
Definition GIDI.hpp:260
#define GIDI_outerDomainValueChars
Definition GIDI.hpp:436
#define GIDI_labelChars
Definition GIDI.hpp:438
#define GIDI_indexChars
Definition GIDI.hpp:437
#define GIDI_domainMaxChars
Definition GIDI.hpp:447
#define GIDI_domainMinChars
Definition GIDI.hpp:446
#define GIDI_polynomial1dChars
Definition GIDI.hpp:290
#define LUPI_maybeUnused
void toXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent="") const
Definition GIDI_axes.cc:113
std::string const & label() const
Definition GIDI.hpp:658
Function1dForm(std::string const &a_moniker, FormType a_type, ptwXY_interpolation a_interpolation, int a_index, double a_outerDomainValue)
Definition GIDI_form.cc:348
Axes const & axes() const
Definition GIDI.hpp:1012
double outerDomainValue() const
Definition GIDI.hpp:1010
void toXMLList_func(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, bool a_embedded, bool a_inRegions) const
Polynomial1d(Axes const &a_axes, double a_domainMin, double a_domainMax, std::vector< double > const &a_coefficients, int a_index=0, double a_outerDomainValue=0.0)
XYs1d * asXYs1d(bool a_asLinlin, double a_accuray, double a_lowerEps, double a_upperEps) const
double evaluate(double a_x1) const
void mapToXsAndAdd(std::size_t a_offset, std::vector< double > const &a_Xs, std::vector< double > &a_results, double a_scaleFactor) const
std::vector< double > const & coefficients() const
Definition GIDI.hpp:1197
std::string const & moniker() const
Definition GUPI.hpp:102
std::string attribute() const
Definition GUPI.hpp:107
void addNodeEnder(std::string const &a_moniker)
Definition GUPI.hpp:59
std::string incrementalIndent(std::string const &indent)
Definition GUPI.hpp:52
void addNodeStarter(std::string const &indent, std::string const &a_moniker, std::string const &a_attributes="")
Definition GUPI.hpp:55
std::string addAttribute(std::string const &a_name, std::string const &a_value) const
Definition GUPI.hpp:60
Node child(const char *name) const
Definition HAPI_Node.cc:72
Definition GIDI.hpp:32
void parseValuesOfDoubles(Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, nf_Buffer< double > &a_vector)
Definition GIDI_misc.cc:88
FormType
Definition GIDI.hpp:118
void doublesToXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent, std::vector< double > const &a_values, std::size_t a_start=0, bool a_newLine=true, std::string const &a_valueType="")
Definition GIDI_misc.cc:180
std::string intToString(int a_value)
Definition GIDI_misc.cc:415
std::string doubleToShortestString(double a_value, int a_significantDigits=15, int a_favorEFormBy=0)
Definition LUPI_misc.cc:349
@ nfu_Okay
enum nfu_status_e nfu_status
ptwXYPoints * ptwXY_createFromFunction(statusMessageReporting *smr, int n, double *xs, ptwXY_createFromFunction_callback func, void *argList, double accuracy, int checkForRoots, int biSectionMax)
Definition ptwXY_misc.c:46
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
struct ptwXYPoints_s ptwXYPoints