Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_settings_particle.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 <iostream>
11#include <math.h>
12
13#include "GIDI.hpp"
14
15namespace GIDI {
16
17namespace Transporting {
18
19/*! \class Particles
20 * Stores a list of Particle instances.
21 */
22
23/* *********************************************************************************************************//**
24 ***********************************************************************************************************/
25
29
30/* *********************************************************************************************************//**
31 ***********************************************************************************************************/
32
36
37/* *********************************************************************************************************//**
38 * Returns a pointer to the Particle in *this* with PoPs id *a_pid*.
39 *
40 * @param a_pid [in] The PoPs id of the particle to return.
41 *
42 * @return Pointer to particle if it exists or nullptr otherwise.
43 ***********************************************************************************************************/
44
45Particle const *Particles::particle( std::string const &a_pid ) const {
46
47 for( auto particleIter = m_particles.begin( ); particleIter != m_particles.end( ); ++particleIter ) {
48 if( PoPI::compareSpecialParticleIDs( (*particleIter).first, a_pid ) ) return( &(*particleIter).second );
49 }
50
51 return( nullptr );
52}
53
54/* *********************************************************************************************************//**
55 * Adds the Particle *a_particle* to *this*. If a particle with the same id as *a_particle* exists in *this*
56 * the *a_particle* is not added and false is returned.
57 *
58 * @param a_particle [in] The Particle to add to *this* as a particle to transport.
59 *
60 * @return Return true if particle is add and false otherwise.
61 ***********************************************************************************************************/
62
63bool Particles::add( Particle const &a_particle ) {
64
65 std::string const &pid = a_particle.pid( );
66
67 if( m_particles.find( pid ) != m_particles.end( ) ) return( false );
68 m_particles.insert( std::pair<std::string, Particle>( pid, Particle( a_particle ) ) );
69 return( true );
70}
71
72/* *********************************************************************************************************//**
73 * Removes the Particle in *this* with PoPs id *a_pid*.
74 *
75 * @param a_pid [in] The PoPs id of the particle to remove from *this*.
76 *
77 * @return Return *true* if particle exist is remove and non-zero otherwise.
78 ***********************************************************************************************************/
79
80bool Particles::remove( std::string const &a_pid ) {
81
82 std::map<std::string, Particle>::iterator particle = m_particles.find( a_pid );
83
84 if( particle == m_particles.end( ) ) return( false );
85 m_particles.erase( a_pid );
86 return( true );
87}
88
89/* *********************************************************************************************************//**
90 * Returns *true* if Particle with id *a_id* is in *this* and false otherwise.
91 *
92 * @param a_id [in] The PoPs id of the particle to check for in *this*.
93 *
94 * @return Return 0 if particle exist is remove and non-zero otherwise.
95 ***********************************************************************************************************/
96
97bool Particles::hasParticle( std::string const &a_id ) const {
98
99 return( particle( a_id ) != nullptr );
100}
101
102/* *********************************************************************************************************//**
103 * Process all the data in *this*.
104 * This includes determining the mapping between the uncollapsed (specified by *a_label*) and the collapsed multi-group boundaries,
105 * and grouping the flux data for each Particle.
106 *
107 * @param a_protare [in] The Protare whose multi-group data are to accessed.
108 * @param a_label [in] The label of the multi-group data to process.
109 ***********************************************************************************************************/
110
111void Particles::process( Protare const &a_protare, std::string const &a_label ) {
112
113 if( a_label == "" ) return;
114
115 Styles::Base const *style = a_protare.styles( ).get<Styles::Base>( a_label );
116
117 if( style->moniker( ) == GIDI_SnElasticUpScatterStyleChars ) style = a_protare.styles( ).get<Styles::Base>( style->derivedStyle( ) );
118 if( style->moniker( ) != GIDI_heatedMultiGroupStyleChars ) throw Exception( "Label does not yield a heatedMultiGroup style." );
119
120 Styles::HeatedMultiGroup const &heatedMultiGroup = *static_cast<Styles::HeatedMultiGroup const *>( style );
121
122 for( std::map<std::string, Particle>::iterator iter = m_particles.begin( ); iter != m_particles.end( ); ++iter ) {
123 std::string pid = iter->first;
124 Particle *particle = &(iter->second);
125
126 particle->process( heatedMultiGroup.transportable( pid ) );
127 }
128}
129
130/* *********************************************************************************************************//**
131 * Returns the particle IDs of *this* as a sorted *std::vector<std::string>* list.
132 *
133 * @param a_orderIsAscending [in] If *true* IDs are sorted in ascending order, otherwise IDs are in descending order.
134 *
135 * @return The list of sorted particle IDs.
136 ***********************************************************************************************************/
137
138std::vector<std::string> Particles::sortedIDs( bool a_orderIsAscending ) const {
139
140 std::vector<std::string> keys;
141
142 for( std::map<std::string, Particle>::const_iterator iter = m_particles.begin( ); iter != m_particles.end( ); ++iter ) keys.push_back( (*iter).first );
143
144 return( sortedListOfStrings( keys, a_orderIsAscending ) );
145}
146
147/* *********************************************************************************************************//**
148 * Prints the contents of *this* to std::cout. Mainly used for debugging.
149 ***********************************************************************************************************/
150
151void Particles::print( ) const {
152
153 std::cout << "particles:" << std::endl;
154
155 std::vector<std::string> IDs = sortedIDs( );
156 for( std::vector<std::string>::const_iterator iter = IDs.begin( ); iter != IDs.end( ); ++iter ) {
157 Particle const &particle = m_particles.at( *iter );
158
159 particle.print( " " );
160 }
161}
162
163/*! \class Particle
164 * Specifies particle information as mainly needed for multi-group transport. For example, the coarse and fine multi-group data.
165 */
166
167/* *********************************************************************************************************//**
168 * @param a_pid [in] Particle id for the particle.
169 * @param a_multiGroup [in] The multi-group boundaries.
170 * @param a_fluxes [in] The fluxes as f(T,E,mu).
171 * @param a_mode [in] Should probably be deprecated.
172 ***********************************************************************************************************/
173
174Particle::Particle( std::string const &a_pid, MultiGroup const &a_multiGroup, Functions::Function3dForm const &a_fluxes,
175 Transporting::Mode a_mode ) :
176 m_pid( a_pid ),
177 m_mode( a_mode ),
178 m_conserve( Transporting::Conserve::number ),
179 m_multiGroup( a_multiGroup ) {
180
181 std::vector<Transporting::Flux> fluxes = settingsFluxesFromFunction3d( a_fluxes );
182
183 for( auto flux = fluxes.begin( ); flux != fluxes.end( ); ++flux ) appendFlux( *flux );
184}
185
186/* *********************************************************************************************************//**
187 * @param a_pid [in] Particle id for the particle.
188 * @param a_mode [in] Should probably be deprecated.
189 ***********************************************************************************************************/
190
191Particle::Particle( std::string const &a_pid, Transporting::Mode a_mode ) :
192 m_pid( a_pid ),
193 m_mode( a_mode ),
194 m_conserve( Transporting::Conserve::number ) {
195
196}
197
198/* *********************************************************************************************************//**
199 * @param a_pid [in] Particle id for the particle.
200 * @param a_group [in] The multi-group boundaries.
201 * @param a_mode [in] Should probably be deprecated.
202 ***********************************************************************************************************/
203
204Particle::Particle( std::string const &a_pid, MultiGroup const &a_group, Transporting::Mode a_mode ) :
205 m_pid( a_pid ),
206 m_mode( a_mode ),
207 m_conserve( Transporting::Conserve::number ),
208 m_multiGroup( a_group ) {
209
210}
211
212/* *********************************************************************************************************//**
213 * @param a_particle [in] The Particle instance to copy.
214 ***********************************************************************************************************/
215
216Particle::Particle( Particle const &a_particle ) :
217 m_pid( a_particle.pid( ) ),
218 m_mode( a_particle.mode( ) ),
219 m_conserve( a_particle.conserve( ) ),
220 m_multiGroup( a_particle.multiGroup( ) ),
221 m_collapseIndices( a_particle.collapseIndices( ) ) {
222
223 for( std::vector<Flux>::const_iterator iter = a_particle.m_fluxes.begin( ); iter != a_particle.m_fluxes.end( ); ++iter ) {
224 m_fluxes.push_back( *iter );
225 }
226
227 for( std::vector<ProcessedFlux>::const_iterator iter = a_particle.m_processedFluxes.begin( ); iter != a_particle.m_processedFluxes.end( ); ++iter ) {
228 m_processedFluxes.push_back( *iter );
229 }
230}
231
232/* *********************************************************************************************************//**
233 ***********************************************************************************************************/
234
238
239/* *********************************************************************************************************//**
240 * Adds a flux at a specified temperature to the list of fluxes. Currently, the temperature of the flux must be
241 * greater than temperatures for the currently listed fluxes.
242 *
243 * @param a_flux [in] The flux to add.
244 * @return An error code. If not error, returns 0, otherwise returns non-0 value.
245 ***********************************************************************************************************/
246
247int Particle::appendFlux( Flux const &a_flux ) {
248
249 double temperature = a_flux.temperature( );
250 std::vector<Flux>::iterator iter;
251
252 for( iter = m_fluxes.begin( ); iter != m_fluxes.end( ); ++iter ) {
253 if( temperature <= iter->temperature( ) ) break;
254 }
255 if( iter != m_fluxes.end( ) ) return( 1 );
256 m_fluxes.insert( iter, a_flux );
257 return( 0 );
258}
259
260/* *********************************************************************************************************//**
261 * Returns the multi-group flux with its temperature closes to *a_temperature*.
262
263 * @param a_temperature [in] The temperature of the desired flux.
264 ***********************************************************************************************************/
265
266ProcessedFlux const *Particle::nearestProcessedFluxToTemperature( double a_temperature ) const {
267
268 double priorTemperature, lastTemperature = 0; // initialize to silence compiler warning
269 std::vector<ProcessedFlux>::const_iterator iter;
270
271 if( m_processedFluxes.size( ) == 0 ) return( nullptr );
272
273 priorTemperature = m_processedFluxes[0].temperature( );
274 for( iter = m_processedFluxes.begin( ); iter != m_processedFluxes.end( ); ++iter ) {
275 lastTemperature = iter->temperature( );
276 if( lastTemperature > a_temperature ) break;
277 }
278 if( iter == m_processedFluxes.end( ) ) {
279 --iter; }
280 else {
281 if( fabs( lastTemperature - a_temperature ) < fabs( a_temperature - priorTemperature ) ) --iter;
282 }
283 return( &(*iter) );
284}
285
286/* *********************************************************************************************************//**
287 * For internal use only: should only be called from Particles::process. Determines the mapping of fine multi-group boundaries to coarse multi-group boundaries,
288 * and calculated multi-group fluxes from *m_fluxes*.
289 *
290 * @param a_transportable [in] The **Transportable** instance that specified the coarse multi-group information for collapsing.
291 * @param a_epsilon [in] Specifies how close a coarse multi-group boundary must be to a fine multi-group boundary to be considered the same boundary.
292 ***********************************************************************************************************/
293
294void Particle::process( Transportable const &a_transportable, double a_epsilon ) {
295
296 std::vector<double> groupBoundaries = a_transportable.groupBoundaries( );
297 std::string errInfo( "cannot collapse particle '" + m_pid
298 + "' from multi-group '" + a_transportable.group( ).label( ) + "' of size " + std::to_string( groupBoundaries.size( ) )
299 + " to multi-group '" + m_multiGroup.label( ) + "' of size " + std::to_string( m_multiGroup.boundaries( ).size( ) ) );
300
302 if( m_multiGroup.size( ) == 0 ) {
303 m_multiGroup = MultiGroup( a_transportable.group( ).label( ), groupBoundaries );
304 }
305 if( m_fineMultiGroup.size( ) > 0 ) {
306 if( m_fineMultiGroup.size( ) != groupBoundaries.size( ) )
307 throw Exception( "For particle '" + m_pid + "', redefining particle's fine multi-group of different size not allowed." );
308 for( std::size_t i1 = 0; i1 < m_fineMultiGroup.size( ); ++i1 ) {
309 if( fabs( m_fineMultiGroup[i1] - groupBoundaries[i1] ) > a_epsilon * m_fineMultiGroup[i1] )
310 throw Exception( "For particle '" + m_pid + "', redefining particle's fine multi-group not allowed." );
311 }
312 return; // Processing already done.
313 }
314
315 std::size_t i1 = 0, n1 = groupBoundaries.size( );
316
317 while( i1 < n1 ) {
318 if( fabs( m_multiGroup[0] - groupBoundaries[i1] ) <= a_epsilon * groupBoundaries[i1] ) break;
319 ++i1;
320 }
321 if( i1 == n1 ) throw Exception( "Groups not compatible: " + errInfo + "." );
322 m_collapseIndices.push_back( i1 );
323
324 for( std::size_t i2 = 1; i2 < m_multiGroup.size( ); ++i2 ) {
325 while( i1 < n1 ) {
326 if( fabs( m_multiGroup[i2] - groupBoundaries[i1] ) <= a_epsilon * groupBoundaries[i1] ) break;
327 ++i1;
328 }
329 if( i1 == n1 ) throw Exception( "Group boundaries not compatible: " + errInfo + "." );
330 m_collapseIndices.push_back( i1 );
331 }
332
333 if( m_fluxes.size( ) == 0 ) {
334 std::vector<double> fluxes;
335 for( std::size_t index = 0; index < groupBoundaries.size( ) - 1; ++index ) {
336 fluxes.push_back( groupBoundaries[index+1] - groupBoundaries[index] );
337 }
338 m_processedFluxes.push_back( ProcessedFlux( 0.0, fluxes ) ); }
339 else {
340 for( std::size_t i2 = 0; i2 < m_fluxes.size( ); ++i2 ) {
341 ProcessedFlux __processedFlux( m_fluxes[i2].process( groupBoundaries ) );
342 m_processedFluxes.push_back( __processedFlux );
343 }
344 }
345
346 m_fineMultiGroup = a_transportable.group( );
347 }
348
349 if( a_transportable.conserve() == GIDI_conserveNumberChars ) {
351 } else if( a_transportable.conserve() == GIDI_conserveEnergyOutChars ) {
353 } else {
354 throw Exception( "Unrecognized particle conserve flag '" + a_transportable.conserve() + "'" );
355 }
356}
357
358/* *********************************************************************************************************//**
359 * Print Particle data to std::cout. Mainly for debugging.
360 *
361 * @param a_indent [in] The indent for each printed line.
362 ***********************************************************************************************************/
363
364void Particle::print( std::string const &a_indent ) const {
365
366 std::string indent2( " " );
367 indent2 += a_indent;
368
369 std::cout << a_indent << "particle: id = " << m_pid << std::endl;
370 m_multiGroup.print( indent2 );
371
372 std::cout << indent2;
373 for( auto iter = m_collapseIndices.begin( ); iter != m_collapseIndices.end( ); ++iter ) std::cout << " " << *iter;
374 std::cout << std::endl;
375
376}
377
378/*! \class ProcessedFlux
379 * Stores multi-group flux data for a specified material temperature.
380 *
381 * Currently, only supports l=0 flux. This needs to be fixed.
382 */
383
384/* *********************************************************************************************************//**
385 * @param a_temperature
386 * @param a_multiGroupFlux
387 ***********************************************************************************************************/
388
389ProcessedFlux::ProcessedFlux( double a_temperature, std::vector<double> const &a_multiGroupFlux ) :
390 m_temperature( a_temperature ),
391 m_multiGroupFlux( a_multiGroupFlux ) {
392
393}
394
395/* *********************************************************************************************************//**
396 * @param a_processedFlux [in] The ProcessedFlux instance to copy.
397 ***********************************************************************************************************/
398
400 m_temperature( a_processedFlux.temperature( ) ),
401 m_multiGroupFlux( a_processedFlux.multiGroupFlux( ) ) {
402
403}
404
405/* *********************************************************************************************************//**
406 ***********************************************************************************************************/
407
408/*
409=========================================================
410*/
414
415}
416
417}
#define GIDI_conserveEnergyOutChars
Definition GIDI.hpp:466
#define GIDI_conserveNumberChars
Definition GIDI.hpp:465
#define GIDI_heatedMultiGroupStyleChars
Definition GIDI.hpp:253
#define GIDI_SnElasticUpScatterStyleChars
Definition GIDI.hpp:254
std::string const & label() const
Definition GIDI.hpp:658
virtual Styles::Suite & styles()=0
Transportable const & transportable(std::string const &a_ID) const
T * get(std::size_t a_Index)
Definition GIDI.hpp:2642
std::string const & conserve() const
Definition GIDI.hpp:2913
std::vector< double > groupBoundaries() const
Definition GIDI.hpp:2915
Group const & group() const
Definition GIDI.hpp:2914
double temperature() const
Definition GIDI.hpp:3586
MultiGroup multiGroup() const
Definition GIDI.hpp:3668
void process(Transportable const &a_transportable, double a_epsilon=1e-6)
Transporting::Mode mode() const
Definition GIDI.hpp:3663
void print(std::string const &a_indent) const
Transporting::Conserve conserve() const
Definition GIDI.hpp:3664
std::vector< std::size_t > const & collapseIndices() const
Definition GIDI.hpp:3672
Particle(std::string const &a_pid, MultiGroup const &a_multiGroup, Functions::Function3dForm const &a_fluxes, Transporting::Mode a_mode=Transporting::Mode::multiGroup)
ProcessedFlux const * nearestProcessedFluxToTemperature(double a_temperature) const
std::string const & pid() const
Definition GIDI.hpp:3662
bool add(Particle const &a_particle)
void process(Protare const &a_protare, std::string const &a_label)
bool remove(std::string const &a_particleID)
Particle const * particle(std::string const &a_particleID) const
bool hasParticle(std::string const &a_id) const
std::vector< std::string > sortedIDs(bool a_orderIsAscending=true) const
ProcessedFlux(double a_temperature, std::vector< double > const &a_multiGroupFlux)
std::vector< double > const & multiGroupFlux() const
Definition GIDI.hpp:3634
Definition GIDI.hpp:32
std::vector< std::string > sortedListOfStrings(std::vector< std::string > const &a_strings, bool a_orderIsAscending=true)
Definition GIDI_misc.cc:353
std::vector< Transporting::Flux > settingsFluxesFromFunction3d(Functions::Function3dForm const &a_function3d)
bool compareSpecialParticleIDs(std::string const &a_id1, std::string const &a_id2)
Definition PoPI_misc.cc:133
std::string to_string(G4FermiAtomicMass mass)