203{
205 static const G4double expxl = -expxu;
206
210
211 static const G4int numMul = 1200;
212 static const G4int numMulAn = 400;
213 static const G4int numSec = 60;
214
217
220
221 static G4bool first =
true;
222 static G4double protmul[numMul], protnorm[numSec];
223 static G4double protmulAn[numMulAn],protnormAn[numSec];
224 static G4double neutmul[numMul], neutnorm[numSec];
225 static G4double neutmulAn[numMulAn],neutnormAn[numSec];
226
227
228
229
230 G4int i, counter, nt, npos, nneg, nzero;
231
232 if( first )
233 {
234 first = false;
235 for( i=0; i<numMul ; i++ ) protmul[i] = 0.0;
236 for( i=0; i<numSec ; i++ ) protnorm[i] = 0.0;
237 counter = -1;
238 for( npos=0; npos<(numSec/3); npos++ )
239 {
240 for( nneg=
Imax(0,npos-1); nneg<=(npos+1); nneg++ )
241 {
242 for( nzero=0; nzero<numSec/3; nzero++ )
243 {
244 if( ++counter < numMul )
245 {
246 nt = npos+nneg+nzero;
247 if( (nt>0) && (nt<=numSec) )
248 {
249 protmul[counter] =
pmltpc(npos,nneg,nzero,nt,protb,c);
250 protnorm[nt-1] += protmul[counter];
251 }
252 }
253 }
254 }
255 }
256 for( i=0; i<numMul; i++ )neutmul[i] = 0.0;
257
258 for( i=0; i<numSec; i++ )neutnorm[i] = 0.0;
259 counter = -1;
260 for( npos=0; npos<numSec/3; npos++ )
261 {
262 for( nneg=npos; nneg<=(npos+2); nneg++ )
263 {
264 for( nzero=0; nzero<numSec/3; nzero++ )
265 {
266 if( ++counter < numMul )
267 {
268 nt = npos+nneg+nzero;
269 if( (nt>0) && (nt<=numSec) )
270 {
271 neutmul[counter] =
pmltpc(npos,nneg,nzero,nt,neutb,c);
272 neutnorm[nt-1] += neutmul[counter];
273 }
274 }
275 }
276 }
277 }
278 for( i=0; i<numSec; i++ )
279 {
280 if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
281 if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
282 }
283
284 for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
285 for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
286 counter = -1;
287 for( npos=1; npos<(numSec/3); npos++ )
288 {
289 nneg = npos;
290 for( nzero=0; nzero<numSec/3; nzero++ )
291 {
292 if( ++counter < numMulAn )
293 {
294 nt = npos+nneg+nzero;
295 if( (nt>0) && (nt<=numSec) )
296 {
297 protmulAn[counter] =
pmltpc(npos,nneg,nzero,nt,protb,c);
298 protnormAn[nt-1] += protmulAn[counter];
299 }
300 }
301 }
302 }
303 for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
304 for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
305 counter = -1;
306 for( npos=1; npos<numSec/3; npos++ )
307 {
308 nneg = npos+1;
309 for( nzero=0; nzero<numSec/3; nzero++ )
310 {
311 if( ++counter < numMulAn )
312 {
313 nt = npos+nneg+nzero;
314 if( (nt>0) && (nt<=numSec) )
315 {
316 neutmulAn[counter] =
pmltpc(npos,nneg,nzero,nt,neutb,c);
317 neutnormAn[nt-1] += neutmulAn[counter];
318 }
319 }
320 }
321 }
322 for( i=0; i<numSec; i++ )
323 {
324 if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
325 if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
326 }
327 }
328
329
330
331
332 pv[0] = incidentParticle;
333 pv[1] = targetParticle;
334 vecLen = 2;
335
336 if( !inElastic )
337 {
338 if( targetCode == protonCode )
339 {
340 G4double cech[] = {0.14, 0.170, 0.180, 0.180, 0.180, 0.170, 0.170, 0.160, 0.155, 0.145,
341 0.11, 0.082, 0.065, 0.050, 0.041, 0.035, 0.028, 0.024, 0.010, 0.000};
342
343 G4int iplab =
G4int( incidentTotalMomentum*10.);
344 if (iplab > 9) iplab =
Imin(19,
G4int( incidentTotalMomentum) + 9);
345 if(
G4UniformRand() < cech[iplab]/std::pow(atomicWeight,0.42) )
346 {
349 }
350 }
351 return;
352 }
354 return;
355
356
357
358 npos = 0; nneg = 0; nzero = 0;
359 G4double anhl[] = {1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.90,
360 0.60, 0.52, 0.47, 0.44, 0.41, 0.39, 0.37, 0.35, 0.34, 0.24,
361 0.19, 0.15, 0.12, 0.10, 0.09, 0.07, 0.06, 0.05, 0.00};
362 G4int iplab =
G4int( incidentTotalMomentum*10.);
363 if ( iplab > 9) iplab = 9 +
G4int( incidentTotalMomentum);
364 if ( iplab > 18) iplab = 18 +
G4int( incidentTotalMomentum*10.);
365 iplab =
Imin(28, iplab);
366
368 {
369
372
373 G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
375 {
376
377
380 {
381 w0 = -
sqr(1.+neutb)/(2.*c*c);
382 w0 = std::exp(w0);
383 wm = -
sqr(-1.+neutb)/(2.*c*c);
384 wm = std::exp(wm);
386 { npos = 0; nneg = 0; nzero = 1; }
387 else
388 { npos = 0; nneg = 1; nzero = 0; }
389 }
390 else
391 {
392 w0 = -
sqr(1.+protb)/(2.*c*c);
393 w0 = std::exp(w0);
394 wp = w0;
395 wm = -
sqr(-1.+protb)/(2.*c*c);
396 wm = std::exp(wm);
397 wt = w0+wp+wm;
398 wp = w0+wp;
400 if( ran < w0/wt)
401 { npos = 0; nneg = 0; nzero = 1; }
402 else if( ran < wp/wt)
403 { npos = 1; nneg = 0; nzero = 0; }
404 else
405 { npos = 0; nneg = 1; nzero = 0; }
406 }
407 }
408 else
409 {
410
411
412 G4double aleab = std::log(availableEnergy);
413 G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
414 + aleab*(0.117712+0.0136912*aleab))) - 2.0;
415
416
417
419
420 for (nt=1; nt<=numSec; nt++) {
421 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
422 dum =
pi*nt/(2.0*
n*
n);
423 if (std::fabs(dum) < 1.0) {
424 if( test >= 1.0e-10 )anpn += dum*test;
425 } else {
426 anpn += dum*test;
427 }
428 }
429
432 if( targetCode == protonCode )
433 {
434 counter = -1;
435 for( npos=0; npos<numSec/3; npos++ )
436 {
437 for( nneg=
Imax(0,npos-1); nneg<=(npos+1); nneg++ )
438 {
439 for( nzero=0; nzero<numSec/3; nzero++ )
440 {
441 if( ++counter < numMul )
442 {
443 nt = npos+nneg+nzero;
444 if ( (nt>0) && (nt<=numSec) ) {
445 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
446 dum = (
pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
447 if (std::fabs(dum) < 1.0) {
448 if( test >= 1.0e-10 )excs += dum*test;
449 } else {
450 excs += dum*test;
451 }
452
453 if (ran < excs) goto outOfLoop;
454 }
455 }
456 }
457 }
458 }
459
460
461 inElastic = false;
462 return;
463 }
464 else
465 {
466 counter = -1;
467 for( npos=0; npos<numSec/3; npos++ )
468 {
469 for( nneg=npos; nneg<=(npos+2); nneg++ )
470 {
471 for( nzero=0; nzero<numSec/3; nzero++ )
472 {
473 if( ++counter < numMul )
474 {
475 nt = npos+nneg+nzero;
476 if ( (nt>=1) && (nt<=numSec) ) {
477 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
478 dum = (
pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
479 if (std::fabs(dum) < 1.0) {
480 if( test >= 1.0e-10 )excs += dum*test;
481 } else {
482 excs += dum*test;
483 }
484
485 if (ran < excs) goto outOfLoop;
486 }
487 }
488 }
489 }
490 }
491
492 inElastic = false;
493 return;
494 }
495 }
496 outOfLoop:
497
499 {
500 if( npos == nneg)
501 {
502 }
503 else if (npos == (nneg-1))
504 {
506 {
508 }
509 else
510 {
512 }
513 }
514 else
515 {
518 }
519 }
520 else
521 {
522 if( npos == nneg)
523 {
525 {
528 }
529 else
530 {
531 }
532 }
533 else if ( npos == (1+nneg))
534 {
536 }
537 else
538 {
540 }
541 }
542
543 }
544 else
545 {
547 {
548
549 G4double aleab = std::log(availableEnergy);
550 G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
551 + aleab*(0.117712+0.0136912*aleab))) - 2.0;
552
553
554
556
557 for (nt=2; nt<=numSec; nt++) {
558 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
559 dum =
pi*nt/(2.0*
n*
n);
560 if (std::fabs(dum) < 1.0) {
561 if( test >= 1.0e-10 )anpn += dum*test;
562 } else {
563 anpn += dum*test;
564 }
565 }
566
569 if( targetCode == protonCode )
570 {
571 counter = -1;
572 for( npos=1; npos<numSec/3; npos++ )
573 {
574 nneg = npos;
575 for( nzero=0; nzero<numSec/3; nzero++ )
576 {
577 if( ++counter < numMulAn )
578 {
579 nt = npos+nneg+nzero;
580 if ( (nt>0) && (nt<=numSec) ) {
581 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
582 dum = (
pi/anpn)*nt*protmulAn[counter]*protnormAn[nt-1]/(2.0*n*n);
583 if (std::fabs(dum) < 1.0) {
584 if( test >= 1.0e-10 )excs += dum*test;
585 } else {
586 excs += dum*test;
587 }
588
589 if (ran < excs) goto outOfLoopAn;
590 }
591 }
592 }
593 }
594
595 inElastic = false;
596 return;
597 }
598 else
599 {
600 counter = -1;
601 for( npos=1; npos<numSec/3; npos++ )
602 {
603 nneg = npos+1;
604 for( nzero=0; nzero<numSec/3; nzero++ )
605 {
606 if( ++counter < numMulAn )
607 {
608 nt = npos+nneg+nzero;
609 if ( (nt>=1) && (nt<=numSec) ) {
610 test = std::exp(
Amin( expxu,
Amax( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
611 dum = (
pi/anpn)*nt*neutmulAn[counter]*neutnormAn[nt-1]/(2.0*n*n);
612 if (std::fabs(dum) < 1.0) {
613 if( test >= 1.0e-10 )excs += dum*test;
614 } else {
615 excs += dum*test;
616 }
617
618 if (ran < excs) goto outOfLoopAn;
619 }
620 }
621 }
622 }
623 inElastic = false;
624 return;
625 }
626 outOfLoopAn:
627 vecLen = 0;
628 }
629 }
630
631 nt = npos + nneg + nzero;
632 while ( nt > 0)
633 {
636 {
637 if( npos > 0 )
639 npos--;
640 }
641 }
642 else if ( ran < (
G4double)(npos+nneg)/nt)
643 {
644 if( nneg > 0 )
645 {
647 nneg--;
648 }
649 }
650 else
651 {
652 if( nzero > 0 )
653 {
655 nzero--;
656 }
657 }
658 nt = npos + nneg + nzero;
659 }
661 {
662 G4cout <<
"Particles produced: " ;
665 for (i=2; i < vecLen; i++)
666 {
668 }
670 }
671 return;
672 }
G4double pmltpc(G4int np, G4int nm, G4int nz, G4int n, G4double b, G4double c)
G4double Amin(G4double a, G4double b)
G4int Imin(G4int a, G4int b)
G4double Amax(G4double a, G4double b)
G4int Imax(G4int a, G4int b)
G4double getTotalMomentum() const