Geant4  10.02
MCGIDI_outputChannel.cc
Go to the documentation of this file.
1 /*
2 # <<BEGIN-copyright>>
3 # <<END-copyright>>
4 */
5 #include <string.h>
6 #include <cmath>
7 
8 #include "MCGIDI.h"
9 #include "MCGIDI_misc.h"
10 
11 #if defined __cplusplus
12 #include "G4Log.hh"
13 namespace GIDI {
14 using namespace GIDI;
15 #endif
16 
17 /*
18 ************************************************************
19 */
20 MCGIDI_outputChannel *MCGIDI_outputChannel_new( statusMessageReporting *smr ) {
21 
22  MCGIDI_outputChannel *outputChannel;
23 
24  if( ( outputChannel = (MCGIDI_outputChannel *) smr_malloc2( smr, sizeof( MCGIDI_outputChannel ), 0, "outputChannel" ) ) == NULL ) return( NULL );
25  if( MCGIDI_outputChannel_initialize( smr, outputChannel ) ) outputChannel = MCGIDI_outputChannel_free( smr, outputChannel );
26  return( outputChannel );
27 }
28 /*
29 ************************************************************
30 */
31 int MCGIDI_outputChannel_initialize( statusMessageReporting * /*smr*/, MCGIDI_outputChannel *outputChannel ) {
32 
33  memset( outputChannel, 0, sizeof( MCGIDI_outputChannel ) );
34  return( 0 );
35 }
36 /*
37 ************************************************************
38 */
39 MCGIDI_outputChannel *MCGIDI_outputChannel_free( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel ) {
40 
41  MCGIDI_outputChannel_release( smr, outputChannel );
42  smr_freeMemory( (void **) &outputChannel );
43  return( NULL );
44 }
45 /*
46 ************************************************************
47 */
48 int MCGIDI_outputChannel_release( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel ) {
49 
50  int i;
51 
52  for( i = 0; i < outputChannel->numberOfProducts; i++ ) MCGIDI_product_release( smr, &(outputChannel->products[i]) );
53  smr_freeMemory( (void **) &(outputChannel->products) );
54  MCGIDI_outputChannel_initialize( smr, outputChannel );
55 
56  return( 0 );
57 }
58 /*
59 ************************************************************
60 */
61 int MCGIDI_outputChannel_parseFromTOM( statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_POPs *pops, MCGIDI_outputChannel *outputChannel,
62  MCGIDI_reaction *reaction, MCGIDI_product *parent ) {
63 
64  int n, delayedNeutronIndex = 0;
65  char const *genre, *Q;
66  xDataTOM_element *child;
67 
68  MCGIDI_outputChannel_initialize( smr, outputChannel );
69 
70  outputChannel->reaction = reaction;
71  outputChannel->parent = parent;
72  if( ( genre = xDataTOM_getAttributesValueInElement( element, "genre" ) ) == NULL ) goto err;
73  if( ( parent != NULL ) && ( strcmp( genre, "NBody" ) ) ) {
74  smr_setReportError2( smr, smr_unknownID, 1, "decay channel's genre can only be 'uncorreclated' (a.k.a. 'NBody') and not '%s'", genre );
75  goto err;
76  }
77  if( strcmp( genre, "twoBody" ) == 0 ) {
78  outputChannel->genre = MCGIDI_channelGenre_twoBody_e; }
79  else if( strcmp( genre, "NBody" ) == 0 ) {
80  outputChannel->genre = MCGIDI_channelGenre_uncorrelated_e; }
81  else if( strcmp( genre, "sumOfRemainingOutputChannels" ) == 0 ) {
82  outputChannel->genre = MCGIDI_channelGenre_sumOfRemaining_e; }
83  else {
84  smr_setReportError2( smr, smr_unknownID, 1, "unsupported genre = '%s'", genre );
85  goto err;
86  }
87  if( ( Q = xDataTOM_getAttributesValueInElement( element, "Q" ) ) == NULL ) goto err;
88  outputChannel->QIsFloat = !MCGIDI_misc_PQUStringToDoubleInUnitOf( smr, Q, "MeV", &(outputChannel->Q) );
89 
90  if( ( n = xDataTOM_numberOfElementsByName( smr, element, "product" ) ) == 0 ) {
91  smr_setReportError2p( smr, smr_unknownID, 1, "outputChannel does not have any products" );
92  goto err;
93  }
94  if( ( outputChannel->products = (MCGIDI_product *) smr_malloc2( smr, n * sizeof( MCGIDI_product ), 0, "outputChannel->products" ) ) == NULL ) goto err;
95 
96  for( child = xDataTOME_getFirstElement( element ); child != NULL; child = xDataTOME_getNextElement( child ) ) {
97  if( strcmp( child->name, "product" ) == 0 ) {
98  if( MCGIDI_product_parseFromTOM( smr, child, outputChannel, pops, &(outputChannel->products[outputChannel->numberOfProducts]),
99  &delayedNeutronIndex ) ) goto err;
100  outputChannel->numberOfProducts++; }
101  else if( strcmp( child->name, "fissionEnergyReleased" ) == 0 ) { /* ????????? Need to support. */
102  continue; }
103  else {
104  printf( "outputChannel child not currently supported = %s\n", child->name );
105  }
106  }
107  if( outputChannel->genre == MCGIDI_channelGenre_twoBody_e ) {
108  double projectileMass_MeV, targetMass_MeV, productMass_MeV, residualMass_MeV;
109 
110  projectileMass_MeV = MCGIDI_reaction_getProjectileMass_MeV( smr, reaction );
111  targetMass_MeV = MCGIDI_reaction_getTargetMass_MeV( smr, reaction );
112  productMass_MeV = MCGIDI_product_getMass_MeV( smr, &(outputChannel->products[0]) );
113  residualMass_MeV = MCGIDI_product_getMass_MeV( smr, &(outputChannel->products[1]) );
114  MCGIDI_product_setTwoBodyMasses( smr, &(outputChannel->products[0]), projectileMass_MeV, targetMass_MeV, productMass_MeV, residualMass_MeV );
115  }
116 
117  return( 0 );
118 
119 err:
120  MCGIDI_outputChannel_release( smr, outputChannel );
121  return( 1 );
122 }
123 /*
124 ************************************************************
125 */
126 int MCGIDI_outputChannel_numberOfProducts( MCGIDI_outputChannel *outputChannel ) {
127 
128  return( outputChannel->numberOfProducts );
129 }
130 /*
131 ************************************************************
132 */
133 MCGIDI_product *MCGIDI_outputChannel_getProductAtIndex( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, int i ) {
134 
135  if( ( i < 0 ) || ( i >= outputChannel->numberOfProducts ) ) {
136  smr_setReportError2( smr, smr_unknownID, 1, "bad product index = %d: outputChannel as only %d products", i, outputChannel->numberOfProducts );
137  return( NULL );
138  }
139  return( &(outputChannel->products[i]) );
140 }
141 /*
142 ************************************************************
143 */
144 int MCGIDI_outputChannel_getDomain( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double *EMin, double *EMax ) {
145 
146  if( outputChannel->reaction != NULL ) return( MCGIDI_reaction_getDomain( smr, outputChannel->reaction, EMin, EMax ) );
147  return( MCGIDI_product_getDomain( smr, outputChannel->parent, EMin, EMax ) );
148 }
149 /*
150 ************************************************************
151 */
152 MCGIDI_target_heated *MCGIDI_outputChannel_getTargetHeated( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel ) {
153 
154  if( outputChannel->reaction != NULL ) return( MCGIDI_reaction_getTargetHeated( smr, outputChannel->reaction ) );
155  return( MCGIDI_product_getTargetHeated( smr, outputChannel->parent ) );
156 }
157 /*
158 ************************************************************
159 */
160 double MCGIDI_outputChannel_getProjectileMass_MeV( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel ) {
161 
162  if( outputChannel->reaction != NULL ) return( MCGIDI_reaction_getProjectileMass_MeV( smr, outputChannel->reaction ) );
163  return( MCGIDI_product_getProjectileMass_MeV( smr, outputChannel->parent ) );
164 }
165 /*
166 ************************************************************
167 */
168 double MCGIDI_outputChannel_getTargetMass_MeV( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel ) {
169 
170  if( outputChannel->reaction != NULL ) return( MCGIDI_reaction_getTargetMass_MeV( smr, outputChannel->reaction ) );
171  return( MCGIDI_product_getTargetMass_MeV( smr, outputChannel->parent ) );
172 }
173 /*
174 ************************************************************
175 */
176 double MCGIDI_outputChannel_getQ_MeV( statusMessageReporting * /*smr*/, MCGIDI_outputChannel *outputChannel, double /*e_in*/ ) {
177 
178  return( outputChannel->Q );
179 }
180 /*
181 ************************************************************
182 */
183 double MCGIDI_outputChannel_getFinalQ( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double e_in ) {
184 
185  int iProduct;
186  double Q = outputChannel->Q;
187  MCGIDI_product *product;
188 
189  for( iProduct = 0; iProduct < outputChannel->numberOfProducts; iProduct++ ) {
190  product = &(outputChannel->products[iProduct]);
191  if( product->decayChannel.genre != MCGIDI_channelGenre_undefined_e ) Q += MCGIDI_outputChannel_getFinalQ( smr, &(product->decayChannel), e_in );
192  if( !smr_isOk( smr ) ) break;
193  }
194  return( Q );
195 }
196 /*
197 ************************************************************
198 */
199 int MCGIDI_outputChannel_sampleProductsAtE( statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, MCGIDI_quantitiesLookupModes &modes,
200  MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productDatas, double *masses_ ) {
201 
202  int i1, multiplicity, secondTwoBody = 0, isDecayChannel = ( outputChannel->reaction == NULL );
203  double e_in = modes.getProjectileEnergy( );
204  MCGIDI_product *product;
205  double phi, p, masses[3];
206  MCGIDI_distribution *distribution;
207  MCGIDI_sampledProductsData productData[2];
208 
209  if( isDecayChannel ) {
210  masses[0] = masses_[0]; /* More work may be needed here. */
211  masses[1] = masses_[1]; }
212  else {
213  masses[0] = MCGIDI_reaction_getProjectileMass_MeV( smr, outputChannel->reaction );
214  masses[1] = MCGIDI_reaction_getTargetMass_MeV( smr, outputChannel->reaction );
215  }
216 
217  for( i1 = 0; i1 < outputChannel->numberOfProducts; i1++ ) {
218  product = &(outputChannel->products[i1]);
219  if( product->decayChannel.genre != MCGIDI_channelGenre_undefined_e ) {
220  if( MCGIDI_outputChannel_sampleProductsAtE( smr, &(product->decayChannel), modes, decaySamplingInfo, productDatas, masses ) < 0 ) return( -1 ); }
221  else {
222  distribution = &(product->distribution);
223  if( distribution->type == MCGIDI_distributionType_none_e ) continue;
224  if( !secondTwoBody ) {
225  if( ( multiplicity = product->multiplicity ) == 0 ) multiplicity = MCGIDI_product_sampleMultiplicity( smr, product, e_in,
226  decaySamplingInfo->rng( decaySamplingInfo->rngState ) );
227  while( multiplicity > 0 ) {
228 
229  multiplicity--;
230  decaySamplingInfo->pop = product->pop;
231  decaySamplingInfo->mu = 0;
232  decaySamplingInfo->Ep = 0;
233  productData[0].isVelocity = decaySamplingInfo->isVelocity;
234  productData[0].pop = product->pop;
235  productData[0].delayedNeutronIndex = product->delayedNeutronIndex;
236  productData[0].delayedNeutronRate = product->delayedNeutronRate;
237  productData[0].birthTimeSec = 0;
238  if( product->delayedNeutronRate > 0 ) {
239  productData[0].birthTimeSec = -G4Log( decaySamplingInfo->rng( decaySamplingInfo->rngState ) ) / product->delayedNeutronRate;
240  }
241 
242  switch( outputChannel->genre ) {
243  case MCGIDI_channelGenre_twoBody_e :
244  secondTwoBody = 1;
245  MCGIDI_angular_sampleMu( smr, distribution->angular, modes, decaySamplingInfo );
246  if( smr_isOk( smr ) ) {
247  phi = 2. * M_PI * decaySamplingInfo->rng( decaySamplingInfo->rngState );
248  MCGIDI_kinetics_2BodyReaction( smr, distribution->angular, e_in, decaySamplingInfo->mu, phi, productData );
249  if( !smr_isOk( smr ) ) return( -1 );
250  productData[1].pop = product[1].pop;
251  productData[1].delayedNeutronIndex = product[1].delayedNeutronIndex;
252  productData[1].delayedNeutronRate = product->delayedNeutronRate;
253  productData[1].birthTimeSec = 0;
254  MCGIDI_sampledProducts_addProduct( smr, productDatas, productData );
255  if( !smr_isOk( smr ) ) return( -1 );
256  MCGIDI_sampledProducts_addProduct( smr, productDatas, &(productData[1]) );
257  if( !smr_isOk( smr ) ) return( -1 );
258  }
259  break;
260  case MCGIDI_channelGenre_uncorrelated_e :
261  case MCGIDI_channelGenre_sumOfRemaining_e :
262  masses[2] = MCGIDI_product_getMass_MeV( smr, product );
263  switch( distribution->type ) {
264  case MCGIDI_distributionType_uncorrelated_e :
265  MCGIDI_uncorrelated_sampleDistribution( smr, distribution, modes, decaySamplingInfo );
266  break;
267  case MCGIDI_distributionType_energyAngular_e :
268  MCGIDI_energyAngular_sampleDistribution( smr, distribution, modes, decaySamplingInfo );
269  break;
270  case MCGIDI_distributionType_KalbachMann_e :
271  MCGIDI_KalbachMann_sampleEp( smr, distribution->KalbachMann, modes, decaySamplingInfo );
272  break;
273  case MCGIDI_distributionType_angularEnergy_e :
274  MCGIDI_angularEnergy_sampleDistribution( smr, distribution->angularEnergy, modes, decaySamplingInfo );
275  break;
276  default :
277  printf( "Unknown spectral data form product name = %s, channel genre = %d\n", product->pop->name, outputChannel->genre );
278  break;
279  }
280  break;
281  case MCGIDI_channelGenre_undefined_e :
282  printf( "Channel is undefined\n" );
283  case MCGIDI_channelGenre_twoBodyDecay_e :
284  printf( "Channel is twoBodyDecay\n" );
285  case MCGIDI_channelGenre_uncorrelatedDecay_e :
286  printf( "Channel is uncorrelatedDecay\n" );
287  default :
288  printf( "Unsupported channel genre = %d\n", outputChannel->genre );
289  }
290  if( !smr_isOk( smr ) ) return( -1 );
291  if( !secondTwoBody ) {
292  if( decaySamplingInfo->frame == xDataTOM_frame_centerOfMass ) {
293  if( MCGIDI_kinetics_COM2Lab( smr, modes, decaySamplingInfo, masses ) != 0 ) return( -1 );
294  }
295  productData[0].kineticEnergy = decaySamplingInfo->Ep;
296  p = std::sqrt( decaySamplingInfo->Ep * ( decaySamplingInfo->Ep + 2. * product->pop->mass_MeV ) );
297  if( productData[0].isVelocity ) p *= MCGIDI_speedOfLight_cm_sec / std::sqrt( p * p + product->pop->mass_MeV * product->pop->mass_MeV );
298  productData[0].pz_vz = p * decaySamplingInfo->mu;
299  p = std::sqrt( 1. - decaySamplingInfo->mu * decaySamplingInfo->mu ) * p;
300  phi = 2. * M_PI * decaySamplingInfo->rng( decaySamplingInfo->rngState );
301  productData[0].px_vx = p * std::sin( phi );
302  productData[0].py_vy = p * std::cos( phi );
303  MCGIDI_sampledProducts_addProduct( smr, productDatas, productData );
304  if( !smr_isOk( smr ) ) return( -1 );
305  }
306  } // Loop checking, 11.06.2015, T. Koi
307  }
308  }
309  }
310  return( productDatas->numberOfProducts );
311 }
312 
313 #if defined __cplusplus
314 }
315 #endif
316 
int MCGIDI_product_parseFromTOM(statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_outputChannel *outputChannel, MCGIDI_POPs *pops, MCGIDI_product *product, int *delayedNeutronIndex)
int MCGIDI_kinetics_COM2Lab(statusMessageReporting *smr, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, double masses[3])
int MCGIDI_angular_sampleMu(statusMessageReporting *smr, MCGIDI_angular *angular, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo)
int MCGIDI_outputChannel_release(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel)
int MCGIDI_product_sampleMultiplicity(statusMessageReporting *, MCGIDI_product *product, double e_in, double r)
xDataTOM_element * xDataTOME_getFirstElement(xDataTOM_element *element)
Definition: xDataTOM.cc:230
int MCGIDI_reaction_getDomain(statusMessageReporting *, MCGIDI_reaction *reaction, double *EMin, double *EMax)
double MCGIDI_outputChannel_getQ_MeV(statusMessageReporting *, MCGIDI_outputChannel *outputChannel, double)
double MCGIDI_reaction_getTargetMass_MeV(statusMessageReporting *smr, MCGIDI_reaction *reaction)
int MCGIDI_KalbachMann_sampleEp(statusMessageReporting *smr, MCGIDI_KalbachMann *KalbachMann, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo)
static double Q[]
double MCGIDI_product_getTargetMass_MeV(statusMessageReporting *smr, MCGIDI_product *product)
int MCGIDI_kinetics_2BodyReaction(statusMessageReporting *smr, MCGIDI_angular *angular, double K, double mu, double phi, MCGIDI_sampledProductsData *outgoingData)
int MCGIDI_uncorrelated_sampleDistribution(statusMessageReporting *smr, MCGIDI_distribution *distribution, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo)
int xDataTOM_numberOfElementsByName(statusMessageReporting *, xDataTOM_element *element, char const *name)
Definition: xDataTOM.cc:268
double MCGIDI_product_getMass_MeV(statusMessageReporting *, MCGIDI_product *product)
double MCGIDI_outputChannel_getTargetMass_MeV(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel)
double MCGIDI_outputChannel_getFinalQ(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double e_in)
int MCGIDI_angularEnergy_sampleDistribution(statusMessageReporting *smr, MCGIDI_angularEnergy *angularEnergy, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo)
int MCGIDI_product_release(statusMessageReporting *smr, MCGIDI_product *product)
int smr_isOk(statusMessageReporting *smr)
int MCGIDI_outputChannel_parseFromTOM(statusMessageReporting *smr, xDataTOM_element *element, MCGIDI_POPs *pops, MCGIDI_outputChannel *outputChannel, MCGIDI_reaction *reaction, MCGIDI_product *parent)
MCGIDI_target_heated * MCGIDI_reaction_getTargetHeated(statusMessageReporting *, MCGIDI_reaction *reaction)
void * smr_freeMemory(void **p)
MCGIDI_product * MCGIDI_outputChannel_getProductAtIndex(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, int i)
MCGIDI_target_heated * MCGIDI_outputChannel_getTargetHeated(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel)
const G4int n
int MCGIDI_outputChannel_initialize(statusMessageReporting *, MCGIDI_outputChannel *outputChannel)
int MCGIDI_sampledProducts_addProduct(statusMessageReporting *smr, MCGIDI_sampledProductsDatas *sampledProductsDatas, MCGIDI_sampledProductsData *sampledProductsData)
double MCGIDI_product_getProjectileMass_MeV(statusMessageReporting *smr, MCGIDI_product *product)
int MCGIDI_misc_PQUStringToDoubleInUnitOf(statusMessageReporting *smr, char const *str, char const *toUnit, double *value)
Definition: MCGIDI_misc.cc:356
MCGIDI_target_heated * MCGIDI_product_getTargetHeated(statusMessageReporting *smr, MCGIDI_product *product)
char const * xDataTOM_getAttributesValueInElement(xDataTOM_element *element, char const *name)
Definition: xDataTOM.cc:286
int MCGIDI_outputChannel_sampleProductsAtE(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo, MCGIDI_sampledProductsDatas *productDatas, double *masses_)
G4double G4Log(G4double x)
Definition: G4Log.hh:230
double MCGIDI_reaction_getProjectileMass_MeV(statusMessageReporting *smr, MCGIDI_reaction *reaction)
xDataTOM_element * xDataTOME_getNextElement(xDataTOM_element *element)
Definition: xDataTOM.cc:238
MCGIDI_outputChannel * MCGIDI_outputChannel_free(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel)
int MCGIDI_outputChannel_getDomain(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel, double *EMin, double *EMax)
int MCGIDI_outputChannel_numberOfProducts(MCGIDI_outputChannel *outputChannel)
MCGIDI_outputChannel * MCGIDI_outputChannel_new(statusMessageReporting *smr)
int MCGIDI_product_getDomain(statusMessageReporting *smr, MCGIDI_product *product, double *EMin, double *EMax)
int MCGIDI_product_setTwoBodyMasses(statusMessageReporting *smr, MCGIDI_product *product, double projectileMass_MeV, double targetMass_MeV, double productMass_MeV, double residualMass_MeV)
double MCGIDI_outputChannel_getProjectileMass_MeV(statusMessageReporting *smr, MCGIDI_outputChannel *outputChannel)
int MCGIDI_energyAngular_sampleDistribution(statusMessageReporting *smr, MCGIDI_distribution *distribution, MCGIDI_quantitiesLookupModes &modes, MCGIDI_decaySamplingInfo *decaySamplingInfo)