Ignore:
Timestamp:
Nov 5, 2010, 3:45:55 PM (15 years ago)
Author:
garnier
Message:

update ti head

Location:
trunk/source/processes/hadronic/models/cascade
Files:
131 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/processes/hadronic/models/cascade/History

    r1337 r1340  
    1 $Id: History,v 1.91 2010/06/11 17:07:23 mkelsey Exp $
     1$Id: History,v 1.203 2010/10/22 20:41:05 mkelsey Exp $
    22-------------------------------------------------------------------
    33
     
    1616     ---------------------------------------------------------------
    1717
    18 11 June 2010 Michael Keley (hadr-casc-V09-03-43)
    19 ------------------------------------------------
     1822 October 2010 Michael Kelsey (hadr-casc-V09-03-84)
     19----------------------------------------------------
     20- G4WatcherGun.cc: Change first numeric argument to G4NuclWatcher to int.
     21
     22NOTE:  Only this change is include in tag.
     23
     2420 October 2010 Michael Kelsey (kelsey-20101020b)
     25-------------------------------------------------
     26- G4NucleiModel:  Add scaling factors ("units") for nuclear radii and
     27  cross-sections, in order to adapt calculations to the literature.
     28
     2920 October 2010 Michael Kelsey (kelsey-20101020a)
     30-------------------------------------------------
     31- G4NucleiModel:  Re-activate changes in worthToPropagate() to use existing
     32  nuclear potential values for kaons and hyperons to decide on trapping.
     33
     3420 October 2010 Michael Kelsey (kelsey-20101020)
     35------------------------------------------------
     36- G4NucleiModel:  Clean up some bugs in refactoring generateModel().  Back
     37  out changes (28 Sep) in worthToPropagate() in order to compare refactored
     38  to production code.
     39
     4020 October 2010 Michael Kelsey (hadr-casc-V09-03-83)
     41----------------------------------------------------
     42- G4CascadParticle.cc:  Remove debugging output left in by accident.
     43
     44NOTE:  Tag does not include reorganization of G4NucleiModel (5 Oct 2010)
     45
     4619 October 2010 Michael Kelsey
     47------------------------------
     48G4FissionStore, G4FissionConfiguration: Undo migration to integer A and Z.
     49
     5019 October 2010 Michael Kelsey
     51------------------------------
     52Clean up CoVerity software analysis reports (three are ignored from obsolete
     53code):
     54        G4Analyser.cc
     55        G4CascadeCheckBalance.cc
     56        G4CascadeInterpolator.icc
     57        G4CascadeSampler.icc
     58        G4CollisionOutput.cc
     59        G4ElementaryParticleCollider.cc
     60        G4InuclCollider.cc
     61        G4NuclWatcher.cc
     62        G4NucleiModel.hh,cc
     63        G4RegionModel.cc
     64
     6514 October 2010 Michael Kelsey
     66------------------------------
     67- G4NucleiModel.cc:  Fix misspelled "G4doulbe" -> G4double.
     68
     69Pick up several missed bits of the "integer A and Z migration," mostly in
     70test and diagnostic code:
     71
     72        G4Analyser.hh,cc
     73        G4FissionConfiguration.hh
     74        G4FissionStore.hh,cc
     75        G4NuclWatcher.hh,cc
     76
     7714 October 2010 Michael Kelsey (hadr-casc-V09-03-82)
     78----------------------------------------------------
     79- G4CascadParticle.cc:  Add protection in getPathToTheNextZone() so that d2
     80  is always computed non-negative.  Avoids 10^-5 FPEs.
     81
     8205 October 2010 Michael Kelsey
     83------------------------------
     84- G4NucleiModel:  Major reorganization of generateModel() code.
     85  1) Rename integration functions from "volNumInt[1]" to "zoneIntegralxxx"
     86     with "xxx" = "WoodsSaxon" or "Gaussian".
     87  2) Move hardwired constants out to static data members, give clear names.
     88  3) Split function into separate pieces to set binding energies, zone
     89     radii, volume/density values, and potential heights.
     90  4) Within new functions, simplify if-cascades where possible, eliminate
     91     duplicated code.
     92  5) Move std::vector<> buffers out to data members.
     93
     94  Also, modify worthToPropagate() to use non-nucleon potential heights to
     95  terminate propagation.  Previously, non-nucleons could never fail, as the
     96  "getFermiKinetic" always returned zero.
     97
     9828 September 2010 Michael Kelsey (hadr-casc-V09-03-81)
     99------------------------------------------------------
     100- G4BigBanger:  Missed some integer A/Z migrations, which caused a bus error
     101  in test47.
     102
     10326 September 2010 Michael Kelsey (hadr-casc-V09-03-80)
     104------------------------------------------------------
     105- G4VCascadeDeexcitation.hh:  NEW abstract base class for post-cascade
     106  processing.  Some common activities will be implemented here from the two
     107  actual modules.
     108
     109- G4CascadeDeexcitation, G4PreCompoundDeexcitation:  Use new base class
     110  above, reorganize code in collide() to use new deExcite(G4Fragment*) where
     111  appropriate.
     112
     113- G4InuclCascader.hh:  Reference new base class for de-excitation modules.
     114
     11525 September 2010 Michael Kelsey
     116--------------------------------
     117- G4CascadeColliderBase:  Add explosion(G4Fragment*) and explosion(A,Z,Eexc).
     118  Move implementation to latter, and write others as call-throughs.  Add
     119  Z==0 condition for explosion, regardless of A.
     120
     121- G4EquilibriumEvaporator.hh:  Remove explosion(G4InuclNuclei*), as
     122  unnecessary.  Existing explosion(A,Z,E) now overrides base class.
     123
     124- G4CollisionOutput:  Add function to process G4ReactionProducts from
     125  PreCompound.
     126
     127- G4PreCompoundDeexcitation.cc:  Move G4ReactionProducts loop to
     128  G4CollisionOutput.
     129
     13024 September 2010 Michael Kelsey
     131--------------------------------
     132- G4IntraNucleiCascader.cc:  Minor shuffle of post-cascade recoil checking,
     133  in preparation for moving fragment construction and processing away.
     134
     135- G4CollisionOutput.cc:  Replace names "TargetFragment*" and "NucleiFragment*"
     136  with "OutgoingNuclei" and "OutgoingNucleus" for consistency with
     137  "OutgoingParticles" names.  This affects the following source files, all
     138  of which are modified to match (using |sed|):
     139
     140        cascade/include/G4Analyser.hh
     141        cascade/include/G4CollisionOutput.hh
     142        cascade/src/G4Analyser.cc
     143        cascade/src/G4CascadeCheckBalance.cc
     144        cascade/src/G4CascadeDeexcitation.cc
     145        cascade/src/G4CascadeInterface.cc
     146        cascade/src/G4CollisionOutput.cc
     147        cascade/src/G4EquilibriumEvaporator.cc
     148        cascade/src/G4Fissioner.cc
     149        cascade/src/G4IntraNucleiCascader.cc
     150        cascade/src/G4InuclCollider.cc
     151        cascade/src/G4InuclEvaporation.cc
     152        cascade/src/G4NonEquilibriumEvaporator.cc
     153        cascade/src/G4PreCompoundDeexcitation.cc
     154
     155- G4CollisionOutput:  Add new G4Fragment data member, with get() and add()
     156  accessors.  This fragment is *not* used by setOnShell() or by any of the
     157  event-total calculations.  It will be filled by G4IntraNucleiCascader for
     158  use by de-excitation modules.  Include G4Fragment in diagnostic output if
     159  not empty.
     160
     161- G4CascadeRecoilMaker.cc:  Remove G4Fragment::SetExcitationEnergy() call.
     162
     163- G4InuclNuclei:  Add new constructor to create from G4Fragment input, and
     164  new makeG4Fragment() to spit out a G4Fragment.  Also provide a casting
     165  operator for the latter.
     166
     16724 September 2010 Michael Kelsey (hadr-casc-V09-03-79)
     168------------------------------------------------------
     169Fix numerous compilation warnings on Linux (not seen on MacOSX) left over
     170from migration to integer A and Z (-73 tag).
     171
     172        G4BigBanger.cc
     173        G4CascadeCheckBalance.hh
     174        G4CascadeColliderBase.cc
     175        G4CascadeRecoilMaker.cc
     176        G4EquilibriumEvaporator.hh,cc
     177        G4ExitonConfiguration.hh
     178        G4Fissioner.cc
     179        G4InuclCollider.cc
     180        G4NonEquilibriumEvaporator.cc
     181        G4NucleiModel.cc
     182
     183- G4PreCompoundDeexcitation.cc:  Drop "G4int" casts as no longer required.
     184
     18523 September 2010 Michael Kelsey (hadr-casc-V09-03-78)
     186------------------------------------------------------
     187- G4CascadeInterface, G4InuclCollider:  change user selection function name
     188  to usePreCompoundDeexcitation(), per Julia Yarba.
     189
     190- G4PreCompoundCascadeInterface.hh,.cc, G4PreCompountInuclCollider.hh,.cc:
     191  REMOVE THESE CLASSES.  These were copied and modified versions of the
     192  standard versions, in order to test the new pre-compound de-excitation.
     193  That has been integrated with runtime flags, so the parallel versions are
     194  not required.
     195
     19623 September 2010 Michael Kelsey
     197--------------------------------
     198- G4InuclElementaryParticle.cc:  Drop warning message when converting
     199  G4ParticleDefinition to type code.
     200
     201- G4CascadeInterface:  Add functions for user selection of which
     202  post-cascade module to use for de-excitation of the residual nucleus.
     203  These call through to the equivalent G4InuclCollider functions.
     204
     205- G4InuclCollider:  Add functions for user selection of which
     206  post-cascade module to use for de-excitation of the residual nucleus.
     207  These delete and re-instantiate the appropriate de-excitation "collider".
     208
     209- G4PreCompoundDeexcitation:  Remove convertFragment() function, remove
     210  pass-by-value std::vector<> from getDeExcitedFragments() (use data member
     211  instead).  Clean up some obsolete code usage.
     212
     213- G4CascadeRecoilMaker:  Change fragment-making interface:
     214  makeRecoilNuclei() now returns G4InuclNuclei* for standard Bertini colliders.
     215  makeRecoilFragment() returns G4Fragment* for external PreCompound models.
     216  addExcitonConfiguration() sets local copy of excitons, needed in order to
     217    call the individual G4Fragment->Setxxx() functions.
     218
     219- G4IntraNucleiCascader.cc:  Follow renaming RecoilMaker::makeRecoilNuclei(),
     220  use new addExcitonConfiguration().
     221
     222- G4CascadeRecoilMaker:  Change fragment-making interface:
     223  makeRecoilNuclei() now returns G4InuclNuclei*.
     224  makeRecoilFragment() returns G4Fragment*.
     225  addExcitonConfiguration() sets local copy of excitons, needed in order to
     226    call the individual G4Fragment->Setxxx() functions.
     227
     228- G4IntraNucleiCascader.cc:  Follow renaming RecoilMaker::makeRecoilNuclei(),
     229  use new addExcitonConfiguration().
     230
     23122 September 2010 Michael Kelsey
     232--------------------------------
     233- G4CascadeMomentum.hh:  This should have been removed from the package long
     234  ago.  Apologies for the oversight.
     235
     23622 September 2010 Julia Yarba
     237-----------------------------
     238Added 1st prototype of interface between Bartini cascade and PreCompound model
     239(post-cascade de-excitation).
     240
     241Changes only to:
     242/geant4/source/processes/hadronic/models/cascade/cascade
     243
     244New developments are those G4PreCompound* classes; the GNUmakefile adapted to
     245include necessary links.
     246
     247The PreComp wrapper is G4PreCompundDeexcitation class.
     248
     249The logic, loops, conditions, etc., in the event processing are the same as in
     250the "native" Bertini code. I actually copied it over from G4CascadeInterface,
     251and started from there.
     252
     253However, there're a few technical changes that I'd like to mention.
     254
     2551. G4PreCompoundInterface inherits directly from G4HadronicInteraction.
     256I felt that we'd not need G4VIntra..., because its only advantage is a pointer
     257(and related access methods) to G4VPreCompoundModel.
     258This has now moved to the de-excitation wrapper.
     259
     2602. In the Collider itself, I've made the data member to be
     261 G4CascadeColliderBase* theDeexcitation
     262This way, it can be transparently set to the native one or the PreComp one
     263(both inherit from G4CascadeColliderBase).
     264
     2653. There's a setDeExcitation(...) methond in the collider, and also in the interface
     266(which will pass it down to the collider).
     267
     26819 September 2010 Michael Kelsey (hadr-casc-V09-03-77)
     269------------------------------------------------------
     270- G4CascadeInterface.cc:  Bug fix to logic in retryInelasticNucleus()
     271
     27217 September 2010 Michael Kelsey (hadr-casc-V09-03-76)
     273------------------------------------------------------
     274- G4CascadeInterface:  Add support to pass nucleus projectiles into
     275  collider.  Not tested or guaranteed to work, but G4IntraNucleiCascader is
     276  supposed to deal with them.
     277
     27816 September 2010 Michael Kelsey
     279--------------------------------
     280- G4CascadeInterface:  Extensive reorganization, moving most
     281  functionality out of ApplyYourself and into small member functions.
     282  Complicated end-of-loop conditions encapsulated.  Data members made into
     283  pointers to hide dependences from outside world.
     284
     28516 September 2010 Michael Kelsey (hadr-casc-V09-03-75)
     286------------------------------------------------------
     287- G4CascadeInterface.cc:  Add parentheses in end-of-while block to fix
     288  compilation warning in GCC 4.3.
     289
     290- G4IntraNucleiCascader.cc:  In decayTrappedParticle(), check for photon
     291  daughters and put them directly onto output list.
     292
     29316 September 2010 Michael Kelsey
     294--------------------------------
     295- G4CascadParticle.hh:  Make getGeneration() const.
     296
     297- G4CascadeDeexcitation.hh:  Fix compiler warning about order of data members.
     298
     299- G4IntraNucleiCascader:  Intercept hyperons which are "trapped" in nuclear
     300  potential, and decay them immediately to produce usable secondaries.  This
     301  resolves problem with sub-MeV final-state hyperons (reported by A. Dotti),
     302  but is not entire correct.  Properly, the hyperon should be incorporated
     303  into a hypernucleus fragment.
     304
     305- G4InuclElementaryParticle.hh:  Add hyperon() identification function, and
     306  constructor to take G4DynamicParticle directly.
     307
     308- G4InuclParticle.hh, G4InuclNuclei.hh:  Add constructor to take
     309  G4DynamicParticle directly.
     310
     31115 September 2010 Michael Kelsey (hadr-casc-V09-03-74)
     312------------------------------------------------------
     313- G4CascadeDeexcitation:  NEW collider to handle post-cascade processing of
     314  nuclear fragment.  Encapsulates BigBanger and Evaporators.  Eventually
     315  will have alternative (configurable or #ifdef) implementation using G4
     316  external "pre-compound" models instead of Bertini factories.
     317
     318- G4InuclCollider:  Remove post-cascade colliders (BigBanger, Evaporators),
     319  replace with new G4CascadeDeexcitation.
     320
     321- G4LorentzConverter:  Move construtor implementations to .cc file, and make
     322  sure all constructors have initializers for all data members.
     323
     32414 September 2010 Michael Kelsey (hadr-casc-V09-03-73)
     325------------------------------------------------------
     326Migrate to integer A and Z values for nuclear configurations.  Includes both
     327explicit arguments for G4InuclNuclei, and function arguments, computational
     328parameters involved in nuclear configurations, breakup, etc.
     329
     330        G4CascadeCheckBalance.cc
     331        G4CascadeInterface.cc
     332        G4CascadeRecoilMaker.hh
     333        G4Fissioner.hh,cc
     334        G4InuclEvaporation.cc
     335        G4InuclNuclei.hh,cc
     336        G4InuclSpecialFunctions.hh
     337        G4NonEquilibriumEvaporator.hh,cc
     338        G4NucleiModel.hh,cc
     339        G4PreCompoundCascadeInterface.cc
     340        bindingEnergy.cc
     341        bindingEnergyAsymptotic.cc
     342        nuclearLevelDensity.cc
     343        paraMaker.cc
     344
     345- G4InuclSpecialFunctions.hh:  Eliminate bindingEnergy functions which are
     346  no longer used, along with their .cc files:
     347
     348        bindingEnergyKummel
     349        bindingEnergyExact
     350
     351Migration validated using 100 events (20 GeV pi+ on lead) with verbose==4.
     352Entire log files (9.6M lines, 433 MB) identical before and after migration.
     353
     35413 September 2010 Michael Kelsey
     355--------------------------------
     356- G4InuclElementaryParticle:  Move printParticle() implementation to .cc,
     357  and add printing of particle name to output.
     358
     359- G4InuclNuclei.cc:  Move base-class printing to first line of output, to
     360  match G4InuclEP.
     361
     36210 September 2010 Michael Kelsey (hadr-casc-V09-03-72)
     363------------------------------------------------------
     364- G4CascadeRecoilMaker:  Add new goodNucleus() function with functionality
     365  from G4IntraNucleiCascader::goodCase().  Add parameter to set "rounding
     366  tolerance" for small/negative mass differences.  Drop getRecoilFragment()
     367  in favor of user calling makeRecoilFragment() directly (instead of doing
     368  it collide()), which returns a non-const pointer.
     369
     370- G4IntraNucleiCascader: Remove previously introduced getResidualMass() and
     371  makeResidualFragment() functions, along with G4InuclNuclei object.
     372  Replace with new RecoilMaker utility.  Move goodCase() to RecoilMaker, and
     373  begin to simplify end-of-cascade processing.
     374
     375- G4ExitonConfiguration.hh:  Add function to reset values to zero.
     376
     377- G4InuclNuclei:  Add function to zero out exciton configuration, and use
     378  it in fill() functions.
     379
     3809 September 2010 Michael Kelsey
     381-------------------------------
     382- G4CascadeCheckBalance:  Add new collide() interface to take lists of both
     383  G4InuclElementaryParticles and G4CascadParticles; supports use by
     384  G4IntraNucleiCascader and G4CascadeRecoilMaker.
     385
     386- G4CascadeRecoilMaker:  NEW pseudo-Collider class to compute the nuclear
     387  recoil kinematics of a cascade, either in process or completed.  To be
     388  used by G4IntraNucleiCascader; uses G4CascadeCheckBalance to do work.
     389
     3906 September 2010 Michael Kelsey (hadr-casc-V09-03-71)
     391-----------------------------------------------------
     392- G4NucleiModel:  Add protections in generateInteractionPartners() so that
     393  nucleon and quasideuteron interactions are only selected if there are
     394  "enough" nucleons of the necessary type still available (xxxNumberCurrent).
     395
     396- G4InuclNuclei:  Add fill() functions which overwrite the entire particle
     397  structure, with same argument lists as constructors.  Will be used mainly
     398  by G4IntraNucleiCascader::makeResidualFragment().
     399
     400- G4IntraNucleiCascader:  Hide non-physical nucleus message behind verbose
     401  flag.  Add function and data member to build recoil nucleus (fragment) at
     402  end of every iteration; will eventually replace functionality of
     403  getResidualMass().
     404
     4052 September 2010 Michael Kelsey (hadr-casc-V09-03-70)
     406-----------------------------------------------------
     407- G4NucleiModel.cc:  Restore hadr-casc-V09-03-68 revision 1.71, and remove
     408  the two resize(3) actions.
     409
     410NOTE:  The exercise below has (finally) resolve the cross-section
     411discrepancy reported by Sunanda Banerjee back in July.  It turns out that my
     412use of "resize(3)" to pre-allocate the qdeutron and acsec buffers on each
     413interaction was incorrect.  This doesn't just reserve memory, it fills the
     414vectors with three elements, so that subsequent push_back()'s fill [3], [4],
     415etc.
     416
     4172 September 2010 Michael Kelsey
     418-------------------------------
     419- G4NucleiModel.cc: Reverted to hadr-casc-V09-03-38 revision 1.45, and
     420  interface changes incorporated.  See NOTE below from 28 July 2010.
     421  Cross-section changes have not been resolved or validated.  Since -38
     422  revision has better data/MC matching (ratio near 1), it is restored as the
     423  baseline version, and changes will be re-done incrementally.
     424
     425  Each increment after (0) is tagged "kelsey-20100902x", x=a,b,c,d etc.
     426
     427        0)  Implement new ctor and generateModel() calls
     428            Make cross-section tables statically initialized
     429            Include absorptionCrossSection definition
     430        1)  Use lookup tables for cross-sections, and new interpolator
     431            Change CHC_CHECK to G4CASCADE_DEBUG_CHARGE
     432        2)  Use this package's bindingEnergy() function
     433        3)  Update diagnostic messages and verbosity levels;
     434            Add missing initializers to all constructors;
     435            Use data-member buffer for G4CollisionOutput
     436        4)  Use generateWithRandomAngles() everywhere appropriate;
     437            Collapse if-cascades to use if-return where possible
     438        5)  Make generateModel() re-usable with data-member buffers
     439        6)  Energy-momentum conservation checking;
     440            Implement generateNucleonMomentum;
     441            Remove extraneous semicolons and blank lines
     442        7)  Use local variables in passFermi();
     443            Fix some minor LorentzVector calculations;
     444            Use generateNucleonMomentum() for quasi-deuterons
     445        8)  Use data-member buffers for quasideuterons, coords, mom.
     446        9)  Use enum labels for quasideuteron codes
     447        10) Restore Dennis' improved potential (6-zone) calculations
     448
     4494 August 2010 Michael Kelsey (hadr-casc-V09-03-69)
     450--------------------------------------------------
     451- G4CascadeData:  Add name data member and optional ctor argument, use
     452  when printing tables.
     453
     454- G4CascadeFunctions.icc:  Pretty-up printing output using name string.
     455
     456- G4Cascade*Channel.cc:  Add name string to data() ctor, use central part of
     457  class name, e.g., "PiMinusP" for G4CascadePiMinusPChannel.
     458
     459- G4ElementaryParticleCollider.cc:  Add printing of all final-state tables,
     460  one time only, protected by G4CASCADE_DEBUG_SAMPLER.
     461
     462- GNUmakefile:  Add G4CASCADE_DEBUG_SAMPLER preprocessor flag.
     463
     4643 August 2010 Michael Kelsey (hadr-casc-V09-03-68)
     465--------------------------------------------------
     466- G4CascadeData.hh: Add print() and printXsec() functions to dump tables.
     467- G4CascadeData.icc:  Move implementations out of G4CascadeData.hh file.
     468
     469- G4CascadeFunctions.hh,icc: Add printTable() to dump tables.
     470
     471- G4CascadeInterpolator.hh,icc: Add printBins() to dump energy bin edges.
     472
     473- G4CascadeSampler.hh,icc: Add print() to call through to interpolator.
     474
     475NOTE:  This should be the last set of functional changes for a while.
     476Sunanda Bannerjee reported substantial changes in validation plots for the
     477Bertini cascade between 4.9.3-ref-05 (hadr-casc-V09-03-23-01) and
     4784.9.3-ref-06/4.9.4-beta-01 (hadr-casc-V09-03-43).
     479
     48028 July 2010 Michael Kelsey (hadr-casc-V09-03-67)
     481-------------------------------------------------
     482- G4NucleiModel.cc:  Set deuteron arrays to fixed length (3).  Add A/Z
     483  values to generateModel diagnostic message.
     484
     485- G4EquilibriumEvaporator.cc:  Change some fixed length std::vector<> to
     486  simple C arrays.
     487
     488- G4Fissioner.cc:  Move G4FissionStore to class data member for reuse.
     489
     490- G4FissionStore:  Add ::clear() function to support reuse, move addConfig()
     491  implementation to .cc file.
     492
     493- G4IntraNucleiCascader:  Move G4NucleiModel to class-level data member
     494  (pointer) so it can be reused across collisions.
     495
     49626 July 2010 Michael Kelsey
     497---------------------------
     498- G4Analyzer.cc:  Use const-refs for particle lists.
     499
     500- G4BigBanger, G4ElementaryParticleCollider:  Move std::vector<> buffers to
     501  .hh file to allow reuse.
     502
     503- G4NucleiModel.cc:  Simplify buffers used in generateModel() to reduce
     504  G4double allocations.
     505
     50623 July 2010 Michael Kelsey (hadr-casc-V09-03-66)
     507-------------------------------------------------
     508- G4CascadeInterface:  Move G4CollisionOutput to .hh file for reuse between
     509  events.
     510
     511- G4IntraNucleiCascader:  Move buffers for cascade output to .hh file, so
     512  they can be reused between events.
     513
     514- G4NucleiModel:  Move G4CollisionOutput to .hh file for reuse; use
     515  references for bullet and target args to G4EPCollider.
     516
     51721 July 2010 Michael Kelsey (hadr-casc-V09-03-65)
     518-------------------------------------------------
     519- GNUmakefile:  Add new G4CASCADE_CHECK_ECONS to turn off all of the
     520  internal conservation checks (reduce std::vector<> memory churn!).
     521
     522- G4CascadeColliderBase.cc:  Use G4CASCADE_CHECK_ECONS to set the default
     523  value of "doConservationChecks": true if defined, false if not defined.
     524  This is done with #ifdef-else-endif block, NOT some fancy macro.
     525
     526- G4CascadeInterface.cc:  Use G4CASCADE_SKIP_ECONS to toggle reporting
     527  violations before end of loop (don't need to call balance.okay() twice!).
     528
     529- G4ElementaryParticleCollider.cc:  Put verbosity check before call to
     530  validateOutput() to avoid unnecessary vector manipulations.
     531
     532- G4IntraNucleiCascader.cc:  Set doConservationChecks = true
     533  unconditionally; used to reject bad cascades.
     534
     535- G4NucleiModel.cc:  Use G4CASCADE_CHECK_ECONS to hide balance.collide().
     536
     53720 July 2010 Michael Kelsey (hadr-casc-V09-03-64)
     538-------------------------------------------------
     539- G4CascadeColliderBase: Make G4CascadeCheckBalance a pointer member, move
     540  ctor and dtor to .cc file.  Change balance tolerances to 1 per mil and 1
     541  MeV.
     542
     543- G4InuclCollder:  Make all colliders pointer members.
     544
     545- G4IntraNucleiCascader:  Make EPCollider a pointer member, and call
     546  G4CollisionOutput::setOnShell() to balance energy-momentum for null fragments.
     547
     548- G4InuclNuclei.cc:  Preserve momentum magnitude when setting excitation
     549  energy by setting mass and kinetic energy.
     550
     55119 July 2010 Michael Kelsey (hadr-casc-V09-03-63)
     552-------------------------------------------------
     553- G4CascadeCheckBalance.cc:  Change zero-tolerance to 10 keV (1e-5) from
     554  1 keV (1e-6).
     555
     556- G4CollisionOutput.hh:  Fix capitalization of "numberOfOutgoingParticles".
     557
     558- G4EquilibriumEvaporator.cc:  Remove duplicate EEXS setting.
     559
     560- G4InuclNuclei:  Change implementation of setExitationEnergy() to adjust
     561  mass while keeping momentum vector constant.  Currently done with
     562  "expensive" LorentzVector manipuation.  Should be done by recomputing
     563  kinetic energy given new mass value.
     564
     565- G4NonEquilibriumEvaporator.cc:  Modify particle-creation block to work as
     566  G4EquilibriumEvaporator now does.  Simplify some if-blocks.
     567
     56816 July 2010 Michael Kelsey (hadr-casc-V09-03-62)
     569-------------------------------------------------
     570- G4CollisionOutput:  Add interfaces to handle G4CascadParticles.
     571
     572- G4IntraNucleiCascader:  Eliminate local "inter_case" data member and
     573  function.  Use base class G4InteractionCase directly.  Add functionality
     574  to test for conservation and recoil before exiting "itry" loop, and redo
     575  cascade if unbalanced recoil fragment.
     576
     577- G4{PreCompound}InuclCollider.cc:  Drop "setInteractionCase()" function.
     578
     57915 July 2010 Michael Kelsey (hadr-casc-V09-03-61)
     580-------------------------------------------------
     581- G4CollisionOutput:  New ::add() function to combine two objects.  New
     582  accessors to get total charge and baryon number.
     583
     584- G4CascadeCheckBalance:  Make tempOutput data member, for thread-safety,
     585  rather than static variables.  Use new G4CollisionOutput accessors.
     586
     587- G4IntraNucleiCascader.cc:  Move local output buffers outside while loop,
     588  use std::vector<>::insert() for copying.
     589
     590- G4InuclCollider.cc:  Use new G4CollisionOutput::add() interface.
     591
     592- G4NucleiModel.cc:  Hide conservation checks behind verbose>2.  Otherwise
     593  log files get too big
     594
     59515 July 2010 Michael Kelsey (hadr-casc-V09-03-60)
     596-------------------------------------------------
     597- G4CascadeCheckBalance:  Add layer of protection in relativeX() (check
     598  initial values) to avoid divide-by-zero errors.  Add another interface to
     599  accept list of G4CascadParticles, for use with G4NucleiModel.  Add check
     600  of momentum direction balance, not just magnitudes.
     601
     602- G4IntraNucleiCascader.cc:  Rearrange end-of-loop if-blocks to allow for
     603  conservation checking prior to return.  Add reporting of both too-low and
     604  too-high residual energy (at verbose=2) for single-nucleon fragments.
     605
     606- G4InuclCollider.cc:  Remove re-named conservation checks, now all done by
     607  colliders themselves.
     608
     609- G4InuclParticle.hh:  Add setKineticEnergy() function to simplify handling
     610  of some kinematics.
     611
     612- G4NucleiModel:  Add G4InuclNuclei data member (created in generateModel()),
     613  for use with conservation checks.  Do check at end of generateParticleFate().
     614
     61515 July 2010 Michael Kelsey (hadr-casc-V09-03-59)
     616-------------------------------------------------
     617- G4InuclNuclei:  Use G4DynamicParticle::theDynamicalMass to carry around
     618  excitation energy (== theDynamicalMass-thePDGMass).  This allows
     619  excitation to be changed on the fly, with all kinematics handled
     620  correctly.  It also allows ONLY the ground state nucleus to be created as
     621  a G4Ions object (whether global or private), reducing the number of such
     622  objects by a factor of thousands.
     623
     62414 July 2010 Michael Kelsey (hadr-casc-V09-03-58)
     625-------------------------------------------------
     626- G4CollisionOutput.cc:  For initial four-momentum adjustment, skip over
     627  particles which would acquire negative energy after "correction."
     628
     629- G4ElementaryParticleCollider.cc: Bug fix for two-body final states.
     630  Kinematics should not require "rescaling."  That was driven by states
     631  which were kinematically forbidden, with m1+m2 > etot_scm (e.g., pi0 p ->
     632  pi+ n with just 5 MeV kinetic energy).  Now those states are caught and
     633  rejected.
     634
     635- G4CascadeInterface.cc, G4InuclCollider.cc:  Improve diagnostics reporting
     636  number of retries.
     637
     638- G4EquilibriumEvaporator.cc:  When computing residual excitation
     639  (EEXS_new), original thrown energy, S, should be used, not reboosted
     640  particle after recoil.  Simplify evaporation kinematics to conserve
     641  four-momentum automatically (PEX -= mom).
     642
     64314 July 2010 Michael Kelsey (hadr-casc-V09-03-57)
     644-------------------------------------------------
     645- G4CascadeColliderBase: New subclass of G4VCascadeCollider, which takes
     646  over all of its concrete functionality, and adds conservation checker
     647  (G4CascadeCheckBalance) as data member.  Wrapper functions and control
     648  flag allow colliders to user it transparently.
     649
     650- G4VCascadeCollider:  Move concrete functionality to new base class.
     651
     652- All colliders:  Change base class to new G4CascadeColliderBase.  Remove
     653  local copies of conservation-checker, using new base function instead.
     654
     655        cascade/include/G4BigBanger.hh
     656        cascade/include/G4ElementaryParticleCollider.hh
     657        cascade/include/G4EquilibriumEvaporator.hh
     658        cascade/include/G4EvaporationInuclCollider.hh
     659        cascade/include/G4Fissioner.hh
     660        cascade/include/G4IntraNucleiCascader.hh
     661        cascade/include/G4InuclCollider.hh
     662        cascade/include/G4NonEquilibriumEvaporator.hh
     663        cascade/include/G4PreCompoundInuclCollider.hh
     664        cascade/src/G4BigBanger.cc
     665        cascade/src/G4ElementaryParticleCollider.cc
     666        cascade/src/G4EquilibriumEvaporator.cc
     667        cascade/src/G4EvaporationInuclCollider.cc
     668        cascade/src/G4Fissioner.cc
     669        cascade/src/G4IntraNucleiCascader.cc
     670        cascade/src/G4InuclCollider.cc
     671        cascade/src/G4NonEquilibriumEvaporator.cc
     672        cascade/src/G4PreCompoundInuclCollider.cc
     673
     674- G4EquilibriumEvaporator:  Use new functionality (above) to turn off
     675  conservation checks when evaporating fission products.
     676
     677- G4CascadeInterface.cc:  Report number of retries in verbose messages.
     678
     679- G4IntraNucleiCascader.cc:  Remove sanity check on afin/zfin vs. model.
     680
     68113 July 2010 Michael Kelsey (hadr-casc-V09-03-56)
     682-------------------------------------------------
     683- G4CascadeCheckBalance:  Add zero protection (needed for momentum ratio)
     684  using a static tolerance parameter.
     685
     686- G4EquilibriumEvaporator.cc:  Add dumping of G4CollisionOutput before exit,
     687  some fixes for "PEX" adjustments as EEXS changes.
     688
     689- G4NonEquilibriumEvaporator.cc:  Add conservation checking, dump of output,
     690  some fixes for "PEX" adjustments as EEXS changes.
     691
     692- G4Fissioner.cc:  Add conservation checking, remove addition of excitation
     693  energy to input nucleus mass, since already included.
     694
     69513 July 2010 Michael Kelsey
     696---------------------------
     697- G4CascadeCheckBalance.cc:  Hide violation reports behind verbose == 1.
     698
     699- G4ElementaryParticleCollider.cc:  Bump ::collide() message to verbose > 1.
     700
     701- G4EquilibriumEvaporator.cc:  Add conservation checking, collapse if-cascades
     702  by doing failure tests and exits up front, add sanity check on eex_real.
     703
     704- G4IntraNucleiCascader.cc:  Add diagnostic messages and some FIXME
     705  comments, validate afin/zfin against G4NucleiModel result.
     706
     707- G4InuclCollider.cc:  Move conservation check outside verbosity flag.  This
     708  adds to CPU usage, so may need #ifdef protection later.  Adjust a few
     709  verbosity levels.
     710
     711- G4LorentzConvertor.cc:  Bump all diagnostic messages to verbose > 2.
     712
     713- G4NucleiModel.cc:  Simplify main if-block to put failure up front; add
     714  debugging messages when decrementing proton or neutron counts.
     715
     71611 July 2010 Michael Kelsey
     717---------------------------
     718- G4CascadeCheckBalance:  Add ctor argument with name of parent class; use
     719  this name when reporting results.  Add interface for nuclear fragment
     720  list.  Allow parent class name to be changed dynamically.
     721
     722- G4BigBanger.cc, G4CascadeInterface.cc, G4ElementaryParticleCollider.cc,
     723  G4InuclCollider.cc, G4NucleiModel.cc:  Pass name to G4CascadeCheckBalance.
     724
     725- G4Fissioner.cc:  Use G4CascadeCheckBalance to test energy conservation.
     726
     727- G4InuclNuclei.hh:  Add model ID as optional ctor argument.
     728
     729- G4InuclCollider.cc:  Move balance checks on evaporators outside verbosity.
     730  Adjust name of G4CascadeCheckBalance for clear reporting.
     731
     732- G4VCascadeCollider.hh:  Add protected function to change name dynamically.
     733
     7346 July 2010 Dennis Wright (hadr-casc-V09-03-55)
     735-----------------------------------------------
     736- G4IntraNucleiCascader.cc: add to final particle list those cascade
     737  particles which were formerly abandoned at cascade termination;
     738- G4IntraNucleiCascader.cc: allow meson excitons to pass out of nucleus
     739  since they are not proper excitons, and would be lost otherwise
     740 
     7414 July 2010 Dennis Wright (hadr-casc-V09-03-54)
     742-----------------------------------------------
     743- tag changes up to now
     744
     7452 July 2010 Michael Kelsey
     746--------------------------
     747- G4BigBanger.cc:  Moving "generateMomentumModules()" inside loop.  For
     748  three-body decays, the angles are not ajustable (so always fails).
     749
     750- G4CascadeInterface.cc:  Set verbosity on G4CollisionOutput.
     751
     752- G4EquilibriumEvaporator.cc:  Simplify if-cascades to reduce nesting (test
     753  for errors and exit up front, rather than in else-blocks).
     754
     755- G4InuclCollider.cc:  Set verbosity on G4CollisionOutput.
     756
     757- G4IntraNucleiCascader.cc:  Throw away casacde which leaves "negative energy
     758  recoil" (i.e. rest-frame energy of recoil less than mass of nucleus or
     759  nucleon).
     760
     7611 July 2010 Michael Kelsey
     762--------------------------
     763- G4InuclCollider.cc:  Used wrong input target for conservation-law checking
     764  subsequent to G4EquilibriumEvaporator.
     765
     766- G4EquilibriumEvaporator.cc, G4NonEquilibriumEvaporator.cc:  Handle
     767  excitation energy differently with new G4InuclNuclei interface.  Compute
     768  updated values correctly, by taking nuclear mass difference then
     769  subtracting energy of evaporated particle.
     770
     771- G4InuclNuclei:  Reorganization to properly incorporate excited states.
     772  Excitation energy included in mass in all cases.  setExcitationEnergy() now
     773  replaces G4PartDefn pointer with new excited state.  getNucleiMass() takes
     774  (optional) excitation, calls G4NucleiProperties to get mass value.  For
     775  weird fragments, multiple isomers allowed, assigned unique non-standard
     776  PDG codes.  Include particle name in printout (now in .cc file).
     777
     778- G4CollisionOutput.cc:  Do not include nuclear excitation energy in output
     779  sum; now included with nuclear mass automatically (and properly).
     780
     781- G4CascadeCheckBalance.cc:  Do not include nucler excitation energy in input
     782  sum; now inluded with nuclear mass automatically (and properly).
     783
     784- G4IntraNucleiCascader.cc:  For recoil nuclear fragments, treat excitation
     785  energy properly: compute as difference between recoil "mass" (recoil-frame
     786  energy) and ground-state A/Z mass, and pass into G4InuclNuclei ctor.
     787  After the cascade, add some recoil energy checks to deal with both
     788  floating-point round-off, and quasi-elastic scatters (which change the
     789  bullet direction, and leave the nucleus with "missing" energy).
     790
     791- G4BigBanger.cc:  Simplify boost to "target" nucleus, using "boostVector"
     792  instead of G4LorentzConvertor machinery.
     793
     79430 June 2010 Michael Kelsey
     795---------------------------
     796- G4BigBanger.cc:  Improve handling of excitation energy as part of nuclear
     797  mass, deal with two-body explosion properly (x=0.5, not random).  Some
     798  tweaks to diagnostic messages.
     799
     800- G4CascadeCheckBalance:  Add excitation energy to total energy for bullet
     801  and target nuclei.  This is done in G4CollisionOutput for secondaries.  It
     802  is NOT relativistically correct (should add to mass, not energy), but is
     803  consistent.
     804
     805- G4CollisionOutput.cc:  Use "getExitationEnergyInGeV()" instead of "0.001*".
     806
     807- G4IntraNucleiCascader.cc:  More diagnostic messages, improve the afin/zfin
     808  sanity check by requiring A>=Z.
     809
     81028 June 2010 Michael Kelsey
     811---------------------------
     812- G4CascadeCheckBalance:  Report violations on G4cerr always, regardless
     813  of verbosity level.  Add collide(...,<vector>) interface to allow use
     814  from within G4ElementaryParticleCollider.
     815
     816- G4ElementaryParticleCollider.cc:  Add conservation checks within ::collide().
     817
     818- G4IntraNucleiCascader.cc:  Add more diagnostic messages.  Test for
     819  negative values of afin, zfin, and try again.  Set round-off limit (1e-6),
     820  and test nuclear recoil energy for bound (setting to zero) before doing
     821  energy-violation test.
     822
     823- G4InuclNuclei.cc:  Abort job if passed negative Z or A argument.
     824
     82528 June 2010 Michael Kelsey
     826---------------------------
     827- G4BigBanger.cc:  Missed one instance of GetBindingEnergy().
     828
     82926 June 2010 Dennis Wright
     830--------------------------
     831- G4InuclNuclei:  Fix bug in calculation of PDG code.
     832
     83325 June 2010 Michael Kelsey (hadr-casc-V09-03-53)
     834-------------------------------------------------
     835- G4ElementaryParticleCollider.cc:  MAJOR BUG FIX:  Three different places
     836  in generating N-body momenta had incorrect "recoil" calculations.  The
     837  Nth four-vector was computed as simply -total, which produced negative
     838  energy states (obviously).  The correct calculation should have been
     839  N = G4LV(0,0,0,etot) - (total) in each instance.
     840
     84124 June 2010 Michael Kelsey (hadr-casc-V09-03-52)
     842-------------------------------------------------
     843- G4CascadeCheckBalance.cc:  Bug fixes to limit checks; should be using
     844  std::abs(), or negative violations don't get caught!  Also did some
     845  cleanup for compiler warnings see on Linux.
     846
     84723 June 2010 Michael Kelsey
     848---------------------------
     849- G4CascadeInterface.cc:  Fix infinite-loop bug with energy-violation; must
     850  check for (nTries>maxTries) outside parenthetical, with balance.okay()
     851  inside.  Do conservation checks all the time, not just with flag set.  If
     852  e-violation is "infinite loop", dump last generated event and abort job.
     853
     854- G4CascadeCheckBalance:  Add checks on baryon number, charge, and kinetic
     855  energy.  "Global" sanity check (::okay() function) does not include K.E.
     856
     85723 June 2010 Michael Kelsey (hadr-casc-V09-03-51)
     858-------------------------------------------------
     859- bindingEnergy.cc:  Replace entire function with call-through to
     860  G4NucleiProperties.  Copy test for valid A/Z from there, and return
     861  0. directly on failure; suppresses warning message in 9.4-beta.
     862
     863- G4EquilibriumEvaporator.cc, G4Fissioner.cc, G4IntraNucleiCascader.cc
     864  G4InuclNuclei.cc, G4NonEquilibriumEvaporator.cc, G4NucleiModel.cc
     865  G4VCascadeCollider.cc:  Restore calls to local "bindingEnergy()" to
     866  get wrapper function above; suppresses warning messages in 9.4-beta.
     867
     868- G4NucleiModel.cc:  Make class re-usable (had been assumed in -47 tag, but
     869  was not true!), by clearing all parameter vectors in generateModel().
     870  Values of A,Z are tested first, and previous data kept if same nucleus is
     871  being modelled.
     872
     87323 June 2010 Michael Kelsey
     874---------------------------
     875- G4CascadeInterface.cc:  Minor fix to rationalize version jumpings.
     876- G4NucleiModel.cc:  Fix bug in partners list termination mods below, and
     877  remove reflection-recoil from boundaryTransition().
     878
     879
     88021 June 2010 Michael Kelsey (MHK-20100621)
     881------------------------------------------
     882- G4CascadeInterface.cc:  Bring MHK-20100620 version back to HEAD, make same
     883  parenthesis fix for GCC 4.5 compilation.
     884
     885- G4IntraNucleiCascader.cc:  Bug fix nuclear recoil kinematics introduced in
     886  MHK-20100620.
     887
     888- G4NucleiModel.cc:  Bring MHK-20100620 version back to HEAD, apply ctor
     889  argument fix.  Eliminate creating temporaries for terminal "partners" on
     890  list; default ctor will take care of it.  Hide negative path-length report
     891  behind verbose flag, and don't return an empty list.
     892
     893  Add block of code in ::boundaryTransition() which recoils the nucleus when
     894  the secondary is reflected off the potential, to balance the momentum
     895  transfer.  This is implemented by computing the boost for the full nucleus
     896  using the computed three-momentum transfer, and applying that boost to the
     897  secondary.
     898
     89923 June 2010 Michael Kelsey (hadr-casc-V09-03-50)
     900-------------------------------------------------
     901- G4IntraNucleiCascader.cc:  Restore G4NucleiModel as local data member.
     902  Not well designed for reuse.
     903
     90421 June 2010 Michael Kelsey (hadr-casc-V09-03-49)
     905-------------------------------------------------
     906NOTE:  Changes below were version jumped into V09-03-48.  Tag above ONLY
     907       includes these two changes!
     908
     909- G4CascadeInterface.cc:  Add parentheses in main iteration loop to support
     910  mixed && and || (reported by gcc-4.5).
     911
     912- G4NucleiModel.cc:  Fix mistake in passing ctor args to generateModel().
     913
     91420 June 2010 Michael Kelsey (MHK-20100620)
     915------------------------------------------
     916- G4CascadeCheckBalance:  New utility class to do energy and momentum
     917  conservation testing.  Implemented as a "collider" to resue interface.
     918
     919- G4CascadeInterface.cc:  Use new G4CascadeCheckBalance for energy
     920  conservation.
     921
     922- G4CollisionOutput:  Add setVerboseLevel() function, diagnostic reports in
     923  ::setOnShell(), and collapse if-cascades to use "if (!xxx) return" instead
     924  of multiple nestings.
     925
     926- G4ElementaryParticleCollider.cc: Collapse if-cascade to use "if (!xxx)
     927  return" instead of multiple nestings.
     928
     929- G4IntraNucleiCascader.cc:  Improve diagnostic messages, change some G4cout
     930  to G4cerr.
     931
     932- G4InuclCollider:  Make output buffers data members to reduce churn;
     933  simplify if-cascades to use "if (!xxx) return" instead of nesting; add
     934  energy-conservation checks at each stage of cascade.
     935
     936- G4NucleiModel.cc:  Improve diagnostics, collapse if-cascades to use "if
     937  (!xxx) return" instead of multiple nestings.
     938
     93918 June 2010 Michael Kelsey (hadr-casc-V09-03-48)
     940-------------------------------------------------
     941- G4CascadeInterface.cc:  Add check on energy conservation between initial
     942  and final states; more than 5% imbalance triggers repeat generation of
     943  cascade.  This check may be disabled with flag G4CASCADE_SKIP_ECONS.  Also
     944  did some minor cleanup of the code.
     945
     946- cascade/GNUmakefile:  Add support for new flag above.
     947
     94817 June 2010 Michael Kelsey (hadr-casc-V09-03-47)
     949-------------------------------------------------
     950- G4CascadeInterface, G4PreCompoundCascadeInterface:  Make G4InuclCollider a
     951  local data member, pass verbosity to it in ::ApplyYourself().
     952
     953- G4InuclCollider, G4ElementaryParticleCollider, G4IntraNucleiCascader,
     954  G4EquilibriumEvaporator, G4BigBanger: Make all sub-colliders local data
     955  members, pass verbosity to each of them.
     956
     957- G4NucleiModel:  Add ctors and generateModel() signatures so both can do
     958  particle or A/Z initialization.  Add setVerboseLevel() function.
     959
     96017 June 2010 Michael Kelsey (hadr-casc-V09-03-46)
     961-------------------------------------------------
     962- cascade/GNUmakefile: Add series of "ifneq (,...)" blocks to map
     963  environment variables for debugging onto "-D..." compiler flags:
     964
     965        G4CASCADE_COULOMB_DEV
     966        G4CASCADE_DEBUG_CHARGE
     967        G4CASCADE_DEBUG_INTERFACE
     968        G4CASCADE_DEBUG_SORT
     969        G4CASCADE_WATCHER_HIGHZ
     970
     971- G4CascadeInterface.cc: Replace preprocessor flags "debug_G4...Interface"
     972  with G4CASCADE_DEBUG_INTERFACE, and "BERTDEV" with G4CASCADE_COULOMB_DEV.
     973  Fix bug with information access in debugging block.
     974
     975- G4EquilibriumEvaporator.cc, G4IntraNucleiCascader.cc,
     976  G4NonEquilibriumEvaporator.cc:  Eliminate preprocessor flag RUN and all
     977  code contained in "#else" blocks.
     978
     979- G4LorentzConverter.cc:  Add diagnostic output with different levels:  All
     980  " >>>" entry messages done for verboseLevel >= 1; all numeric reports for
     981  verboseLevel > 2.
     982
     983- G4NucleiModel: Replace preprocessor flag "CHC_CHECK" with
     984  G4CASCADE_DEBUG_CHARGE.
     985
     986- G4PreCompoundCascadeInterface.cc: Replace preprocessor flag
     987  "debug_G4...Interface" with G4CASCADE_DEBUG_INTERFACE.  Fix bug with
     988  information access in debugging block.
     989
     990- G4WatcherGun.cc: Replace preprocessor flag "PB" with G4CASCADE_WATCHER_HIGHZ.
     991
     99216 June 2010 Michael Kelsey
     993---------------------------
     994- G4CascadeInterface.hh:  Add setVerboseLevel() function.
     995
     996- G4IntraNucleiCascader.cc:  Add reporting of momentum content for residual
     997  nuclear fragment, list of final-state particles, some cleanup of momentum
     998  balancing code.
     999
     1000- G4LorentzConvertor:  Add reporting of bullet and target four-vectors.
     1001
     1002- G4NucleiModel.cc:  Add diagnostic output for partner-list generation,
     1003  replace one random-angle code block with generateWithRandomAngles().
     1004
     100515 June 2010 Michael Kelsey (hadr-casc-V09-03-45)
     1006-------------------------------------------------
     1007- G4CascadeInterface.cc, G4PreCompoundCascadeInterface.cc:  When converting
     1008  output particles from K0/K0bar to K0S/K0L, convert kinetic energy from
     1009  Bertini internal units (GeV) to GEANT4 units (MeV).
     1010
     1011- G4VCascadeCollider:  Make two separate ctors, name and name+verbose, with
     1012  no default values.  All subclasses *must* provide a literal name string.
     1013
     101412 June 2010 Michael Kelsey (hadr-casc-V09-03-44)
     1015-------------------------------------------------
     1016- G4CascadeT33piNChannel.cc:  Swapped 8-body final state tables for pipP
     1017  vs. pimN.
     1018
     101911 June 2010 Michael Kelsey (hadr-casc-V09-03-43)
     1020-------------------------------------------------
    201021- G4CascadeData.hh:  Equally trivial fix for compiler warking on Intel ICC
    211022  for index[] array bounds in ::initialize().  Dimension array as [9], and
  • trunk/source/processes/hadronic/models/cascade/cascade/GNUmakefile

    r819 r1340  
    1 # $Id: GNUmakefile,v 1.9 2007/05/20 12:01:26 miheikki Exp $
     1# $Id: GNUmakefile,v 1.15 2010/09/23 05:02:14 mkelsey Exp $
    22# -----------------------------------------------------------
    33# GNUmakefile for hadronic library.  Gabriele Cosmo, 18/9/96.
     4#
     5# Map user environment/GMake variables onto preprocessor debugging flags
     6#
     7# 20100922 J. Yarba -- Add include directories for pre-compound model
    48# -----------------------------------------------------------
    59
    610name := G4hadronic_bert_cascade
    711
     12ifdef G4CASCADE_COULOMB_DEV
     13  CPPFLAGS += -DG4CASCADE_COULOMB_DEV=1
     14endif
     15
     16ifdef G4CASCADE_DEBUG_CHARGE
     17  CPPFLAGS += -DG4CASCADE_DEBUG_CHARGE=1
     18endif
     19
     20ifdef G4CASCADE_DEBUG_INTERFACE
     21  CPPFLAGS += -DG4CASCADE_DEBUG_INTERFACE=1
     22endif
     23
     24ifdef G4CASCADE_DEBUG_SAMPLER
     25  CPPFLAGS += -DG4CASCADE_DEBUG_SAMPLER=1
     26endif
     27
     28ifdef G4CASCADE_DEBUG_SORT
     29  CPPFLAGS += -DG4CASCADE_DEBUG_SORT=1
     30endif
     31
     32ifdef G4CASCADE_WATCHER_HIGHZ
     33  CPPFLAGS += -DG4CASCADE_WATCHER_HIGHZ=1
     34endif
     35
     36ifdef G4CASCADE_SKIP_ECONS
     37  CPPFLAGS += -DG4CASCADE_SKIP_ECONS=1
     38endif
     39
     40ifdef G4CASCADE_CHECK_ECONS
     41  CPPFLAGS += -DG4CASCADE_CHECK_ECONS=1
     42endif
     43
    844ifndef G4INSTALL
    945  G4INSTALL = ../../../../../..
    1046endif
    11 
    1247include $(G4INSTALL)/config/architecture.gmk
    1348
     
    2661            -I$(G4BASE)/processes/hadronic/models/management/include \
    2762            -I$(G4BASE)/processes/hadronic/models/util/include \
     63            -I$(G4BASE)/processes/hadronic/models/pre_equilibrium/exciton_model/include/ \
     64            -I$(G4BASE)/processes/hadronic/models/de_excitation/multifragmentation/include/ \
     65            -I$(G4BASE)/processes/hadronic/models/de_excitation/fermi_breakup/include/ \
     66            -I$(G4BASE)/processes/hadronic/models/de_excitation/photon_evaporation/include/ \
     67            -I$(G4BASE)/processes/hadronic/models/de_excitation/management/include/ \
    2868            -I$(G4BASE)/processes/hadronic/models/de_excitation/evaporation/include/ \
     69            -I$(G4BASE)/processes/hadronic/models/de_excitation/handler/include/ \
     70            -I$(G4BASE)/processes/hadronic/models/de_excitation/util/include/ \
    2971            -I$(G4BASE)/processes/hadronic/models/cascade/cascade/include \
    3072            -I$(G4BASE)/processes/hadronic/models/cascade/utils/include \
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4Analyser.hh

    r819 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4Analyser.hh,v 1.10 2010/10/14 20:55:10 mkelsey Exp $
    2526//
     27// 20101010  M. Kelsey -- Migrate to integer A and Z
     28
    2629#ifndef G4ANALYSER_HH
    2730#define G4ANALYSER_HH
     
    4346
    4447  G4Analyser();
    45   void setInelCsec(G4double csec,
    46                    G4bool withn);
     48  void setInelCsec(G4double csec, G4bool withn);
    4749  void setWatchers(const std::vector<G4NuclWatcher>& watchers);
    48   void try_watchers(G4double a,
    49                     G4double z,
    50                     G4bool if_nucl);
     50  void try_watchers(G4int a, G4int z, G4bool if_nucl);
    5151  void analyse(const G4CollisionOutput& output);
    5252  void printResults();
     
    6868  G4double averagePionKinEnergy;
    6969  G4double averageExitationEnergy;
    70   G4double averageNucleiFragments;
     70  G4double averageOutgoingNuclei;
    7171  G4double fissy_prob;
    7272  G4double averagePionPl;
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4BigBanger.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4BigBanger.hh,v 1.14 2010/06/25 09:41:48 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4BigBanger.hh,v 1.17 2010/09/28 20:15:00 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100315  M. Kelsey -- Remove "using" directive and unnecessary #includes.
     
    3232// 20100517  M. Kelsey -- Inherit from common base class
    3333// 20100519  M. Kelsey -- Get rid of proton and neutron masses as arguments!
     34// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     35// 20100726  M. Kelsey -- Move std::vector<> buffer to .hh file
     36// 20100928  M. Kelsey -- Migrate to integer A and Z
    3437
    3538#ifndef G4BIG_BANGER_HH
    3639#define G4BIG_BANGER_HH
    3740
    38 #include "G4VCascadeCollider.hh"
     41#include "G4CascadeColliderBase.hh"
    3942#include "G4InuclElementaryParticle.hh"
    4043#include <vector>
     
    4346
    4447
    45 class G4BigBanger : public G4VCascadeCollider {
     48class G4BigBanger : public G4CascadeColliderBase {
    4649public:
    4750  G4BigBanger();
     
    5255
    5356private:
    54   void generateBangInSCM(G4double etot, G4double a, G4double z);
     57  void generateBangInSCM(G4double etot, G4int a, G4int z);
    5558
    56   void generateMomentumModules(G4double etot, G4double a, G4double z);
     59  void generateMomentumModules(G4double etot, G4int a, G4int z);
    5760
    58   G4double xProbability(G4double x,
    59                         G4int ia) const;
     61  G4double xProbability(G4double x, G4int a) const;
    6062
    61   G4double maxProbability(G4double a) const;
     63  G4double maxProbability(G4int a) const;
    6264
    63   G4double generateX(G4int ia,
    64                      G4double a,
    65                      G4double promax) const;
     65  G4double generateX(G4int ia, G4double promax) const;
    6666
    6767  // Buffers for big-bang results
    6868  std::vector<G4InuclElementaryParticle> particles;
    6969  std::vector<G4double> momModules;
     70  std::vector<G4LorentzVector> scm_momentums;
    7071};       
    7172
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadParticle.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadParticle.hh,v 1.15 2010/06/25 09:41:50 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadParticle.hh,v 1.16 2010/09/16 05:21:00 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100112  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
    3030// 20100126  M. Kelsey -- Replace vector<G4Double> position with G4ThreeVector,
    3131//              move ::print() to .cc file, fix uninitialized data members
     32// 20100915  M. Kelsey -- Make getGeneration() const
    3233
    3334#ifndef G4CASCAD_PARTICLE_HH
     
    123124  void print() const;
    124125
    125   G4int getGeneration() {
     126  G4int getGeneration() const {
    126127    return generation;
    127128  }
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeChannel.hh,v 1.7 2010/06/25 09:41:52 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100514  M. Kelsey -- All functionality removed except quantum-number
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeData.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeData.hh,v 1.7 2010/06/25 09:41:54 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeData.hh,v 1.10 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Use template arguments to dimension const-refs
     
    3535// 20100611  M. Kelsey -- Work around Intel ICC compiler warning about
    3636//              index[] subscripts out of range.  Dimension to full [9].
     37// 20100803  M. Kelsey -- Add printing function for debugging, split
     38//              implementation code to .icc file.  Add name argument.
    3739
    3840#ifndef G4_CASCADE_DATA_HH
     
    4143#include "globals.hh"
    4244#include "G4CascadeSampler.hh"          /* To get number of energy bins */
     45#include "G4String.hh"
     46
    4347
    4448template <int NE,int N2,int N3,int N4,int N5,int N6,int N7,int N8=0,int N9=0>
     
    7276  static const G4int empty9bfs[1][9];
    7377
     78  const G4String name;                  // For diagnostic purposes
     79
    7480  G4int maxMultiplicity() const { return NM+1; }  // Used by G4CascadeFunctions
     81
     82  void print(G4int mult=-1) const;      // Dump multiplicty tables (-1 == all)
     83  void printXsec(const G4double (&xsec)[NE]) const;
    7584
    7685  // Constructor for kaon/hyperon channels, with multiplicity <= 7
     
    7887                const G4int (&the4bfs)[N4][4], const G4int (&the5bfs)[N5][5],
    7988                const G4int (&the6bfs)[N6][6], const G4int (&the7bfs)[N7][7],
    80                 const G4double (&xsec)[NXS][NE])
     89                const G4double (&xsec)[NXS][NE],
     90                const G4String& aName="G4CascadeData")
    8191    : x2bfs(the2bfs), x3bfs(the3bfs), x4bfs(the4bfs), x5bfs(the5bfs),
    8292      x6bfs(the6bfs), x7bfs(the7bfs), x8bfs(empty8bfs), x9bfs(empty9bfs),
    83       crossSections(xsec), tot(sum) { initialize(); }
     93      crossSections(xsec), tot(sum), name(aName) { initialize(); }
    8494
    8595  // Constructor for kaon/hyperon channels, with multiplicity <= 7 and inclusive
     
    8797                const G4int (&the4bfs)[N4][4], const G4int (&the5bfs)[N5][5],
    8898                const G4int (&the6bfs)[N6][6], const G4int (&the7bfs)[N7][7],
    89                 const G4double (&xsec)[NXS][NE], const G4double (&theTot)[NE])
     99                const G4double (&xsec)[NXS][NE], const G4double (&theTot)[NE],
     100                const G4String& aName="G4CascadeData")
    90101    : x2bfs(the2bfs), x3bfs(the3bfs), x4bfs(the4bfs), x5bfs(the5bfs),
    91102      x6bfs(the6bfs), x7bfs(the7bfs), x8bfs(empty8bfs), x9bfs(empty9bfs),
    92       crossSections(xsec), tot(theTot) { initialize(); }
     103      crossSections(xsec), tot(theTot), name(aName) { initialize(); }
    93104
    94105  // Constructor for pion/nuleon channels, with multiplicity > 7
     
    97108                const G4int (&the6bfs)[N6][6], const G4int (&the7bfs)[N7][7],
    98109                const G4int (&the8bfs)[N8D][8], const G4int (&the9bfs)[N9D][9],
    99                 const G4double (&xsec)[NXS][NE])
     110                const G4double (&xsec)[NXS][NE],
     111                const G4String& aName="G4CascadeData")
    100112    : x2bfs(the2bfs), x3bfs(the3bfs), x4bfs(the4bfs), x5bfs(the5bfs),
    101113      x6bfs(the6bfs), x7bfs(the7bfs), x8bfs(the8bfs), x9bfs(the9bfs),
    102       crossSections(xsec), tot(sum) { initialize(); }
     114      crossSections(xsec), tot(sum), name(aName) { initialize(); }
    103115
    104116  // Constructor for pion/nuleon channels, with multiplicity > 7 and inclusive
     
    107119                const G4int (&the6bfs)[N6][6], const G4int (&the7bfs)[N7][7],
    108120                const G4int (&the8bfs)[N8D][8], const G4int (&the9bfs)[N9D][9],
    109                 const G4double (&xsec)[NXS][NE], const G4double (&theTot)[NE])
     121                const G4double (&xsec)[NXS][NE], const G4double (&theTot)[NE],
     122                const G4String& aName="G4CascadeData")
    110123    : x2bfs(the2bfs), x3bfs(the3bfs), x4bfs(the4bfs), x5bfs(the5bfs),
    111124      x6bfs(the6bfs), x7bfs(the7bfs), x8bfs(the8bfs), x9bfs(the9bfs),
    112       crossSections(xsec), tot(theTot) { initialize(); }
     125      crossSections(xsec), tot(theTot), name(aName) { initialize(); }
     126
    113127  void initialize();                    // Fill summed arrays from input
    114128};
    115 
    116 template <int NE,int N2,int N3,int N4,int N5,int N6,int N7,int N8,int N9> inline
    117 void G4CascadeData<NE,N2,N3,N4,N5,N6,N7,N8,N9>::initialize() {
    118   // Initialize index offsets for cross-section array (can't do globally)
    119   index[0] = 0;   index[1] = N02; index[2] = N23; index[3] = N24;
    120   index[4] = N25; index[5] = N26; index[6] = N27; index[7] = N28;
    121   index[8] = N29;
    122 
    123   // Initialize multiplicity array
    124   for (G4int m = 0; m < NM; m++) {
    125     G4int start = index[m];
    126     G4int stop = index[m+1];
    127     for (G4int k = 0; k < NE; k++) {
    128       multiplicities[m][k] = 0.0;
    129       for (G4int i = start; i < stop; i++) {
    130         multiplicities[m][k] += crossSections[i][k];
    131       }
    132     }
    133   }
    134  
    135   // Initialize total cross section array
    136   for (G4int k = 0; k < NE; k++) {
    137     sum[k] = 0.0;
    138     for (G4int m = 0; m < NM; m++) {
    139       sum[k] += multiplicities[m][k];
    140     }
    141   }
    142 }
    143129
    144130// Dummy arrays for use when optional template arguments are skipped
     
    149135const G4int G4CascadeData<NE,N2,N3,N4,N5,N6,N7,N8,N9>::empty9bfs[1][9] = {{0}};
    150136
     137// GCC and other compilers require template implementations here
     138#include "G4CascadeData.icc"
     139
    151140#endif
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeFunctions.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4CascadeFunctions.hh,v 1.6 2010/06/25 09:41:56 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4CascadeFunctions.hh,v 1.7 2010/08/03 23:09:36 mkelsey Exp $
     26// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100407  M. Kelsey -- Return particle types std::vector<> by const ref,
     
    3837//              which Sampler is used.  Move implementations to .icc file.
    3938// 20100511  M. Kelsey -- Pass "kinds" buffer as input to getOutputPartTypes
     39// 20100803  M. Kelsey -- Add printing function for debugging
    4040
    4141#ifndef G4_CASCADE_FUNCTIONS_HH
     
    6363  getOutgoingParticleTypes(std::vector<G4int>& kinds, G4int mult, G4double ke);
    6464
     65  static void printTable();
     66
    6567private:
    6668  G4CascadeFunctions() : SAMP() {}
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeFunctions.icc

    r1337 r1340  
     1#ifndef G4_CASCADE_FUNCTIONS_ICC
     2#define G4_CASCADE_FUNCTIONS_ICC
    13//
    24// ********************************************************************
     
    2426// ********************************************************************
    2527//
    26 // $Id: G4CascadeFunctions.icc,v 1.3 2010/06/25 09:41:58 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     28// $Id: G4CascadeFunctions.icc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
     29// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2830//
    2931// 20100512  M. Kelsey -- Pass std::vector<> buffer as argument to
    3032//              getOutgoingPartTypes().
     33// 20100803  M. Kelsey -- Add printing function for debugging
     34// 20100804  M. Kelsey -- Pretty up printing function
    3135
    32 #ifndef G4_CASCADE_FUNCTIONS_ICC
    33 #define G4_CASCADE_FUNCTIONS_ICC
     36#include "G4CascadeFunctions.hh"
     37#include "globals.hh"
    3438
    3539
     
    5559
    5660
     61// Generate list of final state particles
     62
    5763template <class DATA, class SAMP> inline
    5864void G4CascadeFunctions<DATA,SAMP>::
     
    7581#endif
    7682
    77   // Identify final-state array to be copies
     83  // Identify final-state array to be copied
    7884  const G4int* chan = 0;
    7985  if (mult == 2) chan = DATA::data.x2bfs[channel];
     
    96102}
    97103
     104
     105// Dump lookup tables, including interpolation bins, to log file
     106
     107template <class DATA, class SAMP> inline
     108void G4CascadeFunctions<DATA,SAMP>::printTable() {
     109  G4cout << " ---------- " << DATA::data.name << " ----------" << G4endl;
     110  instance.print();
     111  DATA::data.print();
     112  G4cout << " ------------------------------" << G4endl;
     113}
     114
    98115#endif  /* G4_CASCADE_FUNCTIONS_ICC */
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeInterface.hh

    r1315 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeInterface.hh,v 1.16 2010/05/21 18:07:30 mkelsey Exp $
     26// $Id: G4CascadeInterface.hh,v 1.23 2010/09/23 18:13:32 mkelsey Exp $
    2727// Defines an interface to Bertini (BERT) cascade
    2828// based on INUCL  intra-nuclear transport.models
     
    3131// 20100405  M. Kelsey -- Fix constness of op== and op!=
    3232// 20100519  M. Kelsey -- Remove Collider data members
     33// 20100617  M. Kelsey -- Make G4InuclCollider a local data member
     34// 20100723  M. Kelsey -- Move G4CollisionOutput here for reuse
     35// 20100916  M. Kelsey -- Add functions to encapsulate ApplyYourself() actions,
     36//              make colliders pointers (don't expose dependencies)
     37// 20100922  M. Kelsey -- Add functions to select de-excitation method
    3338
    3439#ifndef G4CASCADEINTERFACE_H
     
    3843#include "G4FragmentVector.hh"
    3944#include "G4KineticTrackVector.hh"
     45#include "G4LorentzRotation.hh"
    4046#include "G4Nucleon.hh"
    4147#include "G4Nucleus.hh"
     
    4349#include "G4ReactionProduct.hh"
    4450#include "G4ReactionProductVector.hh"
     51
     52class G4InuclCollider;
     53class G4InuclParticle;
     54class G4CollisionOutput;
     55class G4CascadeCheckBalance;
     56class G4V3DNucleus;
    4557
    4658
     
    5870                                 G4Nucleus& theNucleus);
    5971
     72  void setVerboseLevel(G4int verbose) { verboseLevel = verbose; }
     73
     74  // Select betweeen different post-cascade de-excitation models
     75  void useCascadeDeexcitation();
     76  void usePreCompoundDeexcitation();
     77
     78protected:
     79  // Convert input projectile and target to Bertini internal types
     80  void createBullet(const G4HadProjectile& aTrack);
     81  void createTarget(G4Nucleus& theNucleus);
     82
     83  // Evaluate whether any outgoing particles penetrated Coulomb barrier
     84  G4bool coulombBarrierViolation() const;
     85
     86  // Conditions for rejecting cascade attempt
     87  G4bool retryInelasticProton() const;
     88  G4bool retryInelasticNucleus() const;
     89
     90  // Fill sparse array with minimum momenta for inelastic on hydrogen
     91  void initializeElasticCuts();
     92
     93  // Transfer Bertini internal final state to hadronics interface
     94  void copyOutputToHadronicResult();
     95
     96  // Terminate job because of energy/momentum/etc. violations
     97  void throwNonConservationFailure();
     98
    6099private:
    61100  G4int operator==(const G4CascadeInterface& right) const {
     
    67106  }
    68107
     108  static const G4int maximumTries;      // Number of iterations for inelastic
     109
     110  G4double cutElastic[32];              // Bullet momenta for hydrogen target
     111
    69112  G4int verboseLevel;
     113  G4int numberOfTries;
    70114
    71 private:
    72   G4HadFinalState theResult; 
     115  G4HadFinalState theResult;
     116  G4InuclCollider* collider;
     117  G4CascadeCheckBalance* balance;
     118
     119  G4InuclParticle* bullet;
     120  G4InuclParticle* target;
     121  G4CollisionOutput* output;
     122
     123  G4LorentzRotation bulletInLabFrame;
    73124};
    74125
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeInterpolator.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeInterpolator.hh,v 1.2 2010/06/25 09:42:00 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeInterpolator.hh,v 1.3 2010/08/03 23:09:36 mkelsey Exp $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// Author:  Michael Kelsey <kelsey@slac.stanford.edu>
     
    3838// is the bin index, and the fractional part is, obviously, the
    3939// fractional part.
     40//
     41// 20100803  M. Kelsey -- Add printBins() function for debugging
    4042
    4143#ifndef G4CASCADE_INTERPOLATOR_HH
     
    6466  G4double interpolate(const G4double (&yb)[nBins]) const;
    6567
     68  void printBins() const;       // Show bin edges for debugging purposes
     69
    6670private:
    6771  const G4double (&xBins)[nBins];
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeInterpolator.icc

    r1337 r1340  
     1#ifndef G4CASCADE_INTERPOLATOR_ICC
     2#define G4CASCADE_INTERPOLATOR_ICC
    13//
    24// ********************************************************************
     
    2426// ********************************************************************
    2527//
    26 // $Id: G4CascadeInterpolator.icc,v 1.6 2010/06/25 09:42:02 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     28// $Id: G4CascadeInterpolator.icc,v 1.8 2010/10/19 19:48:00 mkelsey Exp $
     29// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2830//
    2931// Author:  Michael Kelsey <kelsey@slac.stanford.edu>
     
    4345// 20100520  M. Kelsey -- Second bug fix:  Loop in bin search should start at
    4446//              i=1, not i=0 (since i-1 is the key).
     47// 20100803  M. Kelsey -- Add printBins() function for debugging
     48// 20101019  M. Kelsey -- CoVerity reports: recursive #include, index overrun
    4549
     50#include "globals.hh"
    4651#include "G4CascadeInterpolator.hh"
     52#include <iomanip>
    4753
    4854
     
    6672  } else {                              // Assume nBins small; linear search
    6773    int i;
    68     for (i=1; i<nBins && x>xBins[i]; i++) {;}   // Stops when x within bin i-1
     74    for (i=1; i<last && x>xBins[i]; i++) {;}    // Stops when x within bin i-1
    6975    xindex = i-1;
    7076    xbin = xBins[i] - xBins[i-1];
     
    102108  return (i==last) ? yb[last] : (yb[i] + frac*(yb[i+1]-yb[i]));
    103109}
     110
     111
     112// Print bin edges for debugging
     113
     114template <int NBINS>
     115void G4CascadeInterpolator<NBINS>::printBins() const {
     116  G4cout << " G4CascadeInterpolator<" << NBINS << "> : " << G4endl;
     117  for (G4int k=0; k<NBINS; k++) {
     118    G4cout << " " << std::setw(5) << xBins[k];
     119    if ((k+1)%12 == 0) G4cout << G4endl;
     120  }
     121  G4cout << G4endl;
     122}
     123
     124#endif  /* G4CASCADE_INTERPOLATOR_ICC */
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKminusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKminusNChannel.hh,v 1.7 2010/06/25 09:42:04 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKminusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKminusPChannel.hh,v 1.7 2010/06/25 09:42:06 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKplusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKplusNChannel.hh,v 1.7 2010/06/25 09:42:08 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKplusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKplusPChannel.hh,v 1.7 2010/06/25 09:42:10 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKzeroBarNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKzeroBarNChannel.hh,v 1.7 2010/06/25 09:42:12 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKzeroBarPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKzeroBarPChannel.hh,v 1.7 2010/06/25 09:42:14 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKzeroNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKzeroNChannel.hh,v 1.7 2010/06/25 09:42:16 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeKzeroPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeKzeroPChannel.hh,v 1.7 2010/06/25 09:42:18 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeLambdaNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeLambdaNChannel.hh,v 1.7 2010/06/25 09:42:20 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeLambdaPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeLambdaPChannel.hh,v 1.7 2010/06/25 09:42:22 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeNNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeNNChannel.hh,v 1.3 2010/06/25 09:42:24 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_NN_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeNPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeNPChannel.hh,v 1.3 2010/06/25 09:42:26 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_NP_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePPChannel.hh,v 1.3 2010/06/25 09:42:28 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PP_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiMinusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiMinusNChannel.hh,v 1.3 2010/06/25 09:42:30 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIMINUSN_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiMinusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiMinusPChannel.hh,v 1.3 2010/06/25 09:42:32 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIMINUSP_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiPlusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiPlusNChannel.hh,v 1.3 2010/06/25 09:42:34 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIPLUSN_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiPlusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiPlusPChannel.hh,v 1.3 2010/06/25 09:42:36 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIPLUSP_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiZeroNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiZeroNChannel.hh,v 1.3 2010/06/25 09:42:38 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIZERON_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadePiZeroPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadePiZeroPChannel.hh,v 1.3 2010/06/25 09:42:40 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828
    2929#ifndef G4_CASCADE_PIZEROP_CHANNEL_HH
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSampler.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeSampler.hh,v 1.3 2010/06/25 09:42:42 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeSampler.hh,v 1.4 2010/08/03 23:09:36 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100506  M. Kelsey -- Move functionality of G4CascadeChannel here,
     
    3131// 20100512  M. Kelsey -- Make this templated on energy and multiplicity
    3232//              binning, as base to new sampler.
     33// 20100803  M. Kelsey -- Add print function for debugging.
    3334
    3435#ifndef G4_CASCADE_SAMPLER_HH
     
    5960                      const G4double xsec[][energyBins]) const;
    6061
     62  virtual void print() const;
     63
    6164private:
    6265  // Optional start/stop arguments default to inclusive arrays
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSampler.icc

    r1337 r1340  
     1#ifndef G4CASCADE_SAMPLER_ICC
     2#define G4CASCADE_SAMPLER_ICC
    13//
    24// ********************************************************************
     
    2426// ********************************************************************
    2527//
    26 // $Id: G4CascadeSampler.icc,v 1.3 2010/06/25 09:42:44 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     28// $Id: G4CascadeSampler.icc,v 1.5 2010/10/19 19:48:01 mkelsey Exp $
     29// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2830//
    2931// 20100506 M. Kelsey -- Move functionity of G4CascadeChannel here,
    3032//              use as base class to G4CascadeFunctions<T>.
    3133// 20100512 M. Kelsey -- Move implementation to .icc with templating
     34// 20100803 M. Kelsey -- Add print function for debugging.
     35// 20101019  M. Kelsey -- CoVerity report: recursive #include
    3236
    3337#include "G4CascadeSampler.hh"
     
    108112  return 0;     // Is this right?  Shouldn't it return maximum, not minimum?
    109113}
     114
     115
     116template <int NBINS, int NMULT> inline
     117void G4CascadeSampler<NBINS,NMULT>::print() const {
     118  interpolator.printBins();
     119}
     120
     121#endif  /* G4CASCADE_SAMPLER_ICC */
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaMinusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaMinusNChannel.hh,v 1.7 2010/06/25 09:42:46 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaMinusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaMinusPChannel.hh,v 1.7 2010/06/25 09:42:48 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaPlusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaPlusNChannel.hh,v 1.7 2010/06/25 09:42:50 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaPlusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaPlusPChannel.hh,v 1.7 2010/06/25 09:42:52 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaZeroNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaZeroNChannel.hh,v 1.7 2010/06/25 09:42:54 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeSigmaZeroPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeSigmaZeroPChannel.hh,v 1.7 2010/06/25 09:42:56 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeXiMinusNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeXiMinusNChannel.hh,v 1.7 2010/06/25 09:42:58 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeXiMinusPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeXiMinusPChannel.hh,v 1.7 2010/06/25 09:43:00 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeXiZeroNChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeXiZeroNChannel.hh,v 1.7 2010/06/25 09:43:02 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CascadeXiZeroPChannel.hh

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeXiZeroPChannel.hh,v 1.7 2010/06/25 09:43:04 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100507  M. Kelsey -- Remove redundant total-bins template argument
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4CollisionOutput.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CollisionOutput.hh,v 1.20.2.1 2010/06/25 09:43:06 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CollisionOutput.hh,v 1.29 2010/09/26 04:06:03 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3232// 20100418  M. Kelsey -- Add function to boost output lists to lab frame
    3333// 20100520  M. Kelsey -- Add function to rotate Z axis, from G4Casc.Interface
     34// 20100620  M. Kelsey -- Add setVerboseLevel() function
     35// 20100715  M. Kelsey -- Add total charge and baryon number functions, and a
     36//              combined "add()" function to put two of these together.
     37// 20100716  M. Kelsey -- Add interface to handle G4CascadParticles
     38// 20100924  M. Kelsey -- Use "OutgoingNuclei" name consistently, replacing
     39//              old "TargetFragment".  Add new (reusable) G4Fragment buffer
     40//              and access functions for initial post-cascade processing.
     41//              Move implementation of add() to .cc file.
     42// 20100925  M. Kelsey -- Add function to process G4ReactionProduct list
    3443
    3544#ifndef G4COLLISION_OUTPUT_HH
    3645#define G4COLLISION_OUTPUT_HH
    3746
     47#include "G4Fragment.hh"
    3848#include "G4InuclElementaryParticle.hh"
    3949#include "G4InuclNuclei.hh"
    4050#include "G4LorentzRotation.hh"
     51#include "G4ReactionProductVector.hh"
    4152#include <algorithm>
    4253#include <vector>
    4354
     55class G4CascadParticle;
    4456class G4LorentzConvertor;
    4557
     58
    4659class G4CollisionOutput {
    47 
    4860public:
    49 
    5061  G4CollisionOutput();
    51 
    5262  G4CollisionOutput& operator=(const G4CollisionOutput& right);
    5363
    54   void reset();
     64  void setVerboseLevel(G4int verbose) { verboseLevel = verbose; };
     65
     66  // ===== Accumulate contents of lists =====
     67
     68  void reset();         // Empties lists for new event
     69
     70  void add(const G4CollisionOutput& right);     // Merge complete objects
    5571
    5672  void addOutgoingParticle(const G4InuclElementaryParticle& particle) {
     
    6076  void addOutgoingParticles(const std::vector<G4InuclElementaryParticle>& particles);
    6177
    62   void addTargetFragment(const G4InuclNuclei& nuclei) {
    63     nucleiFragments.push_back(nuclei);
     78  void addOutgoingNucleus(const G4InuclNuclei& nuclei) {
     79    outgoingNuclei.push_back(nuclei);
    6480  };
    6581
    66   void addTargetFragments(const std::vector<G4InuclNuclei>& nuclea);
     82  void addOutgoingNuclei(const std::vector<G4InuclNuclei>& nuclea);
    6783
     84  // These are primarily for G4IntraNucleiCascader internal checks
     85  void addOutgoingParticle(const G4CascadParticle& cparticle);
     86  void addOutgoingParticles(const std::vector<G4CascadParticle>& cparticles);
     87
     88  void addOutgoingParticles(const G4ReactionProductVector* rproducts);
     89
     90  // Special buffer for initial, possible unstable fragment from cascade
     91  void addRecoilFragment(const G4Fragment* aFragment) {
     92    if (aFragment) addRecoilFragment(*aFragment);
     93  }
     94
     95  void addRecoilFragment(const G4Fragment& aFragment) {
     96    theRecoilFragment = aFragment;
     97  }
     98
     99  // ===== Access contents of lists =====
     100
     101  G4int numberOfOutgoingParticles() const { return outgoingParticles.size(); }
     102   
    68103  const std::vector<G4InuclElementaryParticle>& getOutgoingParticles() const {
    69104    return outgoingParticles;
    70105  };
    71106
    72   G4int numberOfNucleiFragments() const {
    73     return nucleiFragments.size();
    74   };
     107  G4int numberOfOutgoingNuclei() const { return outgoingNuclei.size(); };
    75108 
    76   const std::vector<G4InuclNuclei>& getNucleiFragments() const {
    77     return nucleiFragments;
     109  const std::vector<G4InuclNuclei>& getOutgoingNuclei() const {
     110    return outgoingNuclei;
    78111  };
    79112
     113  const G4Fragment& getRecoilFragment() const { return theRecoilFragment; }
     114
     115  // ===== Get event totals for conservation checking, recoil, etc. ======
     116
    80117  G4LorentzVector getTotalOutputMomentum() const;
     118  G4int getTotalCharge() const;                 // NOTE:  No fractional charges!
     119  G4int getTotalBaryonNumber() const;
    81120
    82121  void printCollisionOutput() const;
    83122
     123  // ===== Manipulate final-state particles for kinematics =====
     124
    84125  void boostToLabFrame(const G4LorentzConvertor& convertor);
    85 
    86126  void rotateEvent(const G4LorentzRotation& rotate);
    87 
    88   void trivialise(G4InuclParticle* bullet,
    89                   G4InuclParticle* target);
    90 
    91   void setOnShell(G4InuclParticle* bullet,
    92                   G4InuclParticle* target);
    93 
     127  void trivialise(G4InuclParticle* bullet, G4InuclParticle* target);
     128  void setOnShell(G4InuclParticle* bullet, G4InuclParticle* target);
    94129  void setRemainingExitationEnergy();
    95130
    96   double getRemainingExitationEnergy() const {
    97     return eex_rest;
    98   };
    99 
    100   G4bool acceptable() const {
    101     return on_shell;
    102   };
     131  double getRemainingExitationEnergy() const { return eex_rest; };
     132  G4bool acceptable() const { return on_shell; };
    103133
    104134private:
    105135  G4int verboseLevel;
     136
    106137  std::vector<G4InuclElementaryParticle> outgoingParticles;
    107   std::vector<G4InuclNuclei> nucleiFragments;
    108   G4double eex_rest;
     138  std::vector<G4InuclNuclei> outgoingNuclei;
     139  G4Fragment theRecoilFragment;
     140
     141  G4double eex_rest;            // Used by setOnShell() for kinematics
    109142
    110143  std::pair<std::pair<G4int,G4int>, G4int> selectPairToTune(G4double de) const;
    111144
    112145  G4bool on_shell;
    113 
    114146};       
    115147
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4Dineutron.hh

    r1337 r1340  
    2525//
    2626// $Id: G4Dineutron.hh,v 1.4 2010/06/25 09:43:08 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4Diproton.hh

    r1337 r1340  
    2525//
    2626// $Id: G4Diproton.hh,v 1.4 2010/06/25 09:43:10 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4ElementaryParticleCollider.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4ElementaryParticleCollider.hh,v 1.32 2010/06/25 09:43:12 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4ElementaryParticleCollider.hh,v 1.35 2010/08/04 05:28:24 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    4141//              particle-types selector to all modes, not just strangeness.
    4242// 20100517  M. Kelsey -- Inherit from common base class, make arrays static
     43// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     44// 20100726  M. Kelsey -- Move remaining std::vector<> buffers here
     45// 20100804  M. Kelsey -- Add printFinalStateTables() function.
    4346
    4447#ifndef G4ELEMENTARY_PARTICLE_COLLIDER_HH
    4548#define G4ELEMENTARY_PARTICLE_COLLIDER_HH
    4649
    47 #include "G4VCascadeCollider.hh"
     50#include "G4CascadeColliderBase.hh"
    4851#include "G4InuclElementaryParticle.hh"
    4952#include "G4LorentzVector.hh"
     
    5457
    5558
    56 class G4ElementaryParticleCollider : public G4VCascadeCollider {
     59class G4ElementaryParticleCollider : public G4CascadeColliderBase {
    5760public:
    5861  G4ElementaryParticleCollider();
     
    104107                             G4double pmod) const;
    105108
     109  void printFinalStateTables() const;
     110
    106111  // Internal buffers for lists of secondaries
    107112  std::vector<G4InuclElementaryParticle> particles;
     113  std::vector<G4LorentzVector> scm_momentums;
    108114  std::vector<G4double> modules;
     115  std::vector<G4double> masses2;
    109116  std::vector<G4int> particle_kinds;
    110117
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4EquilibriumEvaporator.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4EquilibriumEvaporator.hh,v 1.11.2.1 2010/06/25 09:43:14 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4EquilibriumEvaporator.hh,v 1.15 2010/09/26 04:06:03 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
     
    3130//              simple data members.  Rename timeToBigBang() to override
    3231//              base explosion().
     32// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     33// 20100923  M. Kelsey -- Migrate to integer A and Z
     34// 20100925  M. Kelsey -- Remove no longer necessary explosion() interface
    3335
    3436#ifndef G4EQUILIBRIUM_EVAPORATOR_HH
    3537#define G4EQUILIBRIUM_EVAPORATOR_HH
    3638
    37 #include "G4VCascadeCollider.hh"
     39#include "G4CascadeColliderBase.hh"
     40#include "G4Fissioner.hh"
     41#include "G4BigBanger.hh"
    3842
    3943class G4CollisionOutput;
    40 class G4Fissioner;
    41 class G4BigBanger;
    4244class G4InuclParticle;
    4345
    44 class G4EquilibriumEvaporator : public G4VCascadeCollider {
     46class G4EquilibriumEvaporator : public G4CascadeColliderBase {
    4547public:
    4648  G4EquilibriumEvaporator();
     
    5254private:
    5355  // Replace base class verision
    54   virtual G4bool explosion(G4InuclNuclei*) const { return false; }
    55   virtual G4bool explosion(G4double a,
    56                            G4double z,
    57                            G4double e) const;
     56  virtual G4bool explosion(G4int a, G4int z, G4double e) const;
    5857
    59   G4bool goodRemnant(G4double a,
    60                      G4double z) const;
     58  // FIXME:  Need to redeclare and call through base-class polymorphisms
     59  virtual G4bool explosion(G4InuclNuclei* target) const {
     60    return G4CascadeColliderBase::explosion(target);
     61  }
    6162
    62   G4double getE0(G4double A) const;
     63  virtual G4bool explosion(G4Fragment* target) const {
     64    return G4CascadeColliderBase::explosion(target);
     65  }
    6366
    64   G4double getPARLEVDEN(G4double A,
    65                         G4double Z) const;
     67  G4bool goodRemnant(G4int a, G4int z) const;
     68  G4double getE0(G4int A) const;
     69  G4double getPARLEVDEN(G4int A, G4int Z) const;
     70  G4double getQF(G4double x, G4double x2, G4int a, G4int z, G4double e) const;
     71  G4double getAF(G4double x, G4int a, G4int z, G4double e) const;
    6672
    67   G4double getQF(G4double x,
    68                  G4double x2,
    69                  G4double a,
    70                  G4double z,
    71                  G4double e) const;
    72 
    73   G4double getAF(G4double x,
    74                  G4double a,
    75                  G4double z,
    76                  G4double e) const;
    77 
    78   G4Fissioner* theFissioner;
    79   G4BigBanger* theBigBanger;
     73  G4Fissioner theFissioner;
     74  G4BigBanger theBigBanger;
    8075};       
    8176
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4EvaporationInuclCollider.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EvaporationInuclCollider.hh,v 1.5 2010/05/21 17:56:34 mkelsey Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4EvaporationInuclCollider.hh,v 1.6 2010/07/14 15:41:12 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100315  M. Kelsey -- Remove "using" directive and unnecessary #includes.
     
    3131// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3232//              simple data members
     33// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
    3334
    3435#ifndef G4EVAPORATIONINUCL_COLLIDER_HH
    3536#define G4EVAPORATIONINUCL_COLLIDER_HH
    3637 
    37 #include "G4VCascadeCollider.hh"
     38#include "G4CascadeColliderBase.hh"
    3839
    3940class G4InuclParticle;
     
    4243class G4BigBanger;
    4344
    44 class G4EvaporationInuclCollider : public G4VCascadeCollider {
     45class G4EvaporationInuclCollider : public G4CascadeColliderBase {
    4546public:
    4647  G4EvaporationInuclCollider();
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4ExitonConfiguration.hh

    r819 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4ExitonConfiguration.hh,v 1.7 2010/09/24 06:26:06 mkelsey Exp $
    2526//
     27// 20100909  Add function to reset values to zero
     28// 20100924  Migrate to integer A and Z
     29
    2630#ifndef G4EXITON_CONFIGURATION_HH
    2731#define G4EXITON_CONFIGURATION_HH
    2832
    2933class G4ExitonConfiguration {
     34public:
     35  G4ExitonConfiguration()
     36    : protonQuasiParticles(0), neutronQuasiParticles(0),
     37      protonHoles(0), neutronHoles(0) {}
    3038
    31 public:
     39  G4ExitonConfiguration(G4int qpp, G4int qnp, G4int qph, G4int qnh)
     40    : protonQuasiParticles(qpp), neutronQuasiParticles(qnp),
     41      protonHoles(qph), neutronHoles(qnh) {}
    3242
    33   G4ExitonConfiguration() {
    34     protonQuasiParticles = 0.0;
    35     neutronQuasiParticles = 0.0;
    36     protonHoles = 0.0;
    37     neutronHoles = 0.0;
    38   };
     43  void clear() {
     44    protonQuasiParticles = neutronQuasiParticles = 0;
     45    protonHoles = neutronHoles = 0;
     46  }
    3947
    40   G4ExitonConfiguration(G4double qpp,
    41                         G4double qnp,
    42                         G4double qph,
    43                         G4double qnh)
    44     : protonQuasiParticles(qpp),
    45     neutronQuasiParticles(qnp),
    46     protonHoles(qph),
    47     neutronHoles(qnh) {
    48   };
    49  
    5048  void incrementQP(G4int ip) {
    51     if(ip < 3) {
    52       if(ip == 1) {
    53         protonQuasiParticles += 1.0;
    54       }
    55       else if(ip == 2) {
    56         neutronQuasiParticles += 1.0;
    57       };
    58     };
    59   };
     49    if (ip == 1) protonQuasiParticles++;
     50    else if (ip == 2) neutronQuasiParticles++;
     51  }
    6052
    6153  void incrementHoles(G4int ip) {
    62     if(ip < 3) {
    63       if(ip == 1) {
    64         protonHoles += 1.0;
    65       }
    66       else if(ip == 2) {
    67         neutronHoles += 1.0;
    68       };
    69     };
    70   };
     54    if (ip == 1) protonHoles++;
     55    else if (ip == 2) neutronHoles++;
     56  }
    7157
    7258  void print() const {
     
    7662           << " neutron particles " << neutronQuasiParticles << " holes "
    7763           << neutronHoles << G4endl;
    78   };
     64  }
    7965     
    80   G4double protonQuasiParticles;
    81   G4double neutronQuasiParticles;
    82   G4double protonHoles;
    83   G4double neutronHoles;
    84 
     66  G4int protonQuasiParticles;
     67  G4int neutronQuasiParticles;
     68  G4int protonHoles;
     69  G4int neutronHoles;
    8570};       
    8671
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4FissionStore.hh

    r819 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4FissionStore.hh,v 1.11 2010/10/19 21:33:58 mkelsey Exp $
    2526//
     27// 20100728  Move ::addConfig() to .cc file, add setVerboseLevel(), clear()
     28
    2629#ifndef G4FISSION_STORE_HH
    2730#define G4FISSION_STORE_HH
    2831
    2932#include "G4FissionConfiguration.hh"
    30 
    3133#include <vector>
    3234
    3335class G4FissionStore {
    34 
    3536public:
    36 
    3737  G4FissionStore();
    3838
    39   void addConfig(G4double a,
    40                  G4double z,
    41                  G4double ez,
    42                  G4double ek,
    43                  G4double ev) {
    44     G4FissionConfiguration config(a, z, ez, ek, ev);
    45     configurations.push_back(config);
    46     // config.print();
    47   };
     39  void setVerboseLevel(G4int verbose=1) { verboseLevel = verbose; }
    4840
    49   G4int size() const {
    50     return configurations.size();
    51   };
     41  void addConfig(G4double a, G4double z, G4double ez, G4double ek, G4double ev);
     42
     43  void clear() { configurations.clear(); }
     44
     45  G4int size() const { return configurations.size(); }
    5246
    5347  G4FissionConfiguration generateConfiguration(G4double amax,
     
    5650private:
    5751  G4int verboseLevel;
    58 
    5952  std::vector<G4FissionConfiguration> configurations;
    60 
    6153};
    6254
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4Fissioner.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4Fissioner.hh,v 1.13 2010/06/25 09:43:16 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4Fissioner.hh,v 1.16 2010/09/14 17:51:36 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100315  M. Kelsey -- Remove "using" directive and unnecessary #includes.
    3030// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
    3131// 20100517  M. Kelsey -- Inherit from common base class
     32// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     33// 20100728  M. Kelsey -- Move G4FissionStore to data member and reuse
     34// 20100914  M. Kelsey -- Migrate to integer A and Z
    3235
    3336#ifndef G4FISSIONER_HH
    3437#define G4FISSIONER_HH
    3538
    36 #include "G4VCascadeCollider.hh"
     39#include "G4CascadeColliderBase.hh"
     40#include "G4FissionStore.hh"
    3741#include <vector>
    3842
     
    4145
    4246
    43 class G4Fissioner : public G4VCascadeCollider {
     47class G4Fissioner : public G4CascadeColliderBase {
    4448public:
    4549  G4Fissioner();
     
    5054
    5155private:
    52   G4double getC2(G4double A1,
    53                  G4double A2,
     56  G4FissionStore fissionStore;
     57
     58  G4double getC2(G4int A1,
     59                 G4int A2,
    5460                 G4double X3,
    5561                 G4double X4,
    5662                 G4double R12) const;
    5763
    58   G4double getZopt(G4double A1,
    59                    G4double A2,
    60                    G4double ZT,
     64  G4double getZopt(G4int A1,
     65                   G4int A2,
     66                   G4int ZT,
    6167                   G4double X3,
    6268                   G4double X4,
     
    6672                             std::vector<G4double>& ED,
    6773                             G4double& VC,
    68                              G4double AF,
    69                              G4double AS,
    70                              G4double ZF,
    71                              G4double ZS,
     74                             G4int AF,
     75                             G4int AS,
     76                             G4int ZF,
     77                             G4int ZS,
    7278                             std::vector<G4double>& AL1,
    7379                             std::vector<G4double>& BET1,
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InteractionCase.hh

    r1337 r1340  
    2525//
    2626// $Id: G4InteractionCase.hh,v 1.12 2010/06/25 09:43:18 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100518  M. Kelsey -- Why use std::pair<> at all?  Never exported; just
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4IntraNucleiCascader.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4IntraNucleiCascader.hh,v 1.10.2.1 2010/06/25 09:43:20 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4IntraNucleiCascader.hh,v 1.21 2010/09/16 05:21:00 mkelsey Exp $
     26// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100315  M. Kelsey -- Remove "using" directory and unnecessary #includes.
     
    3130// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3231//              simple data members
     32// 20100617  M. Kelsey -- Make G4NucleiModel a data member, instead of
     33//              creating and deleting on every cycle.
     34// 20100623  M. Kelsey -- Undo change from 0617.  G4NucleiModel not reusable.
     35// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     36// 20100716  M. Kelsey -- Eliminate inter_case; use base-class functionality,
     37//              add function to compute recoil nuclear mass on the fly
     38// 20100720  M. Kelsey -- Make EPCollider pointer member
     39// 20100722  M. Kelsey -- Move cascade output buffers to .hh file
     40// 20100728  M. Kelsey -- Move G4NucleiModel here, as pointer member
     41// 20100907  M. Kelsey -- Add new "makeResidualFragment" to create
     42//              G4InuclNuclei at current stage of cascade
     43// 20100909  M. Kelsey -- Drop makeResidualFragment(), getResidualMass() and
     44//              local G4InuclNuclei object, replace with new RecoilMaker.
     45//              Move goodCase() to RecoilMaker.
     46// 20100916  M. Kelsey -- Add functions to handle trapped particles, and to
     47//              decay hyperons.
    3348
    3449#ifndef G4INTRA_NUCLEI_CASCADER_HH
    3550#define G4INTRA_NUCLEI_CASCADER_HH
    3651
    37 #include "G4VCascadeCollider.hh"
     52#include "G4CascadeColliderBase.hh"
     53#include "G4CollisionOutput.hh"
     54#include <vector>
    3855
     56class G4CascadParticle;
     57class G4CascadeRecoilMaker;
    3958class G4CollisionOutput;
    4059class G4ElementaryParticleCollider;
     60class G4InuclElementaryParticle;
    4161class G4InuclParticle;
     62class G4NucleiModel;
    4263
    4364
    44 class G4IntraNucleiCascader : public G4VCascadeCollider {
     65class G4IntraNucleiCascader : public G4CascadeColliderBase {
    4566public:
    4667  G4IntraNucleiCascader();
     
    5071               G4CollisionOutput& output);
    5172
    52   // FIXME:  This should come from (or be determined by) G4InteractionCase
    53   void setInteractionCase(G4int intcase) {
    54     inter_case = intcase;
    55   };
     73protected:
     74  void processTrappedParticle(const G4CascadParticle& trapped);
     75  void decayTrappedParticle(const G4CascadParticle& trapped);
    5676
    5777private:
     78  G4NucleiModel* model;
    5879  G4ElementaryParticleCollider* theElementaryParticleCollider;
     80  G4CascadeRecoilMaker* theRecoilMaker;
    5981
    60   // FIXME:  This should come from (or be determined by) G4InteractionCase
    61   G4int inter_case;
    62 
    63   G4bool goodCase(G4double a, G4double z, G4double eexs, G4double ein) const;
     82  // Buffers for collecting result of cascade (reset on each iteration)
     83  G4CollisionOutput output;
     84  std::vector<G4CascadParticle> cascad_particles;
     85  std::vector<G4CascadParticle> new_cascad_particles;
     86  std::vector<G4InuclElementaryParticle> output_particles;
     87  G4ExitonConfiguration theExitonConfiguration;
    6488};       
    6589
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclCollider.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4InuclCollider.hh,v 1.13.2.1 2010/06/25 09:43:22 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4InuclCollider.hh,v 1.21 2010/09/27 04:03:43 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
    3029// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3130//              simple data members
     31// 20100620  M. Kelsey -- Move output buffers here to reduce memory churn
     32// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     33// 20100720  M. Kelsey -- Make all the collders pointer members (to reducde
     34//              external compile dependences).
     35// 20100915  M. Kelsey -- Move de-excitation colliders to G4CascadeDeexcitation
     36// 20100922  M. Kelsey -- Add functions to select de-excitation method, change
     37//              "theDeexcitation" to be a base-class pointer for switching
     38// 20100926  M. Kelsey -- Use new intermediate base class for de-exciations.
    3239
    3340#ifndef G4INUCL_COLLIDER_HH
    3441#define G4INUCL_COLLIDER_HH
    3542
    36 #include "G4VCascadeCollider.hh"
     43#include "G4CascadeColliderBase.hh"
     44#include "G4CollisionOutput.hh"
    3745
    38 class G4BigBanger;
    39 class G4CollisionOutput;
     46class G4InuclParticle;
    4047class G4ElementaryParticleCollider;
    41 class G4EquilibriumEvaporator;
    4248class G4IntraNucleiCascader;
    43 class G4InuclParticle;
    44 class G4NonEquilibriumEvaporator;
     49class G4VCascadeDeexcitation;
    4550
    4651
    47 class G4InuclCollider : public G4VCascadeCollider {
    48 
     52class G4InuclCollider : public G4CascadeColliderBase {
    4953public:
    50 
    5154  G4InuclCollider();
    5255  virtual ~G4InuclCollider();
    5356
    5457  void collide(G4InuclParticle* bullet, G4InuclParticle* target,
    55                G4CollisionOutput& output);
     58               G4CollisionOutput& globalOutput);
     59
     60  // Select betweeen different post-cascade de-excitation models
     61  void useCascadeDeexcitation();
     62  void usePreCompoundDeexcitation();
    5663
    5764private:
    5865  G4ElementaryParticleCollider* theElementaryParticleCollider;
    5966  G4IntraNucleiCascader* theIntraNucleiCascader;
    60   G4NonEquilibriumEvaporator* theNonEquilibriumEvaporator;
    61   G4EquilibriumEvaporator* theEquilibriumEvaporator;
    62   G4BigBanger* theBigBanger;
     67
     68  G4VCascadeDeexcitation* theDeexcitation;      // User switchable!
     69
     70  G4CollisionOutput output;             // Secondaries from main cascade
     71  G4CollisionOutput DEXoutput;          // Secondaries from de-excitation
    6372};       
    6473
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclElementaryParticle.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclElementaryParticle.hh,v 1.23 2010/06/25 09:43:24 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclElementaryParticle.hh,v 1.25 2010/09/16 05:21:00 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
    3030// 20100409  M. Kelsey -- Drop unused string argument from ctors.
    3131// 20100429  M. Kelsey -- Change "photon()" to "isPhoton()", use enum names
     32// 20100914  M. Kelsey -- Move printout to .cc file
     33// 20100915  M. Kelsey -- Add hyperon() identification function, ctor for
     34//              G4DynamicParticle
    3235
    3336#ifndef G4INUCL_ELEMENTARY_PARTICLE_HH
     
    4750  explicit G4InuclElementaryParticle(G4int type)
    4851    : G4InuclParticle(makeDefinition(type)), generation(0) {}
     52
     53  G4InuclElementaryParticle(const G4DynamicParticle& dynPart, G4int model=0)
     54    : G4InuclParticle(dynPart), generation(0) {
     55    setModel(model);
     56  }
    4957
    5058  G4InuclElementaryParticle(const G4LorentzVector& mom,
     
    8189  }
    8290
     91  G4bool hyperon() const {
     92    return (baryon() && getStrangeness() != 0.);
     93  }
     94
    8395  G4bool quasi_deutron() const { return (type() > 100); }
     96
     97  G4double getStrangeness() const { return getStrangeness(type()); }
    8498
    8599  G4bool valid() const { return type()>0; }
    86100
    87   virtual void printParticle() const {
    88     G4InuclParticle::printParticle();
    89     G4cout << " Particle: type " << type() << " mass " << getMass()
    90            << " ekin " << getKineticEnergy() << G4endl;
    91   }
     101  virtual void printParticle() const;
    92102
    93103  void setGeneration(G4int gen) { generation = gen; }
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclNuclei.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclNuclei.hh,v 1.17 2010/06/25 09:43:26 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclNuclei.hh,v 1.27 2010/09/25 04:35:02 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100112  Michael Kelsey -- Replace G4CascadeMomentum with G4LorentzVector
     
    3232// 20100319  M. Kelsey -- Remove "using" directory and unnecessary #includes.
    3333// 20100409  M. Kelsey -- Drop unused string argument from ctors.
     34// 20100630  M. Kelsey -- Add excitation energy as optional public ctor arg,
     35//           remove excitation energy data member (part of G4Ions).  Add
     36//           excitation energy to "getNucleiMass()" function, move print to .cc
     37// 20100711  M. Kelsey -- Add optional model ID to constructors
     38// 20100714  M. Kelsey -- Use G4DynamicParticle::theDynamicalMass to deal with
     39//           excitation energy without instantianting "infinite" G4PartDefns.
     40// 20100719  M. Kelsey -- Move setExitationEnergy implementation to .cc file.
     41// 20100906  M. Kelsey -- Add fill() functions to rewrite contents
     42// 20100909  M. Kelsey -- Add function to discard exciton configuration
     43// 20100914  M. Kelsey -- Use integers for A and Z
     44// 20100915  M. Kelsey -- Add constructor to copy G4DynamicParticle input
     45// 20100924  M. Kelsey -- Add constructor to copy G4Fragment input, and output
     46//              functions to create G4Fragment.
    3447
    3548#ifndef G4INUCL_NUCLEI_HH
     
    3750
    3851#include "G4InuclParticle.hh"
     52#include "G4LorentzVector.hh"
    3953#include "G4ExitonConfiguration.hh"
    4054
     55class G4Fragment;
    4156class G4ParticleDefinition;
     57
    4258
    4359class G4InuclNuclei : public G4InuclParticle {
     
    4561  G4InuclNuclei() : G4InuclParticle() {}
    4662
    47   G4InuclNuclei(G4double a, G4double z)
    48     : G4InuclParticle(makeDefinition(a,z)),
    49       exitationEnergy(0.0) {}
     63  G4InuclNuclei(const G4DynamicParticle& dynPart, G4int model=0)
     64    : G4InuclParticle(dynPart) {
     65    setModel(model);
     66  }
    5067
    51   G4InuclNuclei(const G4LorentzVector& mom, G4double a, G4double z)
    52     : G4InuclParticle(makeDefinition(a,z), mom),
    53       exitationEnergy(0.0) {}
     68  G4InuclNuclei(G4int a, G4int z, G4double exc=0., G4int model=0)
     69    : G4InuclParticle(makeDefinition(a,z)) {
     70    setExitationEnergy(exc);
     71    setModel(model);
     72  }
    5473
    55   G4InuclNuclei(G4double ekin, G4double a, G4double z)
    56     : G4InuclParticle(makeDefinition(a,z), ekin),
    57       exitationEnergy(0.0) {}
     74  G4InuclNuclei(const G4LorentzVector& mom, G4int a, G4int z,
     75                G4double exc=0., G4int model=0)
     76    : G4InuclParticle(makeDefinition(a,z), mom) {
     77    setExitationEnergy(exc);
     78    setModel(model);
     79  }
     80
     81  G4InuclNuclei(G4double ekin, G4int a, G4int z, G4double exc,
     82                G4int model=0)
     83    : G4InuclParticle(makeDefinition(a,z), ekin) {
     84    setExitationEnergy(exc);
     85    setModel(model);
     86  }
     87
     88  G4InuclNuclei(const G4Fragment& aFragment, G4int model=0);
    5889
    5990  virtual ~G4InuclNuclei() {}
     
    6192  // Copy and assignment constructors for use with std::vector<>
    6293  G4InuclNuclei(const G4InuclNuclei& right)
    63     : G4InuclParticle(right), exitationEnergy(right.exitationEnergy),
     94    : G4InuclParticle(right),
    6495      theExitonConfiguration(right.theExitonConfiguration) {}
    6596
    6697  G4InuclNuclei& operator=(const G4InuclNuclei& right);
    6798
    68   void setExitationEnergy(G4double e) { exitationEnergy = e; }
     99  // Overwrite data structure (avoids creating/copying temporaries)
     100  void fill(G4int a, G4int z, G4double exc=0., G4int model=0) {
     101    fill(0., a, z, exc, model);
     102  }
     103
     104  void fill(const G4LorentzVector& mom, G4int a, G4int z,
     105            G4double exc=0., G4int model=0);
     106
     107  void fill(G4double ekin, G4int a, G4int z, G4double exc,
     108            G4int model=0);
     109
     110  // Excitation energy is stored as dynamical mass of particle
     111  void setExitationEnergy(G4double e);
    69112
    70113  void setExitonConfiguration(const G4ExitonConfiguration& config) {
     
    72115  }
    73116
    74   G4double getA() const { return getDefinition()->GetAtomicMass(); }
     117  void clearExitonConfiguration() { theExitonConfiguration.clear(); }
    75118
    76   G4double getZ() const { return getDefinition()->GetAtomicNumber(); }
     119  G4int getA() const { return getDefinition()->GetAtomicMass(); }
     120  G4int getZ() const { return getDefinition()->GetAtomicNumber(); }
    77121
    78   G4double getExitationEnergy() const { return exitationEnergy; }
     122  G4double getNucleiMass() const {
     123    return getDefinition()->GetPDGMass()*MeV/GeV;       // From G4 to Bertini
     124  }
    79125
    80   G4double getExitationEnergyInGeV() const {
    81     return 0.001 * exitationEnergy;
     126  G4double getExitationEnergy() const {
     127    return (getMass()-getNucleiMass())*GeV/MeV;         // Always in MeV
    82128  }
     129
     130  G4double getExitationEnergyInGeV() const { return getExitationEnergy()/GeV; }
    83131
    84132  const G4ExitonConfiguration& getExitonConfiguration() const {
     
    86134  }
    87135
    88   static G4double getNucleiMass(G4double a, G4double z);
     136  static G4double getNucleiMass(G4int a, G4int z, G4double exc=0.);
    89137
    90   virtual void printParticle() const {
    91     G4cout << " A " << getA() << " Z " << getZ() << " mass "
    92            << getMass() << " Eex (MeV) " << exitationEnergy << G4endl;
    93     G4InuclParticle::printParticle();
    94   }
     138  virtual void printParticle() const;
     139
     140  // Convert contents to G4Fragment for use outside package
     141  G4Fragment makeG4Fragment() const;
     142  operator G4Fragment() const;
    95143
    96144protected:
    97145  // Convert nuclear configuration to standard GEANT4 pointer
    98   static G4ParticleDefinition*
    99   makeDefinition(G4double a, G4double z, G4double exc=0.);
    100 
    101   static G4ParticleDefinition*
    102   makeNuclearFragment(G4double a, G4double z, G4double exc=0.);
     146  static G4ParticleDefinition* makeDefinition(G4int a, G4int z);
     147  static G4ParticleDefinition* makeNuclearFragment(G4int a, G4int z);
    103148
    104149private:
    105   G4double exitationEnergy;
    106150  G4ExitonConfiguration theExitonConfiguration;
    107151};       
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclParticle.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclParticle.hh,v 1.20 2010/06/25 09:43:28 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclParticle.hh,v 1.22 2010/09/16 05:21:00 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100112  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
    3030// 20100409  M. Kelsey -- Drop unused string argument from ctors.
    3131// 20100519  M. Kelsey -- Add public access to G4DynamicParticle content
     32// 20100715  M. Kelsey -- Add setKineticEnergy() function
     33// 20100915  M. Kelsey -- Add constructor to copy G4DynamicParticle input
    3234
    3335#ifndef G4INUCL_PARTICLE_HH
     
    4244public:
    4345  G4InuclParticle() : modelId(0) {}
     46
     47  explicit G4InuclParticle(const G4DynamicParticle& dynPart)
     48    : pDP(dynPart), modelId(0) {}
    4449
    4550  explicit G4InuclParticle(const G4LorentzVector& mom) : modelId(0) {
     
    6065  // These are call-throughs to G4DynamicParticle
    6166  void setMomentum(const G4LorentzVector& mom);
     67
     68  void setKineticEnergy(G4double ekin) { pDP.SetKineticEnergy(ekin*GeV/MeV); }
    6269
    6370  void setMass(G4double mass) { pDP.SetMass(mass*GeV/MeV); }
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclParticleNames.hh

    r1337 r1340  
    2525//
    2626// $Id: G4InuclParticleNames.hh,v 1.3 2010/06/25 09:43:30 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// Defines enums to map G4InuclElementaryParticle type codes to human
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4InuclSpecialFunctions.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclSpecialFunctions.hh,v 1.17 2010/06/25 09:43:32 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclSpecialFunctions.hh,v 1.18 2010/09/14 17:51:36 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3232//              cbrt() cube-root function (in math.h, but not in <math>!)
    3333// 20100412  M. Kelsey -- Modify paraMaker[Truncated] to take buffer as argument
     34// 20100914  M. Kelsey -- Migrate to integer A and Z.  Discard unused binding
     35//              energy functions
    3436
    3537#ifndef G4INUCL_SPECIAL_FUNC_HH
     
    4244
    4345namespace G4InuclSpecialFunctions {
     46  G4double bindingEnergy(G4int A, G4int Z);
    4447
    45   G4double bindingEnergyExact(G4double A,
    46                               G4double Z);
     48  // NOTE:  Used only by G4Fissioner
     49  G4double bindingEnergyAsymptotic(G4int A, G4int Z);
    4750
    48   G4double bindingEnergyKummel(G4double A,
    49                                G4double Z);
    50 
    51   G4double bindingEnergy(G4double A,
    52                          G4double Z);
    53 
    54   G4double bindingEnergyAsymptotic(G4double A,
    55                                    G4double Z);
    56 
    57   G4double FermiEnergy(G4double A,
    58                        G4double Z,
    59                        G4int ntype);
     51  G4double FermiEnergy(G4int A, G4int Z, G4int ntype);
    6052 
     53  // NOTE:  Passing Z as double here, to be used as interpolation argument
    6154  void paraMaker(G4double Z, std::pair<std::vector<G4double>, std::vector<G4double> >& parms);
    6255
    6356  void paraMakerTruncated(G4double Z, std::pair<G4double, G4double>& parms);
    6457
    65   G4double getAL(G4double A);
     58  G4double getAL(G4int A);
    6659 
    6760  G4double csNN(G4double e);
     
    7972  std::pair<G4double, G4double> randomCOS_SIN();
    8073
    81   G4double nucleiLevelDensity(G4double a);
     74  G4double nucleiLevelDensity(G4int A);
    8275
    8376  // Optional mass argument will be used to fill G4LorentzVector correctly
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4KaonHypSampler.hh

    r1337 r1340  
    2525//
    2626// $Id: G4KaonHypSampler.hh,v 1.2 2010/06/25 09:43:34 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100512  M. Kelsey -- Replaces (old, untemplated) G4CascadeSampler
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4LorentzConvertor.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4LorentzConvertor.hh,v 1.15.2.1 2010/06/25 09:43:36 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4LorentzConvertor.hh,v 1.17 2010/09/15 20:16:16 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100108  Michael Kelsey -- Use G4LorentzVector internally
     
    3130// 20100126  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
    3231// 20100519  M. Kelsey -- Add interfaces to pass G4InuclParticles directly
     32// 20100616  M. Kelsey -- Report bullet and target four-momenta when set
     33// 20100915  M. Kelsey -- Move constructors to .cc file, add initializers
    3334
    3435#ifndef G4LORENTZ_CONVERTOR_HH
     
    4243
    4344class G4LorentzConvertor {
    44 
    4545public:
    46 
    4746  G4LorentzConvertor();
    4847
    4948  G4LorentzConvertor(const G4LorentzVector& bmom, G4double bmass,
    50                      const G4LorentzVector& tmom, G4double tmass) {
    51     setBullet(bmom, bmass);
    52     setTarget(tmom, tmass);
    53   }
     49                     const G4LorentzVector& tmom, G4double tmass);
    5450
    5551  G4LorentzConvertor(const G4InuclParticle* bullet,
    56                      const G4InuclParticle* target) {
    57     setBullet(bullet);
    58     setTarget(target);
    59   }
     52                     const G4InuclParticle* target);
    6053
    6154  void setVerbose(G4int vb=0) { verboseLevel = vb; }
     
    6861
    6962  // Use correct four-vectors as input
    70   void setBullet(const G4LorentzVector& bmom) { bullet_mom = bmom; }
    71   void setTarget(const G4LorentzVector& bmom) { target_mom = bmom; }
     63  void setBullet(const G4LorentzVector& bmom) {
     64    bullet_mom = bmom;
     65    if (verboseLevel > 3) printBullet();
     66  }
    7267
    73   // NOTE:  These functions "repair" input 4-vectors using specified mass
     68  void setTarget(const G4LorentzVector& bmom) {
     69    target_mom = bmom;
     70    if (verboseLevel > 3) printTarget();
     71  }
     72
     73  // These functions "repair" input 4-vectors using specified mass
    7474  void setBullet(const G4LorentzVector& bmom, G4double bmass) {
    7575    bullet_mom.setVectM(bmom.vect(), bmass);
    76 
    77     //  G4cout << " bullet: e " << bullet_mom.e() << " mass "
    78     //         << bullet_mom.m() << G4endl;
    79   };
    80 
     76    if (verboseLevel > 3) printBullet();
     77  }
     78 
    8179  void setTarget(const G4LorentzVector& tmom, G4double tmass) {
    8280    target_mom.setVectM(tmom.vect(), tmass);
    83 
    84     //  G4cout << " target: e " << target_mom.e() << " mass "
    85     //         << target_mom.m() << G4endl;
    86   };
     81    if (verboseLevel > 3) printTarget();
     82  }
    8783
    8884  void toTheCenterOfMass();
     
    109105  G4bool trivial() const { return degenerated; }
    110106
     107  // Reporting functions for diagnostics
     108  void printBullet() const;
     109  void printTarget() const;
     110
    111111private:
    112112  static const G4double small;
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4NonEquilibriumEvaporator.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4NonEquilibriumEvaporator.hh,v 1.11 2010/06/25 09:43:38 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4NonEquilibriumEvaporator.hh,v 1.13 2010/09/14 17:51:36 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100315  M. Kelsey -- Remove "using" directive and unnecessary #includes.
    3030// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
    3131// 20100517  M. Kelsey -- Inherit from common base class
     32// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
     33// 20100914  M. Kelsey -- Migrate to integer A and Z
    3234
    3335#ifndef G4NON_EQUILIBRIUM_EVAPORATOR_HH
    3436#define G4NON_EQUILIBRIUM_EVAPORATOR_HH
    3537
    36 #include "G4VCascadeCollider.hh"
     38#include "G4CascadeColliderBase.hh"
    3739
    3840class G4CollisionOutput;
    3941class G4InuclParticle;
    4042
    41 class G4NonEquilibriumEvaporator : public G4VCascadeCollider {
     43class G4NonEquilibriumEvaporator : public G4CascadeColliderBase {
    4244public:
    4345  G4NonEquilibriumEvaporator();
     
    4850
    4951private:
    50   G4double getMatrixElement(G4double A) const;
    51   G4double getE0(G4double A) const;
    52   G4double getParLev(G4double A, G4double Z) const;
     52  G4double getMatrixElement(G4int A) const;
     53  G4double getE0(G4int A) const;
     54  G4double getParLev(G4int A, G4int Z) const;
    5355};
    5456
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4NuclWatcher.hh

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4NuclWatcher.hh,v 1.14 2010/06/25 09:43:40 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4NuclWatcher.hh,v 1.15 2010/10/14 20:55:10 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100202  M. Kelsey -- Move most code into .cc file
    3030// 20100405  M. Kelsey -- Pass const-ref std::vector<>
     31// 20101010  M. Kelsey -- Migrate to integer A and Z
    3132
    3233#ifndef G4NUCL_WATCHER_HH
     
    4142class G4NuclWatcher {
    4243public:
    43   G4NuclWatcher(G4double z,
     44  G4NuclWatcher(G4int z,
    4445                const std::vector<G4double>& expa,
    4546                const std::vector<G4double>& expcs,
     
    5051  ~G4NuclWatcher() {}
    5152
    52   void watch(G4double a, G4double z);
     53  void watch(G4int a, G4int z);
    5354  void setInuclCs(G4double csec, G4int nev);
    5455
     
    6970
    7071private:
    71   G4double nuclz;
     72  G4int nuclz;
    7273  G4double izotop_chsq;
    7374  G4double average_ratio;
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4NucleiModel.hh

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4NucleiModel.hh,v 1.25.2.1 2010/06/25 09:43:42 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4NucleiModel.hh,v 1.30 2010/09/14 17:51:36 mkelsey Exp $
     26// GEANT4 tag: $Name: geant4-09-03-ref-09 $
    2827//
    2928// 20100319  M. Kelsey -- Remove "using" directory and unnecessary #includes,
     
    4039//              absorptionCrossSection() from SpecialFunc.
    4140// 20100520  M. Kelsey -- Add function to separate momentum from nucleon
     41// 20100617  M. Kelsey -- Add setVerboseLevel() function, add generateModel()
     42//              with particle input, and ctor with A/Z input.
     43// 20100715  M. Kelsey -- Add G4InuclNuclei object for use with balance checks
     44// 20100723  M. Kelsey -- Move G4CollisionOutput buffer, along with all
     45//              std::vector<> buffers, here for reuse
     46// 20100914  M. Kelsey -- Migrate to integer A and Z
    4247
    4348#ifndef G4NUCLEI_MODEL_HH
     
    4651#include "G4InuclElementaryParticle.hh"
    4752#include "G4CascadParticle.hh"
     53#include "G4CollisionOutput.hh"
    4854#include <algorithm>
    4955#include <vector>
     
    5359
    5460class G4NucleiModel {
    55 
    5661public:
    57 
    5862  G4NucleiModel();
    59   G4NucleiModel(G4InuclNuclei* nuclei);
    60 
    61   void generateModel(G4double a, G4double z);
     63  G4NucleiModel(G4int a, G4int z);
     64  explicit G4NucleiModel(G4InuclNuclei* nuclei);
     65
     66  ~G4NucleiModel() {}
     67
     68  void setVerboseLevel(G4int verbose) { verboseLevel = verbose; }
     69
     70  void generateModel(G4InuclNuclei* nuclei);
     71  void generateModel(G4int a, G4int z);
    6272
    6373  void reset() {
     
    6676  }
    6777
    68 
    6978  void printModel() const;
    70 
    7179
    7280  G4double getDensity(G4int ip, G4int izone) const {
     
    94102
    95103
    96   G4double getNumberOfNeutrons() const {
     104  G4int getNumberOfNeutrons() const {
    97105    return neutronNumberCurrent;
    98106  }
    99107
    100108
    101   G4double getNumberOfProtons() const {
     109  G4int getNumberOfProtons() const {
    102110    return protonNumberCurrent;
    103111  }
     
    166174  G4double getRatio(G4int ip) const;
    167175
     176  // Buffers for processing interactions on each cycle
    168177  std::vector<G4CascadParticle> outgoing_cparticles;    // Return buffer
     178  G4CollisionOutput EPCoutput;          // For N-body inelastic collisions
     179
     180  std::vector<G4InuclElementaryParticle> qdeutrons;     // For h+(NN) trials
     181  std::vector<G4double> acsecs;
     182   
     183  std::vector<G4ThreeVector> coordinates;       // for initializeCascad()
     184  std::vector<G4LorentzVector> momentums;
     185  std::vector<G4InuclElementaryParticle> raw_particles;
    169186
    170187  std::vector<std::vector<G4double> > nucleon_densities;
    171 
    172188  std::vector<std::vector<G4double> > zone_potentials;
    173 
    174189  std::vector<std::vector<G4double> > fermi_momenta;
    175 
    176190  std::vector<G4double> zone_radii;
    177 
    178191  std::vector<G4double> binding_energies;
    179 
    180192  G4double nuclei_radius;
    181 
    182193  G4int number_of_zones;
    183194
    184   G4double A;
    185   G4double Z;
    186 
    187   G4double neutronNumber;
    188   G4double protonNumber;
    189 
    190   G4double neutronNumberCurrent;
    191   G4double protonNumberCurrent;
     195  G4int A;
     196  G4int Z;
     197  G4InuclNuclei* theNucleus;
     198
     199  G4int neutronNumber;
     200  G4int protonNumber;
     201
     202  G4int neutronNumberCurrent;
     203  G4int protonNumberCurrent;
    192204
    193205  G4int current_nucl1;
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4ParticleLargerBeta.hh

    r1337 r1340  
    2525//
    2626// $Id: G4ParticleLargerBeta.hh,v 1.7 2010/06/25 09:43:44 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100112  M. Kelsey -- Add additional operator() which uses pointers,
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4ParticleLargerEkin.hh

    r1337 r1340  
    2525//
    2626// $Id: G4ParticleLargerEkin.hh,v 1.12 2010/06/25 09:43:46 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// Implements a *reverse* sorting: std::sort expects a less-than operator
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4PionNucSampler.hh

    r1337 r1340  
    2525//
    2626// $Id: G4PionNucSampler.hh,v 1.2 2010/06/25 09:43:48 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100512  M. Kelsey -- Replaces G4FinalStateSampler
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4UnboundPN.hh

    r1337 r1340  
    2525//
    2626// $Id: G4UnboundPN.hh,v 1.4 2010/06/25 09:43:52 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4VCascadeCollider.hh

    r1337 r1340  
     1#ifndef G4V_CASCADE_COLLIDER_HH
     2#define G4V_CASCADE_COLLIDER_HH
    13//
    24// ********************************************************************
     
    2325// * acceptance of all terms of the Geant4 Software license.          *
    2426// ********************************************************************
     27// $Id: G4VCascadeCollider.hh,v 1.4 2010/07/14 15:41:12 mkelsey Exp $
     28// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2529//
    26 // $Id: G4VCascadeCollider.hh,v 1.1.2.1 2010/06/25 09:43:54 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
    28 
    29 #ifndef G4V_CASCADE_COLLIDER_HH
    30 #define G4V_CASCADE_COLLIDER_HH
     30// 20100615  M. Kelsey -- Split constructor to have verbose separately
     31// 20100711  M. Kelsey -- Allow name to be changed after ctor, by self
     32// 20100714  M. Kelsey -- Move concrete functions to G4CascadeColliderBase
    3133
    3234#include "globals.hh"
    33 #include "G4InteractionCase.hh"
    3435
    35 class G4InuclNuclei;
    3636class G4InuclParticle;
    3737class G4CollisionOutput;
     
    3939class G4VCascadeCollider {
    4040public:
    41   G4VCascadeCollider(const char* name="G4VCascadeCollider", G4int verbose=0);
     41  G4VCascadeCollider(const char* name, G4int verbose=0);
    4242
    4343  virtual ~G4VCascadeCollider() {}
     
    5151  const char* theName;
    5252  G4int verboseLevel;
    53   G4InteractionCase interCase;          // Determine bullet vs. target
    5453
    55   // Decide whether to use G4ElementaryParticleCollider or not
    56   virtual G4bool useEPCollider(G4InuclParticle* bullet,
    57                                G4InuclParticle* target) const;
    58 
    59   // Decide whether to use G4BigBanger or not
    60   virtual G4bool explosion(G4InuclNuclei* target) const;
    61 
    62   // Decide whether to use G4IntraNuclearCascader or not
    63   virtual G4bool inelasticInteractionPossible(G4InuclParticle* bullet,
    64                                               G4InuclParticle* target,
    65                                               G4double ekin) const;
     54  virtual void setName(const char* name) { theName = name; }
    6655};       
    6756
  • trunk/source/processes/hadronic/models/cascade/cascade/include/G4WatcherGun.hh

    r1337 r1340  
    2525//
    2626// $Id: G4WatcherGun.hh,v 1.10 2010/06/25 09:43:56 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100407  M. Kelsey -- Return const-ref to avoid copy overhead.
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4Analyser.cc

    r1315 r1340  
    2424// ********************************************************************
    2525//
     26// $Id: G4Analyser.cc,v 1.24 2010/10/19 19:48:15 mkelsey Exp $
     27//
     28// 20100726  M. Kelsey -- Use references for fetched lists
     29// 20101010  M. Kelsey -- Migrate to integer A and Z
     30// 20101019  M. Kelsey -- CoVerity report, unitialized constructor
     31
    2632#include "G4Analyser.hh"
    2733#include <cmath>
     
    2935
    3036G4Analyser::G4Analyser()
    31   :verboseLevel(0)  {
    32 
     37  : verboseLevel(0), eventNumber(0.0), averageMultiplicity(0.0),
     38    averageProtonNumber(0.0), averageNeutronNumber(0.0),
     39    averagePionNumber(0.0),  averageNucleonKinEnergy(0.0),
     40    averageProtonKinEnergy(0.0), averageNeutronKinEnergy(0.0),
     41    averagePionKinEnergy(0.0), averageExitationEnergy(0.0),
     42    averageOutgoingNuclei(0.0), fissy_prob(0.0), averagePionPl(0.0),
     43    averagePionMin(0.0), averagePion0(0.0), averageA(0.0), averageZ(0.0),
     44    inel_csec(0.0), withNuclei(false) {
    3345  if (verboseLevel > 3) {
    3446    G4cout << " >>> G4Analyser::G4Analyser" << G4endl;
    3547  }
    36 
    37   eventNumber = 0.0;
    38   averageMultiplicity = 0.0;
    39   averageNucleonKinEnergy = 0.0;
    40   averageProtonKinEnergy = 0.0;
    41   averageNeutronKinEnergy = 0.0;
    42   averagePionKinEnergy = 0.0;
    43   averageProtonNumber = 0.0;
    44   averageNeutronNumber = 0.0;
    45   averagePionNumber = 0.0;
    46   averageExitationEnergy = 0.0;
    47   averageNucleiFragments = 0.0;
    48   averagePionPl = 0.0;
    49   averagePionMin = 0.0;
    50   averagePion0 = 0.0;
    51   averageA = 0.0;
    52   averageZ = 0.0;
    53  
    54   withNuclei = false;
    55   fissy_prob = 0.0;
    56 }
    57 
    58 void G4Analyser::setInelCsec(G4double csec,
    59                              G4bool withn) {
     48}
     49
     50void G4Analyser::setInelCsec(G4double csec, G4bool withn) {
    6051
    6152  if (verboseLevel > 3) {
     
    8374}
    8475
    85 void G4Analyser::try_watchers(G4double a,
    86                               G4double z,
    87                               G4bool if_nucl) {
     76void G4Analyser::try_watchers(G4int a, G4int z, G4bool if_nucl) {
    8877
    8978  if (verboseLevel > 3) {
     
    112101
    113102  if (withNuclei) {
    114     std::vector<G4InuclNuclei> nucleus = output.getNucleiFragments();
     103    const std::vector<G4InuclNuclei>& nucleus = output.getOutgoingNuclei();
    115104
    116105    //    if (nucleus.size() >= 0) {
    117106    if (nucleus.size() > 0) {
    118107      G4int nbig = 0;
    119       averageNucleiFragments += nucleus.size();
     108      averageOutgoingNuclei += nucleus.size();
    120109
    121110      for (G4int in = 0; in < G4int(nucleus.size()); in++) {
    122111        averageExitationEnergy += nucleus[in].getExitationEnergy();
    123112
    124         G4double a = nucleus[in].getA();
    125         G4double z = nucleus[in].getZ();
     113        G4int a = nucleus[in].getA();
     114        G4int z = nucleus[in].getZ();
    126115
    127116        if (in == 0) {
     
    130119        };
    131120
    132         if (a > 10.0) nbig++;
     121        if (a > 10) nbig++;
    133122        try_watchers(a, z, true);
    134123      };
     
    136125      if (nbig > 1) fissy_prob += 1.0;
    137126      eventNumber += 1.0;
    138       std::vector<G4InuclElementaryParticle> particles = output.getOutgoingParticles();
     127      const std::vector<G4InuclElementaryParticle>& particles =
     128        output.getOutgoingParticles();
    139129      averageMultiplicity += particles.size();
    140130
    141131      for (G4int i = 0; i < G4int(particles.size()); i++) {
    142         G4double ap = 0.0;
    143         G4double zp = 0.0;
     132        G4int ap = 0;
     133        G4int zp = 0;
    144134
    145135        if (particles[i].nucleon()) {
     
    147137
    148138          if (particles[i].type() == 1) {
    149             zp = 1.0;
    150             ap = 1.0;
     139            zp = 1;
     140            ap = 1;
    151141            averageProtonNumber += 1.0;
    152142            averageProtonKinEnergy += particles[i].getKineticEnergy();
    153143
    154144          } else {
    155             ap = 1.0;
    156             zp = 0.0;
     145            ap = 1;
     146            zp = 0;
    157147            averageNeutronNumber += 1.0;
    158148            averageNeutronKinEnergy += particles[i].getKineticEnergy();
     
    162152          averagePionKinEnergy += particles[i].getKineticEnergy();
    163153          averagePionNumber += 1.0;
    164           ap = 0.0;
     154          ap = 0;
    165155
    166156          if (particles[i].type() == 3) {
    167             zp = 1.0;
     157            zp = 1;
    168158            averagePionPl += 1.0;
    169159
    170160          } else if (particles[i].type() == 5) { 
    171             zp = -1.0;
     161            zp = -1;
    172162            averagePionMin += 1.0;
    173163
    174164          } else if (particles[i].type() == 7) {
    175             zp = 0.0;
     165            zp = 0;
    176166            averagePion0 += 1.0;
    177167          };
     
    183173  } else {
    184174    eventNumber += 1.0;
    185     std::vector<G4InuclElementaryParticle> particles = output.getOutgoingParticles();
     175    const std::vector<G4InuclElementaryParticle>& particles =
     176      output.getOutgoingParticles();
    186177    averageMultiplicity += particles.size();
    187178
     
    230221    G4cout                 
    231222      << " average Exitation Energy " <<
    232       averageExitationEnergy / averageNucleiFragments << G4endl
    233       << " average num of fragments " << averageNucleiFragments / eventNumber << G4endl;
     223      averageExitationEnergy / averageOutgoingNuclei << G4endl
     224      << " average num of fragments " << averageOutgoingNuclei / eventNumber << G4endl;
    234225    G4cout << " fission prob. " << fissy_prob / eventNumber << " c.sec " <<
    235226      inel_csec * fissy_prob / eventNumber << G4endl;
     
    265256      << " average Z " << averageZ / eventNumber << G4endl                 
    266257      << " average Exitation Energy " <<
    267       averageExitationEnergy / averageNucleiFragments << G4endl
    268       << " average num of fragments " << averageNucleiFragments / eventNumber << G4endl;
     258      averageExitationEnergy / averageOutgoingNuclei << G4endl
     259      << " average num of fragments " << averageOutgoingNuclei / eventNumber << G4endl;
    269260    G4cout << " fission prob. " << fissy_prob / eventNumber << " c.sec " <<
    270261      inel_csec * fissy_prob / eventNumber << G4endl;
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4BigBanger.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4BigBanger.cc,v 1.30 2010/06/25 09:43:58 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4BigBanger.cc,v 1.40 2010/09/28 20:15:00 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3434// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
    3535// 20100517  M. Kelsey -- Inherit from common base class, clean up code
     36// 20100628  M. Kelsey -- Use old "bindingEnergy" fn as wrapper, add balance
     37//              checking after bang.
     38// 20100630  M. Kelsey -- Just do simple boost for target, instead of using
     39//              G4LorentzConverter with dummy bullet.
     40// 20100701  M. Kelsey -- Re-throw momentum list, not just angles!
     41// 20100714  M. Kelsey -- Move conservation checking to base class
     42// 20100726  M. Kelsey -- Move std::vector<> buffer to .hh file
     43// 20100923  M. Kelsey -- Migrate to integer A and Z
    3644
    3745#include "G4BigBanger.hh"
     
    4149#include "G4InuclSpecialFunctions.hh"
    4250#include "G4ParticleLargerEkin.hh"
    43 #include "G4LorentzConvertor.hh"
    44 #include "G4HadTmpUtil.hh"
    45 #include "G4NucleiProperties.hh"
    4651#include <algorithm>
    4752
     
    5055typedef std::vector<G4InuclElementaryParticle>::iterator particleIterator;
    5156
    52 G4BigBanger::G4BigBanger() : G4VCascadeCollider("G4BigBanger") {}
     57G4BigBanger::G4BigBanger() : G4CascadeColliderBase("G4BigBanger") {}
    5358
    5459void
     
    5661                     G4CollisionOutput& output) {
    5762
    58   if (verboseLevel > 3) {
    59     G4cout << " >>> G4BigBanger::collide" << G4endl;
    60   }
     63  if (verboseLevel) G4cout << " >>> G4BigBanger::collide" << G4endl;
    6164
    6265  // primitive explosion model A -> nucleons to prevent too exotic evaporation
    63 
    64   const G4double small_ekin = 1.0e-6;
    65 
    66   G4LorentzVector totscm;
    67   G4LorentzVector totlab;
    6866
    6967  G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target);
     
    7371  }
    7472
    75   G4double A = nuclei_target->getA();
    76   G4double Z = nuclei_target->getZ();
     73  G4int A = nuclei_target->getA();
     74  G4int Z = nuclei_target->getZ();
     75
    7776  G4LorentzVector PEX = nuclei_target->getMomentum();
    7877  G4double EEXS = nuclei_target->getExitationEnergy();
    79   G4InuclElementaryParticle dummy(small_ekin, 1);
    80   G4LorentzConvertor toTheNucleiSystemRestFrame;
    81  
    82   toTheNucleiSystemRestFrame.setBullet(dummy);
    83   toTheNucleiSystemRestFrame.setTarget(nuclei_target);
    84   toTheNucleiSystemRestFrame.toTheTargetRestFrame();
    85  
    86   G4double etot = (EEXS - G4NucleiProperties::GetBindingEnergy(G4lrint(A), G4lrint(Z) ) ) * MeV/GeV;  // To Bertini units
     78
     79  G4ThreeVector toTheLabFrame = PEX.boostVector();      // From rest to lab
     80
     81  // This "should" be difference between E-target and sum of m(nucleons)
     82  G4double etot = (EEXS - bindingEnergy(A,Z)) * MeV/GeV;  // To Bertini units
    8783  if (etot < 0.0) etot = 0.0;
    8884 
     
    9086    G4cout << " BigBanger: target " << G4endl;
    9187    nuclei_target->printParticle();
    92     G4cout << " BigBanger: a " << A << " z " << Z << " eexs " << EEXS << " etot " <<
    93       etot << " nm " << nuclei_target->getMass() << G4endl;
    94   }
    95  
     88    G4cout << " etot " << etot << G4endl;
     89  }
     90
     91  if (verboseLevel > 3) {
     92    G4LorentzVector PEXrest = PEX;
     93    PEXrest.boost(-toTheLabFrame);
     94    G4cout << " target rest frame: px " << PEXrest.px() << " py "
     95           << PEXrest.py() << " pz " << PEXrest.pz() << " E " << PEXrest.e()
     96           << G4endl;
     97  }
     98
    9699  generateBangInSCM(etot, A, Z);
    97100 
     
    102105  }
    103106
    104   if(!particles.empty()) { // convert back to Lab
    105     particleIterator ipart;
    106    
    107     for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
    108       if (verboseLevel > 2) {
    109         totscm += ipart->getMomentum();
    110       }
    111       G4LorentzVector mom =
    112         toTheNucleiSystemRestFrame.backToTheLab(ipart->getMomentum());
    113       ipart->setMomentum(mom);
    114      
    115       if (verboseLevel > 2) {
    116         mom = ipart->getMomentum();
    117         totlab += mom;
    118       }
    119     }
    120 
    121     std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
    122 
    123     if (verboseLevel > 2) {
    124       G4cout << " In SCM: total outgoing momentum " << G4endl
    125              << " E " << totscm.e() << " px " << totscm.x()
    126              << " py " << totscm.y() << " pz " << totscm.z() << G4endl;
    127       G4cout << " In Lab: mom cons " << G4endl
    128              << " E " << PEX.e() + 0.001 * EEXS - totlab.e()
    129              << " px " << PEX.x() - totlab.x()
    130              << " py " << PEX.y() - totlab.y()
    131              << " pz " << PEX.z() - totlab.z() << G4endl;
    132     }
     107  if (particles.empty()) {      // No bang!  Don't know why...
     108    G4cerr << " >>> G4BigBanger unable to process fragment "
     109           << nuclei_target->getDefinition()->GetParticleName() << G4endl;
     110
     111    // FIXME:  This will violate baryon number, momentum, energy, etc.
     112    return;
     113  }
     114
     115  // convert back to Lab
     116  G4LorentzVector totscm;
     117  G4LorentzVector totlab;
     118
     119  if (verboseLevel > 2) G4cout << " BigBanger: boosting to lab" << G4endl;
     120
     121  particleIterator ipart;
     122  for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
     123    G4LorentzVector mom = ipart->getMomentum();
     124    if (verboseLevel > 2) totscm += mom;
     125
     126    mom.boost(toTheLabFrame);
     127    if (verboseLevel > 2) totlab += mom;
     128
     129    ipart->setMomentum(mom);
     130    if (verboseLevel > 2) ipart->printParticle();
     131  }
     132 
     133  std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
     134
     135  validateOutput(0, target, particles);         // Checks <vector> directly
     136 
     137  if (verboseLevel > 2) {
     138    G4cout << " In SCM: total outgoing momentum " << G4endl
     139           << " E " << totscm.e() << " px " << totscm.x()
     140           << " py " << totscm.y() << " pz " << totscm.z() << G4endl;
     141    G4cout << " In Lab: mom cons " << G4endl
     142           << " E " << PEX.e() - totlab.e()     // PEX now includes EEXS
     143           << " px " << PEX.x() - totlab.x()
     144           << " py " << PEX.y() - totlab.y()
     145           << " pz " << PEX.z() - totlab.z() << G4endl;
    133146  }
    134147
    135148  output.addOutgoingParticles(particles);
    136 
    137   return;
    138149}                   
    139150
    140 void G4BigBanger::generateBangInSCM(G4double etot, G4double a, G4double z) {
     151void G4BigBanger::generateBangInSCM(G4double etot, G4int a, G4int z) {
    141152  if (verboseLevel > 3) {
    142153    G4cout << " >>> G4BigBanger::generateBangInSCM" << G4endl;
    143154  }
    144155
    145   // Proton and neutron masses
    146   const G4double mp = G4InuclElementaryParticle::getParticleMass(1);
    147   const G4double mn = G4InuclElementaryParticle::getParticleMass(2);
    148 
    149156  const G4double ang_cut = 0.9999;
    150157  const G4int itry_max = 1000;
    151158 
    152   G4int ia = int(a + 0.1);
    153   G4int iz = int(z + 0.1);
    154 
    155   if (verboseLevel > 2) {
    156     G4cout << " ia " << ia << " iz " << iz << G4endl;
     159  if (verboseLevel > 2) {
     160    G4cout << " a " << a << " z " << z << G4endl;
    157161  }
    158162
    159163  particles.clear();    // Reset output vector before filling
    160164 
    161   if(ia == 1) {
    162     // abnormal situation
    163     G4double m = iz > 0 ? mp : mn;
    164     G4double pmod = std::sqrt((etot + 2.0 * m) * etot);
    165     G4LorentzVector mom = generateWithRandomAngles(pmod, m);
    166 
    167     G4int knd = iz > 0 ? 1 : 2;
    168 
    169     particles.push_back(G4InuclElementaryParticle(mom, knd, 8)); // modelId included
    170 
     165  if (a == 1) {         // Special -- bare nucleon doesn't really "explode"
     166    G4int knd = (z>0) ? 1 : 2;
     167    particles.push_back(G4InuclElementaryParticle(knd)); // zero momentum
    171168    return;
    172   }
     169  }
    173170     
    174   generateMomentumModules(etot, a, z);
     171  // NOTE:  If distribution fails, need to regenerate magnitudes and angles!
     172  //*** generateMomentumModules(etot, a, z);
     173
     174  scm_momentums.reserve(a);
     175  G4LorentzVector tot_mom;
     176
    175177  G4bool bad = true;
    176178  G4int itry = 0;
    177 
    178179  while(bad && itry < itry_max) {
    179180    itry++;
    180     std::vector<G4LorentzVector> scm_momentums;
    181     G4LorentzVector tot_mom;
    182 
    183     if(ia == 2) {
    184       // FIXME:  This isn't actually a correct four-vector, wrong mass!
     181    scm_momentums.clear();
     182
     183    generateMomentumModules(etot, a, z);
     184    if (a == 2) {
     185      // This is only a three-vector, not a four-vector
    185186      G4LorentzVector mom = generateWithRandomAngles(momModules[0]);
    186 
    187       tot_mom += mom;           
    188 
    189187      scm_momentums.push_back(mom);
    190 
    191       G4LorentzVector mom1 = -mom;
    192 
    193       scm_momentums.push_back(mom1); 
     188      scm_momentums.push_back(-mom);    // Only safe since three-vector!
    194189      bad = false;
    195190    } else {
    196       for(G4int i = 0; i < ia - 2; i++) {
    197         // FIXME:  This isn't actually a correct four-vector, wrong mass!
     191      tot_mom *= 0.;            // Easy way to reset accumulator
     192
     193      for(G4int i = 0; i < a-2; i++) {          // All but last two are thrown
     194      // This is only a three-vector, not a four-vector
    198195        G4LorentzVector mom = generateWithRandomAngles(momModules[i]);
    199 
     196        scm_momentums.push_back(mom);
    200197        tot_mom += mom;         
    201 
    202         scm_momentums.push_back(mom);
    203198      };
    204199
    205200      //                handle last two
    206201      G4double tot_mod = tot_mom.rho();
    207       G4double ct = -0.5 * (tot_mod * tot_mod + momModules[ia - 2] * momModules[ia - 2] -
    208                             momModules[ia - 1] * momModules[ia - 1]) / tot_mod / momModules[ia - 2];
    209 
    210       if (verboseLevel > 2) {
    211         G4cout << " ct last " << ct << G4endl;
    212       }
     202      G4double ct = -0.5*(tot_mod*tot_mod + momModules[a-2]*momModules[a-2]
     203                          - momModules[a-1]*momModules[a-1]) / tot_mod
     204        / momModules[a-2];
     205
     206      if (verboseLevel > 2) G4cout << " ct last " << ct << G4endl;
    213207 
    214208      if(std::fabs(ct) < ang_cut) {
    215         // FIXME:  These are not actually four-vectors, just three-momenta
    216         G4LorentzVector mom2 = generateWithFixedTheta(ct, momModules[ia - 2]);
    217         //       rotate to the normal system
     209        // This is only a three-vector, not a four-vector
     210        G4LorentzVector mom2 = generateWithFixedTheta(ct, momModules[a - 2]);
     211
     212        // rotate to the normal system
    218213        G4LorentzVector apr = tot_mom/tot_mod;
    219214        G4double a_tr = std::sqrt(apr.x()*apr.x() + apr.y()*apr.y());
     
    224219
    225220        scm_momentums.push_back(mom);
    226         //               and the last one
    227         G4LorentzVector mom1= - mom - tot_mom;
     221
     222        // and the last one (again, not actually a four-vector!)
     223        G4LorentzVector mom1 = -mom - tot_mom;
     224
    228225        scm_momentums.push_back(mom1); 
    229226        bad = false;
    230       };
    231     };   
    232     if(!bad) {
    233       for(G4int i = 0; i < ia; i++) {
    234         G4int knd = i < iz ? 1 : 2;
    235 
    236         particles.push_back(G4InuclElementaryParticle(scm_momentums[i], knd, 8));
    237       };
     227      } // if (abs(ct) < ang_cut)
     228    }   // (a > 2)
     229  }     // while (bad && itry<itry_max)
     230
     231  if (!bad) {
     232    for(G4int i = 0; i < a; i++) {
     233      G4int knd = i < z ? 1 : 2;
     234      particles.push_back(G4InuclElementaryParticle(scm_momentums[i], knd, 8));
    238235    };
    239   }; 
    240   if (verboseLevel > 2) {
    241     if(itry == itry_max) G4cout << " BigBanger -> can not generate bang " << G4endl;
     236  };
     237
     238  if (verboseLevel > 2) {
     239    if (itry == itry_max) G4cout << " BigBanger -> can not generate bang " << G4endl;
    242240  }
    243241
     
    245243}
    246244           
    247 void G4BigBanger::generateMomentumModules(G4double etot, G4double a, G4double z) {
     245void G4BigBanger::generateMomentumModules(G4double etot, G4int a, G4int z) {
    248246  if (verboseLevel > 3) {
    249247    G4cout << " >>> G4BigBanger::generateMomentumModules" << G4endl;
     
    256254  momModules.clear();           // Reset buffer for filling
    257255
    258   G4int ia = G4int(a + 0.1);
    259   G4int iz = G4int(z + 0.1);
    260 
    261256  G4double xtot = 0.0;
    262   G4double promax = maxProbability(a);
    263  
    264   G4int i;
    265   for(i = 0; i < ia; i++) {
    266     G4double x = generateX(ia, a, promax);
    267 
    268     if (verboseLevel > 2) {
    269       G4cout << " i " << i << " x " << x << G4endl;
     257
     258  if (a > 2) {                  // For "large" nuclei, energy is distributed
     259    G4double promax = maxProbability(a);
     260   
     261    for(G4int i = 0; i < a; i++) {
     262      G4double x = generateX(a, promax);
     263     
     264      if (verboseLevel > 2) {
     265        G4cout << " i " << i << " x " << x << G4endl;
     266      }
     267      momModules.push_back(x);
     268      xtot += x;
    270269    }
    271     momModules.push_back(x);
    272     xtot += x;
    273   };
    274   for(i = 0; i < ia; i++) {
    275     G4double m = i < iz ? mp : mn;
     270  } else {                      // Two-body case is special, must be 50%
     271    xtot = 1.;
     272    momModules.push_back(0.5);
     273    momModules.push_back(0.5);
     274  }
     275
     276  for(G4int i = 0; i < a; i++) {
     277    G4double m = i < z ? mp : mn;
    276278
    277279    momModules[i] = momModules[i] * etot / xtot;
     
    286288}
    287289
    288 G4double G4BigBanger::xProbability(G4double x, G4int ia) const {
    289 
    290 
    291   if (verboseLevel > 3) {
    292     G4cout << " >>> G4BigBanger::xProbability" << G4endl;
    293   }
    294 
    295   G4int ihalf = ia / 2;
     290G4double G4BigBanger::xProbability(G4double x, G4int a) const {
     291  if (verboseLevel > 3) G4cout << " >>> G4BigBanger::xProbability" << G4endl;
     292
    296293  G4double ekpr = 0.0;
    297294
     
    299296    ekpr = x * x;
    300297
    301     if(2 * ihalf == ia) { // even A
    302       ekpr *= std::sqrt(1.0 - x) * std::pow((1.0 - x), G4int(G4double(3 * ia - 6) / 2.0));
     298    if (a%2 == 0) { // even A
     299      ekpr *= std::sqrt(1.0 - x) * std::pow((1.0 - x), (3*a-6)/2);
    303300    }
    304301    else {
    305       ekpr *= std::pow((1.0 - x), G4int(G4double(3 * ia - 5) / 2.0));
     302      ekpr *= std::pow((1.0 - x), (3*a-5)/2);
    306303    };
    307304  };
     
    310307}
    311308
    312 G4double G4BigBanger::maxProbability(G4double a) const {
    313 
     309G4double G4BigBanger::maxProbability(G4int a) const {
    314310  if (verboseLevel > 3) {
    315311    G4cout << " >>> G4BigBanger::maxProbability" << G4endl;
    316312  }
    317313
    318   return xProbability(1.0 / (a - 1.0) / 1.5, G4int(a + 0.1));
    319 }
    320 
    321 G4double G4BigBanger::generateX(G4int ia,
    322                                 G4double a,
    323                                 G4double promax) const {
    324 
    325   if (verboseLevel > 3) {
    326     G4cout << " >>> G4BigBanger::generateX" << G4endl;
    327   }
     314  return xProbability(2./3./(a-1.0), a);
     315}
     316
     317G4double G4BigBanger::generateX(G4int a, G4double promax) const {
     318  if (verboseLevel > 3) G4cout << " >>> G4BigBanger::generateX" << G4endl;
    328319
    329320  const G4int itry_max = 1000;
     
    335326    x = inuclRndm();
    336327
    337     if(xProbability(x, ia) >= promax * inuclRndm()) return x;
     328    if(xProbability(x, a) >= promax * inuclRndm()) return x;
    338329  };
    339330  if (verboseLevel > 2) {
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadParticle.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadParticle.cc,v 1.15 2010/06/25 09:44:00 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadParticle.cc,v 1.18 2010/10/20 14:34:26 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100112  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
    3030// 20100114  M. Kelsey -- Replace vector<G4Double> position with G4ThreeVector
     31// 20101012  M. Kelsey -- Check for negative d2 in getPathToTheNextZone()
    3132
    3233#include "G4CascadParticle.hh"
     
    4546                                                G4double rz_out) {
    4647  if (verboseLevel > 3) {
    47     G4cout << " >>> G4CascadParticle::getPathToTheNextZone" << G4endl;
     48    G4cout << " >>> G4CascadParticle::getPathToTheNextZone rz_in " << rz_in
     49           << " rz_out " << rz_out << G4endl;
    4850  }
    4951
     
    5961  G4double ds;
    6062  G4double d2;
    61  
     63
     64  if (verboseLevel > 3) {
     65    G4cout << " current_zone " << current_zone << " rr " << rr
     66           << " rp " << rp << " pp " << pp << " ra " << ra << G4endl;
     67  }
     68
    6269  if (current_zone == 0 || rp > 0.0) {
    6370    d2 = rz_out * rz_out - ra;
    64     ds = 1.0;
    65     movingIn = false;
     71    if (d2 > 0.0) {
     72      ds = 1.0;
     73      movingIn = false;
     74    } else {
     75      d2 = rz_in * rz_in - ra;
     76      ds = -1.0;
     77      movingIn = true;
     78    }
    6679  } else {
    6780    d2 = rz_in * rz_in - ra;
     
    7588    }
    7689  }
     90
     91  if (verboseLevel > 3) G4cout << " ds " << ds << " d2 " << d2 << G4endl;
    7792
    7893  path = ds * std::sqrt(d2) - rp / pp;
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeChannel.cc

    r1337 r1340  
    2525//
    2626// $Id: G4CascadeChannel.cc,v 1.8 2010/06/25 09:44:02 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100514  M. Kelsey -- All functionality removed except quantum-number
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeInterface.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4CascadeInterface.cc,v 1.77.2.1 2010/06/25 09:44:04 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4CascadeInterface.cc,v 1.104 2010/09/24 21:09:01 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3837//              G4CollisionOutput, copy G4DynamicParticle directly from
    3938//              G4InuclParticle, no switch-block required.
     39// 20100615  M. Kelsey -- Bug fix: For K0's need ekin in GEANT4 units
     40// 20100617  M. Kelsey -- Rename "debug_" preprocessor flag to G4CASCADE_DEBUG,
     41//              and "BERTDEV" to "G4CASCADE_COULOMB_DEV"
     42// 20100617  M. Kelsey -- Make G4InuclCollider a local data member
     43// 20100618  M. Kelsey -- Deploy energy-conservation test on final state, with
     44//              preprocessor flag G4CASCADE_SKIP_ECONS to skip test.
     45// 20100620  M. Kelsey -- Use new energy-conservation pseudo-collider
     46// 20100621  M. Kelsey -- Fix compiler warning from GCC 4.5
     47// 20100624  M. Kelsey -- Fix cascade loop to check nTries every time (had
     48//              allowed for infinite loop on E-violation); dump event data
     49//              to output if E-violation exceeds maxTries; use CheckBalance
     50//              for baryon and charge conservation.
     51// 20100701  M. Kelsey -- Pass verbosity through to G4CollisionOutput
     52// 20100714  M. Kelsey -- Report number of iterations before success
     53// 20100720  M. Kelsey -- Use G4CASCADE_SKIP_ECONS flag for reporting
     54// 20100723  M. Kelsey -- Move G4CollisionOutput to .hh file for reuse
     55// 20100914  M. Kelsey -- Migrate to integer A and Z
     56// 20100916  M. Kelsey -- Simplify ApplyYourself() by encapsulating code blocks
     57//              into numerous functions; make data-member colliders pointers;
     58//              provide support for projectile nucleus
     59// 20100919  M. Kelsey -- Fix incorrect logic in retryInelasticNucleus()
     60// 20100922  M. Kelsey -- Add functions to select de-excitation method
     61// 20100924  M. Kelsey -- Migrate to "OutgoingNuclei" names in CollisionOutput
    4062
    4163#include "G4CascadeInterface.hh"
    4264#include "globals.hh"
     65#include "G4CascadeCheckBalance.hh"
    4366#include "G4CollisionOutput.hh"
    4467#include "G4DynamicParticle.hh"
     68#include "G4HadronicException.hh"
    4569#include "G4InuclCollider.hh"
    4670#include "G4InuclElementaryParticle.hh"
     
    4872#include "G4InuclParticle.hh"
    4973#include "G4InuclParticleNames.hh"
     74#include "G4KaonZeroLong.hh"
    5075#include "G4KaonZeroShort.hh"
    51 #include "G4KaonZeroLong.hh"
    52 #include "G4LorentzRotation.hh"
    5376#include "G4Nucleus.hh"
    5477#include "G4ParticleDefinition.hh"
    5578#include "G4Track.hh"
    5679#include "G4V3DNucleus.hh"
     80#include <cmath>
    5781
    5882using namespace G4InuclParticleNames;
    59 
    60 //#define BERTDEV 1  // A flag to activate a development version of Bertini cascade
    6183
    6284typedef std::vector<G4InuclElementaryParticle>::const_iterator particleIterator;
    6385typedef std::vector<G4InuclNuclei>::const_iterator nucleiIterator;
    6486
    65 G4CascadeInterface::G4CascadeInterface(const G4String& nam)
    66   :G4VIntraNuclearTransportModel(nam), verboseLevel(0) 
    67 {
    68   if (verboseLevel > 3) {
    69     G4cout << " >>> G4CascadeInterface::G4CascadeInterface" << G4endl;
    70   }
    71 
    72 }
    73 
    74 
    75 G4CascadeInterface::~G4CascadeInterface()
    76 {}
    77    
    78 G4ReactionProductVector* G4CascadeInterface::Propagate(G4KineticTrackVector* ,
    79                                                        G4V3DNucleus* ) {
     87
     88// Maximum number of iterations allowed for inelastic collision attempts
     89
     90const G4int G4CascadeInterface::maximumTries = 100;
     91
     92
     93// Constructor and destrutor
     94
     95G4CascadeInterface::G4CascadeInterface(const G4String& name)
     96  : G4VIntraNuclearTransportModel(name),
     97    verboseLevel(0), numberOfTries(0),
     98    collider(new G4InuclCollider),
     99    balance(new G4CascadeCheckBalance(0.05, 0.1, name)),
     100    bullet(0), target(0), output(new G4CollisionOutput) {
     101  initializeElasticCuts();
     102}
     103
     104G4CascadeInterface::~G4CascadeInterface() {
     105  delete collider; collider=0;
     106  delete balance; balance=0;
     107  delete bullet; bullet=0;
     108  delete target; target=0;
     109  delete output; output=0;
     110}
     111
     112// Fill sparse array with minimum momenta for inelastic on hydrogen
     113
     114void G4CascadeInterface::initializeElasticCuts() {
     115  cutElastic[proton   ]   = 1.0;        // Bertini uses GeV for everything
     116  cutElastic[neutron  ]   = 1.0;
     117  cutElastic[pionPlus ]   = 0.6;
     118  cutElastic[pionMinus]   = 0.2;
     119  cutElastic[pionZero ]   = 0.2;
     120  cutElastic[kaonPlus ]   = 0.5;
     121  cutElastic[kaonMinus]   = 0.5;
     122  cutElastic[kaonZero]    = 0.5;
     123  cutElastic[kaonZeroBar] = 0.5;
     124  cutElastic[lambda]      = 1.0;
     125  cutElastic[sigmaPlus]   = 1.0;
     126  cutElastic[sigmaZero]   = 1.0;
     127  cutElastic[sigmaMinus]  = 1.0;
     128  cutElastic[xiZero]      = 1.0;
     129  cutElastic[xiMinus]     = 1.0;
     130}
     131
     132
     133// Select post-cascade processing (default will be CascadeDeexcitation)
     134// NOTE:  Currently just calls through to Collider, in future will do something
     135
     136void G4CascadeInterface::useCascadeDeexcitation() {
     137  collider->useCascadeDeexcitation();
     138}
     139
     140void G4CascadeInterface::usePreCompoundDeexcitation() {
     141  collider->usePreCompoundDeexcitation();
     142}
     143
     144// Main Actions
     145
     146G4ReactionProductVector*
     147G4CascadeInterface::Propagate(G4KineticTrackVector*, G4V3DNucleus* ) {
    80148  return 0;
    81149}
    82150
    83 // #define debug_G4CascadeInterface
    84 
    85 G4HadFinalState* G4CascadeInterface::ApplyYourself(const G4HadProjectile& aTrack,
    86                                                      G4Nucleus& theNucleus) {
    87 #ifdef debug_G4CascadeInterface
     151G4HadFinalState*
     152G4CascadeInterface::ApplyYourself(const G4HadProjectile& aTrack,
     153                                  G4Nucleus& theNucleus) {
     154  if (verboseLevel)
     155    G4cout << " >>> G4CascadeInterface::ApplyYourself" << G4endl;
     156
     157#ifdef G4CASCADE_DEBUG_INTERFACE
    88158  static G4int counter(0);
    89159  counter++;
    90   G4cerr << "Reaction number "<< counter << " "<<aTrack.GetDynamicParticle()->GetDefinition()->GetParticleName()<<" "<< aTrack.GetDynamicParticle()->GetKineticEnergy()<<G4endl;
     160  G4cerr << "Reaction number "<< counter << " "
     161         << aTrack.GetDefinition()->GetParticleName() << " "
     162         << aTrack.GetKineticEnergy() << G4endl;
    91163#endif
    92164
    93165  theResult.Clear();
    94 
    95   if (verboseLevel > 3) {
    96     G4cout << " >>> G4CascadeInterface::ApplyYourself" << G4endl;
    97   };
    98 
    99   G4double eInit     = 0.0;
    100   G4double eTot      = 0.0;
    101   G4double sumBaryon = 0.0;
    102   G4double sumEnergy = 0.0;
    103166
    104167  // Make conversion between native Geant4 and Bertini cascade classes.
    105168  // NOTE: Geant4 units are MeV = 1 and GeV = 1000. Cascade code by default use GeV = 1.
    106169
    107   G4int bulletType;
    108   if (aTrack.GetDefinition() == G4KaonZeroLong::KaonZeroLong() ||
    109       aTrack.GetDefinition() == G4KaonZeroShort::KaonZeroShort() )
    110     bulletType = (G4UniformRand() > 0.5) ? kaonZero : kaonZeroBar;
    111   else
    112     bulletType = G4InuclElementaryParticle::type(aTrack.GetDefinition());
    113 
    114   // Code momentum and energy.
    115   G4LorentzVector projectileMomentum = aTrack.Get4Momentum();
    116   G4LorentzRotation toZ;
    117   toZ.rotateZ(-projectileMomentum.phi());
    118   toZ.rotateY(-projectileMomentum.theta());
    119   G4LorentzRotation toLabFrame = toZ.inverse();
    120 
    121   G4LorentzVector momentumBullet(0., 0., aTrack.GetTotalMomentum()/GeV,
    122                                  aTrack.GetTotalEnergy()/GeV);
    123 
    124   G4InuclElementaryParticle* bullet =
    125     new G4InuclElementaryParticle(momentumBullet, bulletType);
    126 
    127   sumEnergy = bullet->getKineticEnergy(); // In GeV
    128   sumBaryon += bullet->baryon();        // Returns baryon number (0, 1, or 2)
    129 
    130   // Set target
    131   G4InuclNuclei*   target  = 0;
    132   G4InuclParticle* targetH = 0;
    133 
    134   G4double theNucleusA = theNucleus.GetN();
    135 
    136   if ( G4int(theNucleusA) != 1 ) {
    137     target  = new G4InuclNuclei(theNucleusA, theNucleus.GetZ());
    138     eInit = bullet->getEnergy() + target->getEnergy();
    139 
    140     sumBaryon += theNucleusA;
    141 
    142     if (verboseLevel > 2) {
    143       G4cout << "Bullet:  " << G4endl; 
    144       bullet->printParticle();
    145     }
    146     if (verboseLevel > 2) {
    147       G4cout << "Target:  " << G4endl; 
    148       target->printParticle();
    149     }
    150   }
    151 
    152   G4CollisionOutput output;
     170  createBullet(aTrack);
     171  createTarget(theNucleus);
     172
     173  if (verboseLevel > 2) {
     174    G4cout << "Bullet:  " << G4endl; 
     175    bullet->printParticle();
     176    G4cout << "Target:  " << G4endl; 
     177    target->printParticle();
     178  }
    153179
    154180  // Colliders initialisation
    155   G4InuclCollider* collider = new G4InuclCollider;
    156 
    157   G4int  maxTries = 100; // maximum tries for inelastic collision to avoid infinite loop
    158   G4int  nTries   = 0;  // try counter
    159 
    160 #ifdef BERTDEV
    161   G4int coulombOK =0;  // flag for correct Coulomb barrier
    162 #endif
    163   if (G4int(theNucleusA) == 1) { // special treatment for target H(1,1) (proton)
     181  collider->setVerboseLevel(verboseLevel);
     182  balance->setVerboseLevel(verboseLevel);
     183  output->setVerboseLevel(verboseLevel);
     184
     185  numberOfTries = 0;
     186
     187  // special treatment for target H(1,1) (proton)
     188  if (theNucleus.GetA_asInt() == 1) {
     189    G4int btype = dynamic_cast<G4InuclElementaryParticle*>(bullet)->type();
     190
     191    if (bullet->getMomModule() <= cutElastic[btype]) {
     192      collider->collide(bullet, target, *output);       // Only elastic
     193    } else {
     194      do {                      // we try to create inelastic interaction
     195        if (verboseLevel > 1)
     196          G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
     197
     198        output->reset();
     199        collider->collide(bullet, target, *output);
     200        balance->collide(bullet, target, *output);
     201
     202        numberOfTries++;
     203      } while(retryInelasticProton());
     204    }
     205  } else {                      // treat all other targets excepet H(1,1)
     206    do {                        // we try to create inelastic interaction
     207      if (verboseLevel > 1)
     208        G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
     209
     210      output->reset();
     211      collider->collide(bullet, target, *output);
     212      balance->collide(bullet, target, *output);
     213
     214      numberOfTries++;
     215    } while (retryInelasticNucleus());
     216  }
     217
     218  // Check whether repeated attempts have all failed; report and exit
     219  if (numberOfTries >= maximumTries && !balance->okay()) {
     220    throwNonConservationFailure();      // This terminates the job
     221  }
     222
     223  // Successful cascade -- clean up and return
     224  if (verboseLevel) {
     225    G4cout << " Cascade output after trials " << numberOfTries << G4endl;
     226    if (verboseLevel > 1) output->printCollisionOutput();
     227  }
     228
     229  // Rotate event to put Z axis along original projectile direction
     230  output->rotateEvent(bulletInLabFrame);
     231
     232  copyOutputToHadronicResult();
     233
     234  // Report violations of conservation laws in original frame
     235  balance->collide(bullet, target, *output);
     236
     237  if (verboseLevel > 2) {
     238    if (!balance->baryonOkay()) {
     239      G4cerr << "ERROR: no baryon number conservation, sum of baryons = "
     240             << balance->deltaB() << G4endl;
     241    }
     242
     243    if (!balance->chargeOkay()) {
     244      G4cerr << "ERROR: no charge conservation, sum of charges = "
     245             << balance->deltaQ() << G4endl;
     246    }
     247
     248    if (std::abs(balance->deltaKE()) > 0.01 ) { // GeV
     249      G4cerr << "Kinetic energy conservation violated by "
     250             << balance->deltaKE() << " GeV" << G4endl;
     251    }
     252
     253    G4double eInit = bullet->getEnergy() + target->getEnergy();
     254    G4double eFinal = eInit + balance->deltaE();
     255
     256    G4cout << "Initial energy " << eInit << " final energy " << eFinal
     257           << "\nTotal energy conservation at level "
     258           << balance->deltaE() * GeV << " MeV" << G4endl;
    164259   
    165     targetH = new G4InuclElementaryParticle(proton);
    166    
    167     G4float cutElastic[32];
    168    
    169     cutElastic[proton   ] = 1.0; // GeV
    170     cutElastic[neutron  ] = 1.0;
    171     cutElastic[pionPlus ] = 0.6;
    172     cutElastic[pionMinus] = 0.2;
    173     cutElastic[pionZero ] = 0.2;
    174     cutElastic[kaonPlus ] = 0.5;
    175     cutElastic[kaonMinus] = 0.5;
    176     cutElastic[kaonZero] = 0.5;
    177     cutElastic[kaonZeroBar] = 0.5;
    178     cutElastic[lambda] = 1.0;
    179     cutElastic[sigmaPlus] = 1.0;
    180     cutElastic[sigmaZero] = 1.0;
    181     cutElastic[sigmaMinus] = 1.0;
    182     cutElastic[xiZero] = 1.0;
    183     cutElastic[xiMinus] = 1.0;
    184    
    185     if (momentumBullet.z() > cutElastic[bulletType]) { // inelastic collision possible
    186      
    187       do {   // we try to create inelastic interaction
    188         output.reset();
    189         collider->collide(bullet, targetH, output);
    190         nTries++;
    191       } while(
    192               (nTries < maxTries) &&
    193               (output.getOutgoingParticles().size() == 2 && // elastic: bullet + p = H(1,1) coming out
    194                (output.getOutgoingParticles().begin()->type() == bulletType ||
    195                 output.getOutgoingParticles().begin()->type() == proton)
    196                )
    197               );
    198     } else { // only elastic collision is energetically possible
    199       collider->collide(bullet, targetH, output);
    200     }
    201    
    202     sumBaryon += 1;
    203    
    204     eInit = bullet->getEnergy() + targetH->getEnergy();
    205    
    206     if (verboseLevel > 2) {
    207       G4cout << "Target:  " << G4endl;
    208       targetH->printParticle();
    209     }
    210    
    211   } else {  // treat all other targets excepet H(1,1)
    212    
    213     do { // we try to create inelastic interaction
    214 
    215 #ifdef BERTDEV
    216       coulombOK=0;  // by default coulomb analysis is OK
    217 #endif
    218       output.reset();
    219       collider->collide(bullet, target, output);
    220       nTries++;
    221      
    222 #ifdef BERTDEV
    223       G4double coulumbBarrier = 8.7 * MeV;
    224       const std::vector<G4InuclElementaryParticle>& p= output.getOutgoingParticles();
    225       if(!p.empty()) {
    226         for(    particleIterator ipart = p.begin(); ipart != p.end(); ipart++) {
    227           if (ipart->type() == proton) {
    228             G4double e = ipart->getKineticEnergy()*GeV;
    229             if (e < coulumbBarrier) coulombOK= 1; // If event with coulomb barrier violation detected -> retry
    230             //            G4cout << "///AH "<< e << "" << coulumbBarrier <<G4endl;
    231           }
    232         }
    233       }
    234 #endif
    235     } while(
    236             (nTries < maxTries) &&  // conditions for next try
    237             (output.getOutgoingParticles().size()!=0) &&
    238 #ifdef BERTDEV
    239             (coulombOK==1) &&
    240             ((output.getOutgoingParticles().size() + output.getNucleiFragments().size()) > 2.5)
    241 #else
    242             ((output.getOutgoingParticles().size() + output.getNucleiFragments().size()) < 2.5) && 
    243             (output.getOutgoingParticles().begin()->type()==bullet->type())
    244 #endif
    245              );
    246   }
    247 
    248   if (verboseLevel > 1) {
    249     G4cout << " Cascade output: " << G4endl;
    250     output.printCollisionOutput();
    251   }
    252  
    253   // Rotate event to put Z axis along original projectile direction
    254   output.rotateEvent(toLabFrame);
    255 
    256   // Convert cascade data to use hadronics interface
    257   const std::vector<G4InuclNuclei>& nucleiFragments = output.getNucleiFragments();
    258   const std::vector<G4InuclElementaryParticle>& particles = output.getOutgoingParticles();
     260    if (balance->deltaKE() > 5.0e-5 ) {         // 0.05 MeV
     261      G4cerr << "FATAL ERROR: kinetic energy created  "
     262             << balance->deltaKE() * GeV << " MeV" << G4endl;
     263    }
     264  }
     265
     266  delete bullet; bullet=0;
     267  delete target; target=0;
     268
     269  return &theResult;
     270}
     271
     272
     273// Convert input projectile to Bertini internal object
     274
     275void G4CascadeInterface::createBullet(const G4HadProjectile& aTrack) {
     276  const G4ParticleDefinition* trkDef = aTrack.GetDefinition();
     277
     278  G4int bulletType = 0;                 // For elementary particles
     279  G4int bulletA = 0, bulletZ = 0;       // For nucleus projectile
     280
     281  if (trkDef->GetAtomicMass() <= 1) {
     282    if (trkDef == G4KaonZeroLong::KaonZeroLong() ||
     283        trkDef == G4KaonZeroShort::KaonZeroShort() )
     284      bulletType = (G4UniformRand() > 0.5) ? kaonZero : kaonZeroBar;
     285    else
     286      bulletType = G4InuclElementaryParticle::type(trkDef);
     287  } else {
     288    bulletA = trkDef->GetAtomicMass();
     289    bulletZ = trkDef->GetAtomicNumber();
     290  }
     291
     292  // Code momentum and energy -- Bertini wants z-axis and GeV units
     293  G4LorentzVector projectileMomentum = aTrack.Get4Momentum()/GeV;
     294 
     295  // Rrotation/boost to get from z-axis back to original frame
     296  bulletInLabFrame = G4LorentzRotation::IDENTITY;       // Initialize
     297  bulletInLabFrame.rotateZ(-projectileMomentum.phi());
     298  bulletInLabFrame.rotateY(-projectileMomentum.theta());
     299  bulletInLabFrame.invert();
     300 
     301  G4LorentzVector momentumBullet(0., 0., projectileMomentum.rho(),
     302                                 projectileMomentum.e());
     303
     304  if (bulletType > 0)
     305    bullet = new G4InuclElementaryParticle(momentumBullet, bulletType);
     306  else
     307    bullet = new G4InuclNuclei(momentumBullet, bulletA, bulletZ);
     308
     309  return;
     310}
     311
     312
     313// Convert input nuclear target to Bertini internal object
     314
     315void G4CascadeInterface::createTarget(G4Nucleus& theNucleus) {
     316  G4int theNucleusA = theNucleus.GetA_asInt();
     317  G4int theNucleusZ = theNucleus.GetZ_asInt();
     318
     319  if (theNucleusA == 1)
     320    target = new G4InuclElementaryParticle((theNucleusZ==1)?proton:neutron);
     321  else
     322    target = new G4InuclNuclei(theNucleusA, theNucleusZ);
     323
     324  return;
     325}
     326
     327
     328// Transfer Bertini internal final state to hadronics interface
     329
     330void G4CascadeInterface::copyOutputToHadronicResult() {
     331  const std::vector<G4InuclNuclei>& outgoingNuclei = output->getOutgoingNuclei();
     332  const std::vector<G4InuclElementaryParticle>& particles = output->getOutgoingParticles();
    259333
    260334  theResult.SetStatusChange(stopAndKill);
     
    262336  // Get outcoming particles
    263337  G4DynamicParticle* cascadeParticle = 0;
     338
    264339  if (!particles.empty()) {
    265340    particleIterator ipart = particles.begin();
     
    267342      G4int outgoingType = ipart->type();
    268343
    269       eTot += ipart->getEnergy();
    270       sumBaryon -= ipart->baryon();
    271       sumEnergy -= ipart->getKineticEnergy();
    272 
    273344      if (!ipart->valid() || ipart->quasi_deutron()) {
    274         G4cerr << " ERROR: G4CascadeInterface::Propagate incompatible"
     345        G4cerr << " ERROR: G4CascadeInterface::ApplyYourself incompatible"
    275346               << " particle type " << outgoingType << G4endl;
    276347        continue;
     
    280351      if (outgoingType == kaonZero || outgoingType == kaonZeroBar) {
    281352        G4ThreeVector momDir = ipart->getMomentum().vect().unit();
    282         G4double ekin = ipart->getKineticEnergy();
     353        G4double ekin = ipart->getKineticEnergy()*GeV;  // Bertini -> G4 units
    283354
    284355        G4ParticleDefinition* pd = G4KaonZeroShort::Definition();
     
    296367  // get nuclei fragments
    297368  G4DynamicParticle * aFragment = 0;
    298   if (!nucleiFragments.empty()) {
    299     nucleiIterator ifrag = nucleiFragments.begin();
    300     for (; ifrag != nucleiFragments.end(); ifrag++) {
    301       eTot += ifrag->getEnergy();
    302       sumBaryon -= ifrag->getA();
    303       sumEnergy -= ifrag->getKineticEnergy();
    304      
    305       // hpw @@@ ==> Should be zero: G4double fragmentExitation = ifrag->getExitationEnergyInGeV();
    306      
     369  if (!outgoingNuclei.empty()) {
     370    nucleiIterator ifrag = outgoingNuclei.begin();
     371    for (; ifrag != outgoingNuclei.end(); ifrag++) {
    307372      if (verboseLevel > 2) {
    308373        G4cout << " Nuclei fragment: " << G4endl;
     
    315380    }
    316381  }
    317 
    318   // Report violations of energy, baryon conservation
    319   if (verboseLevel > 2) {
    320     if (sumBaryon != 0) {
    321       G4cout << "ERROR: no baryon number conservation, sum of baryons = "
    322              << sumBaryon << G4endl;
    323     }
    324 
    325     if (sumEnergy > 0.01 ) {
    326       G4cout << "Kinetic energy conservation violated by "
    327              << sumEnergy << " GeV" << G4endl;
    328     }
    329      
    330     G4cout << "Total energy conservation at level ~"
    331            << (eInit - eTot) * GeV << " MeV" << G4endl;
    332    
    333     if (sumEnergy < -5.0e-5 ) { // 0.05 MeV
    334       G4cout << "FATAL ERROR: energy created  "
    335              << sumEnergy * GeV << " MeV" << G4endl;
    336     }
    337   }
    338 
    339   delete bullet;
    340   delete collider;
    341 
    342   if(target != 0) delete target;
    343   if(targetH != 0) delete targetH;
    344 
    345   return &theResult;
    346 }
     382}
     383
     384
     385// Evaluate whether any outgoing particles penetrated Coulomb barrier
     386
     387G4bool G4CascadeInterface::coulombBarrierViolation() const {
     388  G4bool violated = false;              // by default coulomb analysis is OK
     389
     390  const G4double coulumbBarrier = 8.7 * MeV/GeV;        // Bertini uses GeV
     391
     392  const std::vector<G4InuclElementaryParticle>& p =
     393    output->getOutgoingParticles();
     394
     395  for (particleIterator ipart=p.begin(); ipart != p.end(); ipart++) {
     396    if (ipart->type() == proton) {
     397      violated |= (ipart->getKineticEnergy() < coulumbBarrier);
     398    }
     399  }
     400
     401  return violated;
     402}
     403
     404// Check whether inelastic collision on proton failed
     405
     406G4bool G4CascadeInterface::retryInelasticProton() const {
     407  const std::vector<G4InuclElementaryParticle>& out =
     408    output->getOutgoingParticles();
     409
     410  return ( (numberOfTries < maximumTries) &&
     411           (out.size() == 2) &&
     412           (out[0].getDefinition() == bullet->getDefinition() ||
     413            out[1].getDefinition() == bullet->getDefinition())
     414           );
     415}
     416
     417// Check whether generic inelastic collision failed
     418// NOTE:  some conditions are set by compiler flags
     419
     420G4bool G4CascadeInterface::retryInelasticNucleus() const {
     421  // Quantities necessary for conditional block below
     422  G4int npart = output->numberOfOutgoingParticles();
     423  G4int nfrag = output->numberOfOutgoingNuclei();
     424
     425  const G4ParticleDefinition* firstOut = (npart == 0) ? 0 :
     426    output->getOutgoingParticles().begin()->getDefinition();
     427
     428  return ( ((numberOfTries < maximumTries) &&
     429            (npart != 0) &&
     430#ifdef G4CASCADE_COULOMB_DEV
     431            (coulombBarrierViolation() && npart+nfrag > 2)
     432#else
     433            (npart+nfrag < 3 && firstOut == bullet->getDefinition())
     434#endif
     435            )
     436#ifndef G4CASCADE_SKIP_ECONS
     437           || (!balance->okay())
     438#endif
     439           );
     440}
     441
     442
     443// Terminate job in case of persistent non-conservation
     444
     445void G4CascadeInterface::throwNonConservationFailure() {
     446  G4cerr << " >>> G4CascadeInterface::ApplyYourself()\n has non-conserving"
     447         << " cascade after " << numberOfTries << " attempts." << G4endl;
     448
     449  G4String throwMsg = "G4CascadeInterface::ApplyYourself() - ";
     450  if (!balance->energyOkay()) {
     451    throwMsg += "Energy";
     452    G4cerr << " Energy conservation violated by " << balance->deltaE()
     453           << " GeV (" << balance->relativeE() << ")" << G4endl;
     454  }
     455 
     456  if (!balance->momentumOkay()) {
     457    throwMsg += "Momentum";
     458    G4cerr << " Momentum conservation violated by " << balance->deltaP()
     459           << " GeV/c (" << balance->relativeP() << ")" << G4endl;
     460  }
     461 
     462  if (!balance->baryonOkay()) {
     463    throwMsg += "Baryon number";
     464    G4cerr << " Baryon number violated by " << balance->deltaB() << G4endl;
     465  }
     466 
     467  if (!balance->chargeOkay()) {
     468    throwMsg += "Charge";
     469    G4cerr << " Charge conservation violated by " << balance->deltaB()
     470           << G4endl;
     471  }
     472 
     473  G4cout << "\n Final event output, for debugging:"
     474         << "\n Bullet:  " << G4endl; 
     475  bullet->printParticle();
     476  G4cout << "\n Target:  " << G4endl; 
     477  target->printParticle();
     478 
     479  output->printCollisionOutput();
     480 
     481  throwMsg += " non-conservation. More info in output.";
     482  throw G4HadronicException(__FILE__, __LINE__, throwMsg);   // Job ends here!
     483}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKminusNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKminusNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeKminusNChannel.hh"
     
    712714G4CascadeKminusNChannelData::data(kmn2bfs, kmn3bfs, kmn4bfs,
    713715                                  kmn5bfs, kmn6bfs, kmn7bfs,
    714                                   kmnCrossSections);
     716                                  kmnCrossSections, "KminusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKminusPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKminusPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeKminusPChannel.hh"
     
    855857G4CascadeKminusPChannelData::data(kmp2bfs, kmp3bfs, kmp4bfs,
    856858                                  kmp5bfs, kmp6bfs, kmp7bfs,
    857                                   kmpCrossSections);
     859                                  kmpCrossSections, "KminusP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKplusNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKplusNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628 
    2729#include "G4CascadeKplusNChannel.hh"
     
    680682G4CascadeKplusNChannelData::data(kpn2bfs, kpn3bfs, kpn4bfs,
    681683                                 kpn5bfs, kpn6bfs, kpn7bfs,
    682                                  kpnCrossSections);
     684                                 kpnCrossSections, "KplusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKplusPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKplusPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeKplusPChannel.hh"
     
    605607G4CascadeKplusPChannelData::data(kpp2bfs, kpp3bfs, kpp4bfs,
    606608                                 kpp5bfs, kpp6bfs, kpp7bfs,
    607                                  kppCrossSections);
     609                                 kppCrossSections, "KplusP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKzeroBarNChannel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeKzeroBarNChannel.cc,v 1.6 2010/06/25 09:44:06 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeKzeroBarNChannel.cc,v 1.7 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
     28//
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadeKzeroBarNChannel.hh"
     
    857859G4CascadeKzeroBarNChannelData::data(kzbn2bfs, kzbn3bfs, kzbn4bfs,
    858860                                    kzbn5bfs, kzbn6bfs, kzbn7bfs,
    859                                     kzbnCrossSections);
     861                                    kzbnCrossSections, "KzeroBarN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKzeroBarPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKzeroBarPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeKzeroBarPChannel.hh"
     
    712714G4CascadeKzeroBarPChannelData::data(kzbp2bfs, kzbp3bfs, kzbp4bfs,
    713715                                    kzbp5bfs, kzbp6bfs, kzbp7bfs,
    714                                     kzbpCrossSections);
     716                                    kzbpCrossSections, "KzeroBarP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKzeroNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKzeroNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeKzeroNChannel.hh"
     
    605607G4CascadeKzeroNChannelData::data(k0n2bfs, k0n3bfs, k0n4bfs,
    606608                                 k0n5bfs, k0n6bfs, k0n7bfs,
    607                                  k0nCrossSections);
     609                                 k0nCrossSections, "KzeroN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeKzeroPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeKzeroPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628 
    2729#include "G4CascadeKzeroPChannel.hh"
     
    680682G4CascadeKzeroPChannelData::data(k0p2bfs, k0p3bfs, k0p4bfs,
    681683                                 k0p5bfs, k0p6bfs, k0p7bfs,
    682                                  k0pCrossSections);
     684                                 k0pCrossSections, "KzeroP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeLambdaNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeLambdaNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeLambdaNChannel.hh"
     
    904906G4CascadeLambdaNChannelData::data(ln2bfs, ln3bfs, ln4bfs,
    905907                                  ln5bfs, ln6bfs, ln7bfs,
    906                                   lnCrossSections);
     908                                  lnCrossSections, "LambdaN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeLambdaPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeLambdaPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeLambdaPChannel.hh"
     
    904906G4CascadeLambdaPChannelData::data(lp2bfs, lp3bfs, lp4bfs,
    905907                                  lp5bfs, lp6bfs, lp7bfs,
    906                                   lpCrossSections);
     908                                  lpCrossSections, "LambdaP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaMinusNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaMinusNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaMinusNChannel.hh"
     
    662664G4CascadeSigmaMinusNChannelData::data(smn2bfs, smn3bfs, smn4bfs,
    663665                                      smn5bfs, smn6bfs, smn7bfs,
    664                                       smnCrossSections);
     666                                      smnCrossSections, "SigmaMinusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaMinusPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaMinusPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaMinusPChannel.hh"
     
    903905G4CascadeSigmaMinusPChannelData::data(smp2bfs, smp3bfs, smp4bfs,
    904906                                      smp5bfs, smp6bfs, smp7bfs,
    905                                       smpCrossSections);
     907                                      smpCrossSections, "SigmaMinusP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaPlusNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaPlusNChannel.cc,v 1.6 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaPlusNChannel.hh"
     
    904906G4CascadeSigmaPlusNChannelData::data(spn2bfs, spn3bfs, spn4bfs,
    905907                                     spn5bfs, spn6bfs, spn7bfs,
    906                                      spnCrossSections);
     908                                     spnCrossSections, "SigmaPlusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaPlusPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaPlusPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaPlusPChannel.hh"
     
    662664G4CascadeSigmaPlusPChannelData::data(spp2bfs, spp3bfs, spp4bfs,
    663665                                     spp5bfs, spp6bfs, spp7bfs,
    664                                      sppCrossSections);
     666                                     sppCrossSections, "SigmaPlusP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaZeroNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaZeroNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaZeroNChannel.hh"
     
    904906G4CascadeSigmaZeroNChannelData::data(s0n2bfs, s0n3bfs, s0n4bfs,
    905907                                     s0n5bfs, s0n6bfs, s0n7bfs,
    906                                      s0nCrossSections);
     908                                     s0nCrossSections, "SigmaZeroN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeSigmaZeroPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeSigmaZeroPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeSigmaZeroPChannel.hh"
     
    904906G4CascadeSigmaZeroPChannelData::data(s0p2bfs, s0p3bfs, s0p4bfs,
    905907                                     s0p5bfs, s0p6bfs, s0p7bfs,
    906                                      s0pCrossSections);
     908                                     s0pCrossSections, "SigmaZeroP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeT0npChannel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeT0npChannel.cc,v 1.2 2010/06/25 09:44:08 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeT0npChannel.cc,v 1.3 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
     28//
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadeNPChannel.hh"
     
    665667G4CascadeNPChannelData::data_t
    666668G4CascadeNPChannelData::data(np2bfs, np3bfs, np4bfs, np5bfs, np6bfs, np7bfs,
    667                              np8bfs, np9bfs, npCrossSections, npTotXSec);
     669                             np8bfs, np9bfs, npCrossSections, npTotXSec,
     670                             "NeutronProton");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeT11pizNChannel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeT11pizNChannel.cc,v 1.2 2010/06/25 09:44:10 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeT11pizNChannel.cc,v 1.3 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
     28//
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadePiZeroPChannel.hh"
     
    685687                                  pizP5bfs, pizP6bfs, pizP7bfs,
    686688                                  pizP8bfs, pizP9bfs, pizPCrossSections,
    687                                   pizPtotXSec);
     689                                  pizPtotXSec, "PiZeroP");
    688690
    689691G4CascadePiZeroNChannelData::data_t
     
    691693                                  pizN5bfs, pizN6bfs, pizN7bfs,
    692694                                  pizN8bfs, pizN9bfs, pizPCrossSections,
    693                                   pizPtotXSec);
     695                                  pizPtotXSec, "PiZeroN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeT1NNChannel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeT1NNChannel.cc,v 1.2 2010/06/25 09:44:12 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeT1NNChannel.cc,v 1.3 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
     28//
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadePPChannel.hh"
     
    643645G4CascadePPChannelData::data_t
    644646G4CascadePPChannelData::data(pp2bfs, pp3bfs, pp4bfs, pp5bfs, pp6bfs, pp7bfs,
    645                              pp8bfs, pp9bfs, ppCrossSections, ppTotXSec);
     647                             pp8bfs, pp9bfs, ppCrossSections, ppTotXSec,
     648                             "ProtonProton");
    646649
    647650G4CascadeNNChannelData::data_t
    648651G4CascadeNNChannelData::data(nn2bfs, nn3bfs, nn4bfs, nn5bfs, nn6bfs, nn7bfs,
    649                              nn8bfs, nn9bfs, ppCrossSections, ppTotXSec);
     652                             nn8bfs, nn9bfs, ppCrossSections, ppTotXSec,
     653                             "NeutronNeutron");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeT31piNChannel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CascadeT31piNChannel.cc,v 1.2 2010/06/25 09:44:14 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4CascadeT31piNChannel.cc,v 1.3 2010/08/04 05:28:24 mkelsey Exp $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
     28//
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadePiMinusPChannel.hh"
     
    689691                                   pimP5bfs, pimP6bfs, pimP7bfs,
    690692                                   pimP8bfs, pimP9bfs, pimPCrossSections,
    691                                    pimPtotXSec);
     693                                   pimPtotXSec, "PiMinusP");
    692694
    693695G4CascadePiPlusNChannelData::data_t
     
    695697                                  pipN5bfs, pipN6bfs, pipN7bfs,
    696698                                  pipN8bfs, pipN9bfs, pimPCrossSections,
    697                                   pimPtotXSec);
     699                                  pimPtotXSec, "PiPlusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeT33piNChannel.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeT33piNChannel.cc,v 1.3 2010/08/04 05:28:24 mkelsey Exp $
     26// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2527//
    26 // $Id: G4CascadeT33piNChannel.cc,v 1.1.2.1 2010/06/25 09:44:16 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     28// 20100612  M. Kelsey -- BUG FIX:  Swapped eight-body channel final-states
     29// 20100804  M. Kelsey -- Add name string to ctor
    2830
    2931#include "G4CascadePiPlusPChannel.hh"
     
    7072
    7173  static const G4int pipP8bfs[7][8] =
    72    {{pim,neu,pip,pip,pip,pim,pim,pim}, {pim,neu,pip,pip,pim,pim,pi0,pi0},
    73     {pim,neu,pip,pim,pi0,pi0,pi0,pi0}, {pim,neu,pi0,pi0,pi0,pi0,pi0,pi0},
    74     {pim,pro,pip,pip,pim,pim,pim,pi0}, {pim,pro,pip,pim,pim,pi0,pi0,pi0},
    75     {pim,pro,pim,pi0,pi0,pi0,pi0,pi0}};
     74   {{pip,pro,pip,pip,pip,pim,pim,pim}, {pip,pro,pip,pip,pim,pim,pi0,pi0},
     75    {pip,pro,pip,pim,pi0,pi0,pi0,pi0}, {pip,pro,pi0,pi0,pi0,pi0,pi0,pi0},
     76    {pip,neu,pip,pip,pip,pim,pim,pi0}, {pip,neu,pip,pip,pim,pi0,pi0,pi0},
     77    {pip,neu,pip,pi0,pi0,pi0,pi0,pi0}};
    7678
    7779  static const G4int pipP9bfs[8][9] =
     
    120122
    121123  static const G4int pimN8bfs[7][8] =
    122    {{pip,pro,pip,pip,pip,pim,pim,pim}, {pip,pro,pip,pip,pim,pim,pi0,pi0},
    123     {pip,pro,pip,pim,pi0,pi0,pi0,pi0}, {pip,pro,pi0,pi0,pi0,pi0,pi0,pi0},
    124     {pip,neu,pip,pip,pip,pim,pim,pi0}, {pip,neu,pip,pip,pim,pi0,pi0,pi0},
    125     {pip,neu,pip,pi0,pi0,pi0,pi0,pi0}};
     124   {{pim,neu,pip,pip,pip,pim,pim,pim}, {pim,neu,pip,pip,pim,pim,pi0,pi0},
     125    {pim,neu,pip,pim,pi0,pi0,pi0,pi0}, {pim,neu,pi0,pi0,pi0,pi0,pi0,pi0},
     126    {pim,pro,pip,pip,pim,pim,pim,pi0}, {pim,pro,pip,pim,pim,pi0,pi0,pi0},
     127    {pim,pro,pim,pi0,pi0,pi0,pi0,pi0}};
    126128
    127129  static const G4int pimN9bfs[8][9] =
     
    536538                                  pipP5bfs, pipP6bfs, pipP7bfs,
    537539                                  pipP8bfs, pipP9bfs, pipPCrossSections,
    538                                   pipPtotXSec);
     540                                  pipPtotXSec, "PiPlusP");
    539541
    540542G4CascadePiMinusNChannelData::data_t
     
    542544                                   pimN5bfs, pimN6bfs, pimN7bfs,
    543545                                   pimN8bfs, pimN9bfs, pipPCrossSections,
    544                                    pipPtotXSec);
     546                                   pipPtotXSec, "PiMinusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeXiMinusNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeXiMinusNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeXiMinusNChannel.hh"
     
    494496G4CascadeXiMinusNChannelData::data(xmn2bfs, xmn3bfs, xmn4bfs,
    495497                                   xmn5bfs, xmn6bfs, xmn7bfs,
    496                                    xmnCrossSections);
     498                                   xmnCrossSections, "XiMinusN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeXiMinusPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeXiMinusPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeXiMinusPChannel.hh"
     
    316318G4CascadeXiMinusPChannelData::data(xmp2bfs, xmp3bfs, xmp4bfs,
    317319                                   xmp5bfs, xmp6bfs, xmp7bfs,
    318                                    xmpCrossSections);
     320                                   xmpCrossSections, "XiMinusP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeXiZeroNChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeXiZeroNChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeXiZeroNChannel.hh"
     
    316318G4CascadeXiZeroNChannelData::data(x0n2bfs, x0n3bfs, x0n4bfs,
    317319                                  x0n5bfs, x0n6bfs, x0n7bfs,
    318                                   x0nCrossSections);
     320                                  x0nCrossSections, "XiZeroN");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CascadeXiZeroPChannel.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4CascadeXiZeroPChannel.cc,v 1.5 2010/08/04 05:28:24 mkelsey Exp $
    2526//
     27// 20100804  M. Kelsey -- Add name string to ctor
    2628
    2729#include "G4CascadeXiZeroPChannel.hh"
     
    494496G4CascadeXiZeroPChannelData::data(x0p2bfs, x0p3bfs, x0p4bfs,
    495497                                  x0p5bfs, x0p6bfs, x0p7bfs,
    496                                   x0pCrossSections);
     498                                  x0pCrossSections, "XiZeroP");
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4CollisionOutput.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4CollisionOutput.cc,v 1.23.2.1 2010/06/25 09:44:18 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4CollisionOutput.cc,v 1.37 2010/10/19 19:48:34 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3332// 20100418  M. Kelsey -- Add function to boost output lists to lab frame
    3433// 20100520  M. Kelsey -- Add function to rotate Z axis, from G4Casc.Interface
     34// 20100620  M. Kelsey -- Add some diagnostics in setOnShell, simplify if's
     35// 20100630  M. Kelsey -- Use "getExcitationEnergyInGeV()" instead of ".001*"
     36// 20100701  M. Kelsey -- G4InuclNuclei now includes excitation energy as part
     37//              of the reported mass and four-vector.
     38// 20100714  M. Kelsey -- Modify setOnShell() to avoid creating particles
     39//              with negative kinetic energy.
     40// 20100715  M. Kelsey -- Add total charge and baryon number functions, and a
     41//              combined "add()" function to put two of these together
     42// 20100924  M. Kelsey -- Use "OutgoingNuclei" name consistently, replacing
     43//              old "TargetFragment".  Add new (reusable) G4Fragment buffer
     44//              and access functions for initial post-cascade processing.
     45//              Move implementation of add() to .cc file.
     46// 20101019  M. Kelsey -- CoVerity report: unitialized constructor
    3547
    3648#include "G4CollisionOutput.hh"
     49#include "G4CascadParticle.hh"
    3750#include "G4ParticleLargerEkin.hh"
    3851#include "G4LorentzConvertor.hh"
    3952#include "G4LorentzRotation.hh"
     53#include "G4ReactionProductVector.hh"
     54#include "G4ReactionProduct.hh"
    4055#include <algorithm>
    4156
     
    4560
    4661G4CollisionOutput::G4CollisionOutput()
    47   : verboseLevel(0) {
    48  
    49   if (verboseLevel > 3)
     62  : verboseLevel(0), eex_rest(0), on_shell(false) {
     63  if (verboseLevel > 1)
    5064    G4cout << " >>> G4CollisionOutput::G4CollisionOutput" << G4endl;
    5165}
     
    5771    verboseLevel = right.verboseLevel;
    5872    outgoingParticles = right.outgoingParticles;
    59     nucleiFragments = right.nucleiFragments;
     73    outgoingNuclei = right.outgoingNuclei;
     74    theRecoilFragment = right.theRecoilFragment;
    6075    eex_rest = right.eex_rest;
    6176    on_shell = right.on_shell;
     
    6580
    6681void G4CollisionOutput::reset() {
    67   nucleiFragments.clear();
     82  outgoingNuclei.clear();
    6883  outgoingParticles.clear();
    69 }
    70 
     84
     85  static const G4Fragment emptyFragment;        // Default ctor is all zeros
     86  theRecoilFragment = emptyFragment;
     87}
     88
     89
     90// Merge two complete objects
     91
     92void G4CollisionOutput::add(const G4CollisionOutput& right) {
     93  addOutgoingParticles(right.outgoingParticles);
     94  addOutgoingNuclei(right.outgoingNuclei);
     95  theRecoilFragment = right.theRecoilFragment;
     96}
     97
     98
     99// Append to lists
    71100
    72101void G4CollisionOutput::addOutgoingParticles(const std::vector<G4InuclElementaryParticle>& particles) {
     
    75104}
    76105
    77 
    78 void G4CollisionOutput::addTargetFragments(const std::vector<G4InuclNuclei>& nuclea) {
    79   nucleiFragments.insert(nucleiFragments.end(), nuclea.begin(), nuclea.end());
     106void G4CollisionOutput::addOutgoingNuclei(const std::vector<G4InuclNuclei>& nuclea) {
     107  outgoingNuclei.insert(outgoingNuclei.end(), nuclea.begin(), nuclea.end());
     108}
     109
     110// These are primarily for G4IntraNucleiCascader internal checks
     111
     112void G4CollisionOutput::addOutgoingParticle(const G4CascadParticle& cparticle) {
     113  addOutgoingParticle(cparticle.getParticle());
     114}
     115
     116void G4CollisionOutput::addOutgoingParticles(const std::vector<G4CascadParticle>& cparticles) {
     117  for (unsigned i=0; i<cparticles.size(); i++)
     118    addOutgoingParticle(cparticles[i].getParticle());
     119}
     120
     121// This comes from PreCompound de-excitation, both particles and nuclei
     122
     123void G4CollisionOutput::addOutgoingParticles(const G4ReactionProductVector* rproducts) {
     124  if (!rproducts) return;               // Sanity check, no error if null
     125
     126  G4ReactionProductVector::const_iterator j;
     127  for (j=rproducts->begin(); j!=rproducts->end(); ++j) {
     128    G4ParticleDefinition* pd = (*j)->GetDefinition();
     129
     130    // FIXME:  This is expensive and unnecessary copying!
     131    G4DynamicParticle aFragment(pd, (*j)->GetMomentum());
     132   
     133    // Nucleons and nuclei are jumbled together in the list
     134    if (G4InuclElementaryParticle::type(pd)) {
     135      addOutgoingParticle(G4InuclElementaryParticle(aFragment, 9));
     136    } else {
     137      addOutgoingNucleus(G4InuclNuclei(aFragment, 9));
     138    }
     139  }
    80140}
    81141
    82142
    83143G4LorentzVector G4CollisionOutput::getTotalOutputMomentum() const {
     144  if (verboseLevel > 1)
     145    G4cout << " >>> G4CollisionOutput::getTotalOutputMomentum" << G4endl;
     146
    84147  G4LorentzVector tot_mom;
    85   double eex_r = 0.0;
    86148  G4int i(0);
    87   for(i = 0; i < G4int(outgoingParticles.size()); i++) {
     149  for(i=0; i < G4int(outgoingParticles.size()); i++) {
    88150    tot_mom += outgoingParticles[i].getMomentum();
    89151  }
    90   for(i = 0; i < G4int(nucleiFragments.size()); i++) {
    91     tot_mom += nucleiFragments[i].getMomentum();
    92     eex_r += 0.001 * nucleiFragments[i].getExitationEnergy();
    93   }
    94   tot_mom.setE(tot_mom.e() + eex_r);
     152  for(i=0; i < G4int(outgoingNuclei.size()); i++) {
     153    tot_mom += outgoingNuclei[i].getMomentum();
     154  }
    95155  return tot_mom;
    96156}
    97157
     158G4int G4CollisionOutput::getTotalCharge() const {
     159  if (verboseLevel > 1)
     160    G4cout << " >>> G4CollisionOutput::getTotalCharge" << G4endl;
     161
     162  G4int charge = 0;
     163  G4int i(0);
     164  for(i=0; i < G4int(outgoingParticles.size()); i++) {
     165    charge += G4int(outgoingParticles[i].getCharge());
     166  }
     167  for(i=0; i < G4int(outgoingNuclei.size()); i++) {
     168    charge += G4int(outgoingNuclei[i].getCharge());
     169  }
     170  return charge;
     171}
     172
     173G4int G4CollisionOutput::getTotalBaryonNumber() const {
     174  if (verboseLevel > 1)
     175    G4cout << " >>> G4CollisionOutput::getTotalBaryonNumber" << G4endl;
     176
     177  G4int baryon = 0;
     178  G4int i(0);
     179  for(i=0; i < G4int(outgoingParticles.size()); i++) {
     180    baryon += outgoingParticles[i].baryon();
     181  }
     182  for(i=0; i < G4int(outgoingNuclei.size()); i++) {
     183    baryon += G4int(outgoingNuclei[i].getA());
     184  }
     185  return baryon;
     186}
     187
     188
    98189void G4CollisionOutput::printCollisionOutput() const {
     190  G4cout << " Output: " << G4endl
     191         << " Outgoing Particles: " << outgoingParticles.size() << G4endl;
     192
    99193  G4int i(0);
    100 
    101   G4cout << " Output: " << G4endl 
    102          << " Outgoing Particles: " << outgoingParticles.size() << G4endl;
    103   for(i = 0; i < G4int(outgoingParticles.size()); i++)
     194  for(i=0; i < G4int(outgoingParticles.size()); i++)
    104195    outgoingParticles[i].printParticle();
    105196
    106   G4cout << " Nuclei fragments: " << nucleiFragments.size() << G4endl;     
    107   for(i = 0; i < G4int(nucleiFragments.size()); i++)
    108     nucleiFragments[i].printParticle();
     197  G4cout << " Outgoing Nuclei: " << outgoingNuclei.size() << G4endl;     
     198  for(i=0; i < G4int(outgoingNuclei.size()); i++)
     199    outgoingNuclei[i].printParticle();
     200
     201  if (theRecoilFragment.GetA() > 0) {
     202    G4cout << theRecoilFragment << G4endl;
     203  }
    109204}
    110205
     
    113208
    114209void G4CollisionOutput::boostToLabFrame(const G4LorentzConvertor& convertor) {
     210  if (verboseLevel > 1)
     211    G4cout << " >>> G4CollisionOutput::boostToLabFrame" << G4endl;
     212
    115213  G4bool withReflection = convertor.reflectionNeeded();
    116214
     
    129227  }
    130228 
    131   if (!nucleiFragments.empty()) {
    132     nucleiIterator inuc = nucleiFragments.begin();
     229  if (!outgoingNuclei.empty()) {
     230    nucleiIterator inuc = outgoingNuclei.begin();
    133231   
    134     for (; inuc != nucleiFragments.end(); inuc++) {
     232    for (; inuc != outgoingNuclei.end(); inuc++) {
    135233      G4LorentzVector mom = inuc->getMomentum();
    136234     
     
    147245
    148246void G4CollisionOutput::rotateEvent(const G4LorentzRotation& rotate) {
     247  if (verboseLevel > 1)
     248    G4cout << " >>> G4CollisionOutput::rotateEvent" << G4endl;
     249
    149250  particleIterator ipart = outgoingParticles.begin();
    150251  for(; ipart != outgoingParticles.end(); ipart++)
    151252    ipart->setMomentum(ipart->getMomentum()*=rotate);
    152253
    153   nucleiIterator inuc = nucleiFragments.begin();
    154   for (; inuc != nucleiFragments.end(); inuc++)
     254  nucleiIterator inuc = outgoingNuclei.begin();
     255  for (; inuc != outgoingNuclei.end(); inuc++)
    155256    inuc->setMomentum(inuc->getMomentum()*=rotate);
    156257}
     
    159260void G4CollisionOutput::trivialise(G4InuclParticle* bullet,
    160261                                   G4InuclParticle* target) {
     262  if (verboseLevel > 1)
     263    G4cout << " >>> G4CollisionOutput::trivialize" << G4endl;
     264
    161265  if (G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target)) {
    162     nucleiFragments.push_back(*nuclei_target);
     266    outgoingNuclei.push_back(*nuclei_target);
    163267  } else {
    164268    G4InuclElementaryParticle* particle =
     
    168272
    169273  if (G4InuclNuclei* nuclei_bullet = dynamic_cast<G4InuclNuclei*>(bullet)) {
    170     nucleiFragments.push_back(*nuclei_bullet);
     274    outgoingNuclei.push_back(*nuclei_bullet);
    171275  } else {
    172276    G4InuclElementaryParticle* particle =
     
    179283void G4CollisionOutput::setOnShell(G4InuclParticle* bullet,
    180284                                   G4InuclParticle* target) {
    181 
    182   if (verboseLevel > 3) {
     285  if (verboseLevel > 1)
    183286    G4cout << " >>> G4CollisionOutput::setOnShell" << G4endl;
    184   }
    185 
    186   const G4double accuracy = 0.00001; // momentum concerves at the level of 1 eV
     287
     288  const G4double accuracy = 0.00001; // momentum concerves at the level of 10 keV
    187289
    188290  on_shell = false;
     
    194296 
    195297  G4LorentzVector out_mom = getTotalOutputMomentum();
    196   G4LorentzVector mon_non_cons;
    197298  if(verboseLevel > 2){
    198299    G4cout << " bullet momentum = " << ini_mom.e() <<", "<< ini_mom.x() <<", "<< ini_mom.y()<<", "<< ini_mom.z()<<G4endl;
     
    201302  }
    202303
    203   mon_non_cons = ini_mom - out_mom;
     304  G4LorentzVector mon_non_cons = ini_mom - out_mom;
    204305
    205306  G4double pnc = mon_non_cons.rho();
     307  G4double enc = mon_non_cons.e();
    206308
    207309  setRemainingExitationEnergy();       
     
    210312    printCollisionOutput();
    211313    G4cout << " momentum non conservation: " << G4endl
    212            << " e " << mon_non_cons.e()
    213            << " p " << pnc << G4endl;
     314           << " e " << enc << " p " << pnc << G4endl;
    214315    G4cout << " remaining exitation " << eex_rest << G4endl;
    215316  }
    216317
    217   if(std::fabs(mon_non_cons.e()) > accuracy || pnc > accuracy) { // renormalization
    218     G4int npart = outgoingParticles.size();
    219  
    220     if(npart > 0) {
    221 
    222       G4LorentzVector last_mom = outgoingParticles[npart - 1].getMomentum();
    223 
    224       last_mom += mon_non_cons;
    225       outgoingParticles[npart - 1].setMomentum(last_mom);
    226     }
    227     else {
    228 
    229       G4int nnuc = nucleiFragments.size();
    230  
    231       if(nnuc > 0) {
    232 
    233         G4LorentzVector last_mom = nucleiFragments[nnuc - 1].getMomentum();
    234 
    235         last_mom += mon_non_cons;
    236         nucleiFragments[nnuc - 1].setMomentum(last_mom);
    237         nucleiFragments[nnuc - 1].setEnergy();
     318  if(std::fabs(enc) <= accuracy && pnc <= accuracy) {
     319    on_shell = true;
     320    return;
     321  }
     322
     323  // Adjust "last" particle's four-momentum to balance event
     324  // ONLY adjust particles with sufficient e or p to remain physical!
     325
     326  if (verboseLevel > 2) G4cout << " re-balancing four-momenta" << G4endl;
     327
     328  G4int npart = outgoingParticles.size();
     329  G4int nnuc = outgoingNuclei.size();
     330  if (npart > 0) {
     331    for (G4int ip=npart-1; ip>=0; ip--) {
     332      if (outgoingParticles[ip].getKineticEnergy()+enc > 0.) {
     333        G4LorentzVector last_mom = outgoingParticles[ip].getMomentum();
     334        last_mom += mon_non_cons;
     335        outgoingParticles[ip].setMomentum(last_mom);
     336        break;
     337      }
     338    }
     339  } else if (nnuc > 0) {
     340    for (G4int in=nnuc-1; in>=0; in--) {
     341      if (outgoingNuclei[in].getKineticEnergy()+enc > 0.) {
     342        G4LorentzVector last_mom = outgoingNuclei[in].getMomentum();
     343        last_mom += mon_non_cons;
     344        outgoingNuclei[in].setMomentum(last_mom);
     345        break;
     346      }
     347    }
     348  }
     349
     350  out_mom = getTotalOutputMomentum();
     351  mon_non_cons = ini_mom - out_mom;
     352  pnc = mon_non_cons.rho();
     353  enc = mon_non_cons.e();
     354
     355  if(verboseLevel > 2){
     356    printCollisionOutput();
     357    G4cout << " momentum non conservation after (1): " << G4endl
     358           << " e " << enc << " p " << pnc << G4endl;
     359  }
     360
     361  // Can energy be balanced just with nuclear excitation?
     362  G4bool need_hard_tuning = true;
     363 
     364  G4double encMeV = mon_non_cons.e() / GeV;     // Excitation below is in MeV
     365  if (outgoingNuclei.size() > 0) {
     366    for (G4int i=0; i < G4int(outgoingNuclei.size()); i++) {
     367      G4double eex = outgoingNuclei[i].getExitationEnergy();
     368     
     369      if(eex > 0.0 && eex + encMeV >= 0.0) {
     370        outgoingNuclei[i].setExitationEnergy(eex+encMeV);
     371        need_hard_tuning = false;
     372        break;
     373      }
     374    }
     375    if (need_hard_tuning && encMeV > 0.) {
     376      outgoingNuclei[0].setExitationEnergy(encMeV);
     377      need_hard_tuning = false;
     378    }
     379  }
     380 
     381  if (!need_hard_tuning) {
     382    on_shell = true;
     383    return;
     384  }
     385
     386  // Momentum (hard) tuning required for energy conservation
     387  if (verboseLevel > 2)
     388    G4cout << " trying hard (particle-pair) tuning" << G4endl;
     389
     390  std::pair<std::pair<G4int, G4int>, G4int> tune_par = selectPairToTune(mon_non_cons.e());
     391  std::pair<G4int, G4int> tune_particles = tune_par.first;
     392  G4int mom_ind = tune_par.second;
     393 
     394  if(verboseLevel > 2) {
     395    G4cout << " p1 " << tune_particles.first << " p2 " << tune_particles.second
     396           << " ind " << mom_ind << G4endl;
     397  }
     398
     399  G4bool tuning_possible =
     400    (tune_particles.first >= 0 && tune_particles.second >= 0 &&
     401     mom_ind >= G4LorentzVector::X);
     402
     403  if (!tuning_possible) {
     404    if (verboseLevel > 2) G4cout << " tuning impossible " << G4endl;
     405    return;
     406  }
     407   
     408  G4LorentzVector mom1 = outgoingParticles[tune_particles.first].getMomentum();
     409  G4LorentzVector mom2 = outgoingParticles[tune_particles.second].getMomentum();
     410  G4double newE12 = mom1.e() + mom2.e() + mon_non_cons.e();
     411  G4double R = 0.5 * (newE12 * newE12 + mom2.e() * mom2.e() - mom1.e() * mom1.e()) / newE12;
     412  G4double Q = -(mom1[mom_ind] + mom2[mom_ind]) / newE12;
     413  G4double UDQ = 1.0 / (Q * Q - 1.0);
     414  G4double W = (R * Q + mom2[mom_ind]) * UDQ;
     415  G4double V = (mom2.e() * mom2.e() - R * R) * UDQ;
     416  G4double DET = W * W + V;
     417 
     418  if (DET < 0.0) {
     419    if (verboseLevel > 2) G4cout << " DET < 0 " << G4endl;
     420    return;
     421  }
     422
     423  // Tuning allowed only for non-negative determinant
     424  G4double x1 = -(W + std::sqrt(DET));
     425  G4double x2 = -(W - std::sqrt(DET));
     426 
     427  // choose the appropriate solution
     428  G4bool xset = false;
     429  G4double x = 0.0;
     430 
     431  if(mon_non_cons.e() > 0.0) { // x has to be > 0.0
     432    if(x1 > 0.0) {
     433      if(R + Q * x1 >= 0.0) {
     434        x = x1;
     435        xset = true;
    238436      };
    239     };
    240     out_mom = getTotalOutputMomentum();
    241     mon_non_cons = ini_mom - out_mom;
    242     pnc = mon_non_cons.rho();
    243 
    244     if(verboseLevel > 2){
    245       printCollisionOutput();
    246       G4cout << " momentum non conservation after (1): " << G4endl
    247              << " e " << mon_non_cons.e() << " p " << pnc << G4endl;
    248     }
    249     G4bool need_hard_tuning = true;
    250    
    251     if(nucleiFragments.size() > 0) {
    252       for(G4int i = 0; i < G4int(nucleiFragments.size()); i++) {
    253 
    254         G4double eex = nucleiFragments[i].getExitationEnergyInGeV();
    255 
    256         if(eex > 0.0 && eex + mon_non_cons.e() >= 0.0) {
    257           nucleiFragments[i].setExitationEnergy(1000.0 * (eex + mon_non_cons.e()));
    258           need_hard_tuning = false;
    259           break;
    260         };
    261       };
    262       if(need_hard_tuning && mon_non_cons.e() > 0.) {
    263         nucleiFragments[0].setExitationEnergy(1000.0 * mon_non_cons.e());
    264         need_hard_tuning = false;
     437    }; 
     438    if(!xset && x2 > 0.0) {
     439      if(R + Q * x2 >= 0.0) {
     440        x = x2;
     441        xset = true;
    265442      };
    266443    };
    267    
    268     if(need_hard_tuning) {
    269      
    270       std::pair<std::pair<G4int, G4int>, G4int> tune_par = selectPairToTune(mon_non_cons.e());
    271       std::pair<G4int, G4int> tune_particles = tune_par.first;
    272       G4int mom_ind = tune_par.second;
    273 
    274       if(verboseLevel > 2) {
    275         G4cout << " p1 " << tune_particles.first << " p2 " << tune_particles.second
    276                << " ind " << mom_ind << G4endl;
    277       }
    278       if(tune_particles.first >= 0 && tune_particles.second >= 0 &&
    279          mom_ind >= G4LorentzVector::X) { // tunning possible
    280 
    281         G4LorentzVector mom1 = outgoingParticles[tune_particles.first].getMomentum();
    282         G4LorentzVector mom2 = outgoingParticles[tune_particles.second].getMomentum();
    283         G4double newE12 = mom1.e() + mom2.e() + mon_non_cons.e();
    284         G4double R = 0.5 * (newE12 * newE12 + mom2.e() * mom2.e() - mom1.e() * mom1.e()) / newE12;
    285         G4double Q = -(mom1[mom_ind] + mom2[mom_ind]) / newE12;
    286         G4double UDQ = 1.0 / (Q * Q - 1.0);
    287         G4double W = (R * Q + mom2[mom_ind]) * UDQ;
    288         G4double V = (mom2.e() * mom2.e() - R * R) * UDQ;
    289         G4double DET = W * W + V;
    290 
    291         if(DET > 0.0) {
    292 
    293           G4double x1 = -(W + std::sqrt(DET));
    294           G4double x2 = -(W - std::sqrt(DET));
    295           // choose the appropriate solution
    296           G4bool xset = false;
    297           G4double x = 0.0;
    298 
    299           if(mon_non_cons.e() > 0.0) { // x has to be > 0.0
    300             if(x1 > 0.0) {
    301               if(R + Q * x1 >= 0.0) {
    302                 x = x1;
    303                 xset = true;
    304               };
    305             }; 
    306             if(!xset && x2 > 0.0) {
    307               if(R + Q * x2 >= 0.0) {
    308                 x = x2;
    309                 xset = true;
    310               };
    311             };
    312           }
    313           else {
    314             if(x1 < 0.0) {
    315               if(R + Q * x1 >= 0.) {
    316                 x = x1;
    317                 xset = true;
    318               };
    319             }; 
    320             if(!xset && x2 < 0.0) {
    321               if(R + Q * x2 >= 0.0) {
    322                 x = x2;
    323                 xset = true;
    324               };
    325             };
    326           }     // if(mon_non_cons.e() > 0.0)
    327           if(xset) { // retune momentums
    328             mom1[mom_ind] += x;
    329             mom2[mom_ind] -= x;
    330             outgoingParticles[tune_particles.first ].setMomentum(mom1);
    331             outgoingParticles[tune_particles.second].setMomentum(mom2);
    332             out_mom = getTotalOutputMomentum();
    333             std::sort(outgoingParticles.begin(), outgoingParticles.end(), G4ParticleLargerEkin());
    334             mon_non_cons = ini_mom - out_mom;
    335             pnc = mon_non_cons.rho();
    336             if(verboseLevel > 2){
    337               G4cout << " momentum non conservation tuning: " << G4endl
    338                      << " e " << mon_non_cons.e() << " p " << pnc << G4endl;
    339             }
    340             if(std::fabs(mon_non_cons.e()) < accuracy || pnc < accuracy) on_shell = true;
    341           }
    342           else {
    343             if(verboseLevel > 2){
    344               G4cout << " no appropriate solution found " << G4endl;
    345             }
    346           }     // if(xset)
    347         }
    348         else {
    349           if(verboseLevel > 2){
    350             G4cout << " DET < 0 " << G4endl;
    351           }
    352         }       // if(DET > 0.0)
    353       }
    354       else {
    355         if(verboseLevel > 2){
    356           G4cout << " tuning impossible " << G4endl;
    357         }
    358       } // if (<tuning-possible>)
    359     }
    360     else {
    361       on_shell = true;
    362     }   // if(need_hard_tuning)
    363   }
    364   else {
    365     on_shell = true;
    366   };    // if (<renormalization>)
    367 }
     444  } else {
     445    if(x1 < 0.0) {
     446      if(R + Q * x1 >= 0.) {
     447        x = x1;
     448        xset = true;
     449      };
     450    }; 
     451    if(!xset && x2 < 0.0) {
     452      if(R + Q * x2 >= 0.0) {
     453        x = x2;
     454        xset = true;
     455      };
     456    };
     457  }     // if(mon_non_cons.e() > 0.0)
     458 
     459  if(!xset) {
     460    if(verboseLevel > 2)
     461      G4cout << " no appropriate solution found " << G4endl;
     462    return;
     463  }     // if(xset)
     464
     465  // retune momentums
     466  mom1[mom_ind] += x;
     467  mom2[mom_ind] -= x;
     468  outgoingParticles[tune_particles.first ].setMomentum(mom1);
     469  outgoingParticles[tune_particles.second].setMomentum(mom2);
     470  out_mom = getTotalOutputMomentum();
     471  std::sort(outgoingParticles.begin(), outgoingParticles.end(), G4ParticleLargerEkin());
     472  mon_non_cons = ini_mom - out_mom;
     473  pnc = mon_non_cons.rho();
     474  enc = mon_non_cons.e();
     475
     476  on_shell = (std::fabs(enc) < accuracy || pnc < accuracy);
     477
     478  if(verboseLevel > 2) {
     479    G4cout << " momentum non conservation tuning: " << G4endl
     480           << " e " << enc << " p " << pnc
     481           << (on_shell?" success":" FAILURE") << G4endl;
     482  }
     483}
     484
    368485
    369486
    370487void G4CollisionOutput::setRemainingExitationEnergy() {
    371488  eex_rest = 0.0;
    372   for(G4int i = 0; i < G4int(nucleiFragments.size()); i++)
    373     eex_rest += 0.001 * nucleiFragments[i].getExitationEnergy();
     489  for(G4int i=0; i < G4int(outgoingNuclei.size()); i++)
     490    eex_rest += outgoingNuclei[i].getExitationEnergyInGeV();
    374491}
    375492
     
    377494std::pair<std::pair<G4int, G4int>, G4int>
    378495G4CollisionOutput::selectPairToTune(G4double de) const {
    379   if (verboseLevel > 3) {
     496  if (verboseLevel > 2)
    380497    G4cout << " >>> G4CollisionOutput::selectPairToTune" << G4endl;
    381   }
    382498
    383499  std::pair<G4int, G4int> tup(-1, -1);
     
    394510  G4double p2;
    395511 
    396   for (G4int i = 0; i < G4int(outgoingParticles.size()) - 1; i++) {
     512  for (G4int i = 0; i < G4int(outgoingParticles.size())-1; i++) {
    397513    G4LorentzVector mom1 = outgoingParticles[i].getMomentum();
    398514   
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4Dineutron.cc

    r1337 r1340  
    2525//
    2626// $Id: G4Dineutron.cc,v 1.5 2010/06/25 09:44:20 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4Diproton.cc

    r1337 r1340  
    2525//
    2626// $Id: G4Diproton.cc,v 1.5 2010/06/25 09:44:22 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4ElementaryParticleCollider.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4ElementaryParticleCollider.cc,v 1.64.2.1 2010/06/25 09:44:24 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4ElementaryParticleCollider.cc,v 1.75 2010/10/19 19:48:35 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    5959// 20100517  M. Kelsey -- Inherit from common base class, make arrays static
    6060// 20100519  M. Kelsey -- Use G4InteractionCase to compute "is" values.
     61// 20100625  M. Kelsey -- Two bugs in n-body momentum, last particle recoil
     62// 20100713  M. Kelsey -- Bump collide start message up to verbose > 1
     63// 20100714  M. Kelsey -- Move conservation checking to base class
     64// 20100714  M. Kelsey -- Add sanity check for two-body final state, to ensure
     65//              that final state total mass is below etot_scm; also compute
     66//              kinematics without "rescaling" (which led to non-conservation)
     67// 20100726  M. Kelsey -- Move remaining std::vector<> buffers to .hh file
     68// 20100804  M. Kelsey -- Add printing of final-state tables, protected by
     69//              G4CASCADE_DEBUG_SAMPLER preprocessor flag
     70// 20101019  M. Kelsey -- CoVerity report: check dynamic_cast<> for null
    6171
    6272#include "G4ElementaryParticleCollider.hh"
     
    109119
    110120G4ElementaryParticleCollider::G4ElementaryParticleCollider()
    111   : G4VCascadeCollider("G4ElementaryParticleCollider") {}
     121  : G4CascadeColliderBase("G4ElementaryParticleCollider") {}
    112122
    113123
     
    117127                                      G4CollisionOutput& output)
    118128{
     129  if (verboseLevel > 1)
     130    G4cout << " >>> G4ElementaryParticleCollider::collide" << G4endl;
     131
    119132  if (!useEPCollider(bullet,target)) {          // Sanity check
    120133    G4cerr << " ElementaryParticleCollider -> can collide only particle with particle "
     
    123136  }
    124137
     138#ifdef G4CASCADE_DEBUG_SAMPLER
     139  static G4bool doPrintTables = true;   // Once and only once per job
     140  if (doPrintTables) {
     141    printFinalStateTables();            // For diagnostic reporting
     142    doPrintTables = false;
     143  }
     144#endif
     145
    125146  interCase.set(bullet, target);        // To identify kind of collision
     147
     148  if (verboseLevel > 1) {
     149    bullet->printParticle();
     150    target->printParticle();
     151  }
    126152
    127153  G4InuclElementaryParticle* particle1 =
     
    130156    dynamic_cast<G4InuclElementaryParticle*>(target);
    131157
     158  if (!particle1 || !particle2) {       // Redundant with useEPCollider()
     159    G4cerr << " ElementaryParticleCollider -> can collide only particle with particle "
     160           << G4endl;
     161    return;
     162  }
     163
    132164  if (particle1->isPhoton() || particle2->isPhoton()) {
    133     G4cout << " ElementaryParticleCollider -> cannot collide photons "
     165    G4cerr << " ElementaryParticleCollider -> cannot collide photons "
    134166           << G4endl;
    135   } else {
     167    return;
     168  }
    136169
    137170  // Generate nucleon or pion collision with nucleon
    138171  // or pion with quasi-deuteron
    139172
    140     if (particle1->nucleon() || particle2->nucleon()) { // ok
    141       G4LorentzConvertor convertToSCM;
    142       if(particle2->nucleon()) {
    143         convertToSCM.setBullet(particle1);
    144         convertToSCM.setTarget(particle2);
     173  if (particle1->nucleon() || particle2->nucleon()) { // ok
     174    G4LorentzConvertor convertToSCM;
     175    if(particle2->nucleon()) {
     176      convertToSCM.setBullet(particle1);
     177      convertToSCM.setTarget(particle2);
     178    } else {
     179      convertToSCM.setBullet(particle2);
     180      convertToSCM.setTarget(particle1);
     181    };
     182
     183    convertToSCM.setVerbose(verboseLevel);
     184
     185    convertToSCM.toTheCenterOfMass();
     186    G4double ekin = convertToSCM.getKinEnergyInTheTRS();
     187    G4double etot_scm = convertToSCM.getTotalSCMEnergy();
     188    G4double pscm = convertToSCM.getSCMMomentum();
     189
     190    generateSCMfinalState(ekin, etot_scm, pscm, particle1, particle2,
     191                          &convertToSCM);
     192   
     193    if(!particles.empty()) { // convert back to Lab
     194      G4LorentzVector mom;              // Buffer to avoid memory churn
     195      particleIterator ipart;
     196      for(ipart = particles.begin(); ipart != particles.end(); ipart++) {       
     197        mom = convertToSCM.backToTheLab(ipart->getMomentum());
     198        ipart->setMomentum(mom);
     199      };
     200
     201      // Check conservation in mutlibody final state
     202      if (verboseLevel && !validateOutput(bullet, target, particles)) {
     203        G4cout << " incoming particles: " << G4endl;
     204        particle1->printParticle();
     205        particle2->printParticle();
     206        G4cout << " outgoing particles: " << G4endl;
     207        for(ipart = particles.begin(); ipart != particles.end(); ipart++)
     208          ipart->printParticle();
     209        G4cout << " <<< Non-conservation in G4ElementaryParticleCollider"
     210               << G4endl;
     211      }
     212
     213      std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
     214      output.addOutgoingParticles(particles);
     215    };
     216  } else {
     217    if(particle1->quasi_deutron() || particle2->quasi_deutron()) {
     218      if(particle1->pion() || particle2->pion()) {
     219        G4LorentzConvertor convertToSCM;
     220        if(particle1->pion()) {
     221          convertToSCM.setBullet(particle1);
     222          convertToSCM.setTarget(particle2);
     223        } else {
     224          convertToSCM.setBullet(particle2);
     225          convertToSCM.setTarget(particle1);
     226        };
     227        convertToSCM.toTheCenterOfMass();
     228        G4double etot_scm = convertToSCM.getTotalSCMEnergy();
     229       
     230        generateSCMpionAbsorption(etot_scm, particle1, particle2);
     231
     232        if(!particles.empty()) { // convert back to Lab
     233          G4LorentzVector mom;  // Buffer to avoid memory churn
     234          particleIterator ipart;
     235          for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
     236            mom = convertToSCM.backToTheLab(ipart->getMomentum());
     237            ipart->setMomentum(mom);
     238          };
     239
     240          validateOutput(bullet, target, particles);    // Check conservation
     241
     242          std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
     243          output.addOutgoingParticles(particles);
     244        };
     245       
    145246      } else {
    146         convertToSCM.setBullet(particle2);
    147         convertToSCM.setTarget(particle1);
    148       }; 
    149       convertToSCM.toTheCenterOfMass();
    150       G4double ekin = convertToSCM.getKinEnergyInTheTRS();
    151       G4double etot_scm = convertToSCM.getTotalSCMEnergy();
    152       G4double pscm = convertToSCM.getSCMMomentum();
    153 
    154       generateSCMfinalState(ekin, etot_scm, pscm, particle1, particle2,
    155                             &convertToSCM);
    156 
    157       if(verboseLevel > 2){
    158         G4cout << " particles " << particles.size() << G4endl;
    159 
    160         for(G4int i = 0; i < G4int(particles.size()); i++)
    161           particles[i].printParticle();
    162 
    163       }
    164       if(!particles.empty()) { // convert back to Lab
    165         G4LorentzVector mom;            // Buffer to avoid memory churn
    166         particleIterator ipart;
    167         for(ipart = particles.begin(); ipart != particles.end(); ipart++) {     
    168           mom = convertToSCM.backToTheLab(ipart->getMomentum());
    169           ipart->setMomentum(mom);
    170         };
    171         std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
    172         output.addOutgoingParticles(particles);
     247        G4cerr << " ElementaryParticleCollider -> can only collide pions with deuterons "
     248               << G4endl;
    173249      };
    174250    } else {
    175       if(particle1->quasi_deutron() || particle2->quasi_deutron()) {
    176         if(particle1->pion() || particle2->pion()) {
    177           G4LorentzConvertor convertToSCM;
    178           if(particle1->pion()) {
    179             convertToSCM.setBullet(particle1);
    180             convertToSCM.setTarget(particle2);
    181           } else {
    182             convertToSCM.setBullet(particle2);
    183             convertToSCM.setTarget(particle1);
    184           };
    185           convertToSCM.toTheCenterOfMass();
    186           G4double etot_scm = convertToSCM.getTotalSCMEnergy();
    187 
    188           generateSCMpionAbsorption(etot_scm, particle1, particle2);
    189 
    190           if(!particles.empty()) { // convert back to Lab
    191             G4LorentzVector mom;        // Buffer to avoid memory churn
    192             particleIterator ipart;
    193             for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
    194               mom = convertToSCM.backToTheLab(ipart->getMomentum());
    195               ipart->setMomentum(mom);
    196             };
    197             std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
    198             output.addOutgoingParticles(particles);
    199           };
    200 
    201         } else {
    202           G4cout << " ElementaryParticleCollider -> can only collide pions with deuterons "
    203                  << G4endl;
    204         };
    205       } else {
    206         G4cout << " ElementaryParticleCollider -> can only collide something with nucleon or deuteron "
    207                << G4endl;
    208       };
    209     }; 
    210 
    211   }
    212 
     251      G4cerr << " ElementaryParticleCollider -> can only collide something with nucleon or deuteron "
     252             << G4endl;
     253    };
     254  }; 
    213255}
    214256
     
    293335  G4bool generate = true;
    294336
    295   particles.clear();            // Initialize buffers for this event
    296   particle_kinds.clear();
    297 
    298337  while (generate) {
    299     if(multiplicity == 0) {
    300       multiplicity = generateMultiplicity(is, ekin);
    301     } else {
    302       multiplicity = generateMultiplicity(is, ekin);
    303       particle_kinds.clear();
    304     }
     338    particles.clear();          // Initialize buffers for this event
     339    particle_kinds.clear();
    305340
    306341    // Generate list of final-state particles
     342    multiplicity = generateMultiplicity(is, ekin);
     343
    307344    generateOutgoingPartTypes(is, multiplicity, ekin);
    308 
    309345    if (particle_kinds.empty()) continue;
    310     // G4cout << " Particle kinds = " ;
    311     // for (G4int i = 0; i < multiplicity; i++) G4cout << particle_kinds[i] << " , " ;
    312     // G4cout << G4endl;
    313346
    314347    if (multiplicity == 2) {
     
    317350      G4int kw = (finaltype != is) ? 2 : 1;
    318351
    319       G4double pmod = pscm;     // May need to rescale momentum
    320       if (kw == 2) {
     352      G4double pmod = pscm;     // Elastic scattering preserves CM momentum
     353
     354      if (kw == 2) {            // Non-elastic needs new CM momentum value
    321355        G4double m1 = dummy.getParticleMass(particle_kinds[0]);
    322         m1 *= m1;
    323356        G4double m2 = dummy.getParticleMass(particle_kinds[1]);
    324         m2 *= m2;       
    325         G4double a = 0.5 * (etot_scm * etot_scm - m1 - m2);
    326         G4double em = a * a - m1 * m2;
    327 
    328         if (em > 0) {           //  It is possible to rescale
    329           pmod = std::sqrt( em / (m1 + m2 + 2.0 * a));
     357
     358        if (etot_scm < m1+m2) {         // Can't produce final state
     359          if (verboseLevel > 2) {
     360            G4cerr << " bad final state " << particle_kinds[0]
     361                   << " , " << particle_kinds[1] << " etot_scm " << etot_scm
     362                   << " < m1+m2 " << m1+m2 << " , but ekin " << ekin << G4endl;
     363          }
     364          continue;
    330365        }
     366
     367        G4double ecm_sq = etot_scm*etot_scm;
     368        G4double msumsq = m1+m2; msumsq *= msumsq;
     369        G4double mdifsq = m1-m2; mdifsq *= mdifsq;
     370
     371        G4double a = (ecm_sq - msumsq) * (ecm_sq - mdifsq);
     372
     373        pmod = std::sqrt(a)/(2.*etot_scm);
    331374      }
    332375
    333376      G4LorentzVector mom = sampleCMmomentumFor2to2(is, kw, ekin, pmod);
    334377
    335       if (verboseLevel > 3){
     378      if (verboseLevel > 3) {
    336379        G4cout << " Particle kinds = " << particle_kinds[0] << " , "
    337380               << particle_kinds[1] << G4endl
     381               << " pscm " << pscm << " pmod " << pmod << G4endl
    338382               << " before rotation px " << mom.x() << " py " << mom.y()
    339383               << " pz " << mom.z() << G4endl;
     
    346390          " pz " << mom.z() << G4endl;
    347391      }
    348       G4LorentzVector mom1 = -mom;
     392      G4LorentzVector mom1(-mom.vect(), mom.e());
    349393
    350394      particles.push_back(G4InuclElementaryParticle(mom, particle_kinds[0], 3));
     
    391435           
    392436            G4LorentzVector mom1 = generateWithFixedTheta(ct, modules[0]);
    393            
    394437            mom1 = toSCM->rotate(mom3, mom1);
    395            
    396             G4LorentzVector mom2 = -(mom3 + mom1);
     438
     439            // Second particle recoils off 1 & 3
     440            G4LorentzVector mom2(etot_scm);
     441            mom2 -= mom1+mom3;
    397442           
    398443            bad = false;
     
    405450        } else { // multiplicity > 3
    406451          // generate first mult - 2 momentums
    407           std::vector<G4LorentzVector> scm_momentums;
    408452          G4LorentzVector tot_mom;
     453          scm_momentums.clear();
    409454         
    410455          for (G4int i = 0; i < multiplicity - 2; i++) {
     
    479524            scm_momentums.push_back(mom);
    480525
    481             // and the last one
    482             G4LorentzVector mom1 = -(mom+tot_mom);
     526            // Last particle recoils off everything else
     527            G4LorentzVector mom1(etot_scm);
     528            mom1 -= mom+tot_mom;
    483529           
    484530            scm_momentums.push_back(mom1); 
     
    536582  // FIXME:  Code below wants to set modules[i] directly.  Bad practice
    537583  modules.clear();                      // Initialize buffer for this attempt
    538   modules.insert(modules.begin(), mult, 0.);
    539 
    540   std::vector<G4double> masses2(mult);
     584  modules.resize(mult,0.);
     585
     586  masses2.clear();
     587  masses2.resize(mult,0.);              // Allows direct [i] setting
    541588
    542589  for (G4int i = 0; i < mult; i++) {
     
    9791026
    9801027  return;
     1028}
     1029
     1030
     1031// Dump lookup tables for N-body final states
     1032
     1033void G4ElementaryParticleCollider::printFinalStateTables() const {
     1034  G4CascadeKminusNChannel::printTable();
     1035  G4CascadeKminusPChannel::printTable();
     1036  G4CascadeKplusNChannel::printTable();
     1037  G4CascadeKplusPChannel::printTable();
     1038  G4CascadeKzeroBarNChannel::printTable();
     1039  G4CascadeKzeroBarPChannel::printTable();
     1040  G4CascadeKzeroNChannel::printTable();
     1041  G4CascadeKzeroPChannel::printTable();
     1042  G4CascadeLambdaNChannel::printTable();
     1043  G4CascadeLambdaPChannel::printTable();
     1044  G4CascadeNNChannel::printTable();
     1045  G4CascadeNPChannel::printTable();
     1046  G4CascadePPChannel::printTable();
     1047  G4CascadePiMinusNChannel::printTable();
     1048  G4CascadePiMinusPChannel::printTable();
     1049  G4CascadePiPlusNChannel::printTable();
     1050  G4CascadePiPlusPChannel::printTable();
     1051  G4CascadePiZeroNChannel::printTable();
     1052  G4CascadePiZeroPChannel::printTable();
     1053  G4CascadeSigmaMinusNChannel::printTable();
     1054  G4CascadeSigmaMinusPChannel::printTable();
     1055  G4CascadeSigmaPlusNChannel::printTable();
     1056  G4CascadeSigmaPlusPChannel::printTable();
     1057  G4CascadeSigmaZeroNChannel::printTable();
     1058  G4CascadeSigmaZeroPChannel::printTable();
     1059  G4CascadeXiMinusNChannel::printTable();
     1060  G4CascadeXiMinusPChannel::printTable();
     1061  G4CascadeXiZeroNChannel::printTable();
     1062  G4CascadeXiZeroPChannel::printTable();
    9811063}
    9821064
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4EquilibriumEvaporator.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4EquilibriumEvaporator.cc,v 1.32.2.1 2010/06/25 09:44:26 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4EquilibriumEvaporator.cc,v 1.48 2010/09/24 20:51:05 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    4039//              simple data members.  Rename timeToBigBang() to override
    4140//              base explosion().
    42 
    43 #define RUN
     41// 20100617  M. Kelsey -- Remove "RUN" preprocessor flag and all "#else" code,
     42//              pass verbosity to colliders.
     43// 20100620  M. Kelsey -- Use local "bindingEnergy()" function to call through.
     44// 20100701  M. Kelsey -- Don't need to add excitation to nuclear mass; compute
     45//              new excitation energies properly (mass differences)
     46// 20100702  M. Kelsey -- Simplify if-cascades, indentation
     47// 20100712  M. Kelsey -- Add conservation checking
     48// 20100714  M. Kelsey -- Move conservation checking to base class.  Use
     49//              _generated_ evaporate energy (S) to adjust EEXS directly,
     50//              and test for S < EEXS before any particle generation; shift
     51//              nucleus momentum (PEX) by evaporate momentum directly
     52// 20100719  M. Kelsey -- Remove duplicative EESX_new calculation.
     53// 20100923  M. Kelsey -- Migrate to integer A and Z
    4454
    4555#include "G4EquilibriumEvaporator.hh"
    4656#include "G4BigBanger.hh"
     57#include "G4CascadeInterpolator.hh"
    4758#include "G4CollisionOutput.hh"
    48 #include "G4CascadeInterpolator.hh"
    4959#include "G4Fissioner.hh"
    50 #include "G4HadTmpUtil.hh"
    5160#include "G4InuclNuclei.hh"
    5261#include "G4InuclSpecialFunctions.hh"
    5362#include "G4LorentzConvertor.hh"
    5463#include "G4LorentzVector.hh"
    55 #include "G4NucleiProperties.hh"
    5664#include "G4ThreeVector.hh"
    5765
     
    6068
    6169G4EquilibriumEvaporator::G4EquilibriumEvaporator()
    62   : G4VCascadeCollider("G4EquilibriumEvaporator"),
    63     theFissioner(new G4Fissioner),
    64     theBigBanger(new G4BigBanger) {}
    65 
    66 G4EquilibriumEvaporator::~G4EquilibriumEvaporator() {
    67   delete theFissioner;
    68   delete theBigBanger;
    69 }
     70  : G4CascadeColliderBase("G4EquilibriumEvaporator") {}
     71
     72G4EquilibriumEvaporator::~G4EquilibriumEvaporator() {}
    7073
    7174
     
    7376                                      G4InuclParticle* target,
    7477                                      G4CollisionOutput& output) {
    75   if (verboseLevel > 3) {
     78  if (verboseLevel) {
    7679    G4cout << " >>> G4EquilibriumEvaporator::collide" << G4endl;
    7780  }
     
    8487  }
    8588
     89  if (verboseLevel > 1) {
     90    G4cout << " evaporating target: " << G4endl;
     91    target->printParticle();
     92  }
     93
     94  theFissioner.setVerboseLevel(verboseLevel);
     95  theBigBanger.setVerboseLevel(verboseLevel);
     96
    8697  // simple implementation of the equilibium evaporation a la Dostrowski
    8798  const G4double huge_num = 50.0;
     
    89100  const G4double prob_cut_off = 1.0e-15;
    90101  const G4double Q1[6] = { 0.0, 0.0, 2.23, 8.49, 7.72, 28.3 };
    91   const G4double AN[6] = { 1.0, 1.0, 2.0, 3.0, 3.0, 4.0 };
    92   const G4double Q[6] = { 0.0, 1.0, 1.0, 1.0, 2.0, 2.0 };
     102  const G4int AN[6] = { 1, 1, 2, 3, 3, 4 };
     103  const G4int Q[6] =  { 0, 1, 1, 1, 2, 2 };
    93104  const G4double G[6] = { 2.0, 2.0, 6.0, 6.0, 6.0, 4.0 };
    94105  const G4double BE = 0.0063;
    95106  const G4double fisssion_cut = 1000.0;
    96 
    97 #ifdef RUN
    98107  const G4double cut_off_energy = 0.1;
    99 #else
    100   const G4double cut_off_energy = 100000.0;
    101 #endif
    102108
    103109  const G4double BF = 0.0242;
     
    107113  const G4int itry_gam_max = 100;
    108114
    109   std::vector<G4double> W(8);
    110   std::vector<G4double> A1(6);
    111   std::vector<G4double> Z1(6);
    112   std::vector<G4double> u(6);
    113   std::vector<G4double> V(6);
    114   std::vector<G4double> TM(6);
    115 
    116   G4double coul_coeff;
    117 
    118     G4double A = nuclei_target->getA();
    119     G4double Z = nuclei_target->getZ();
    120     G4LorentzVector PEX = nuclei_target->getMomentum();
    121     G4double EEXS = nuclei_target->getExitationEnergy();
    122 
     115  G4double W[8], u[6], V[6], TM[6];
     116  G4int A1[6], Z1[6];
     117
     118  G4int A = nuclei_target->getA();
     119  G4int Z = nuclei_target->getZ();
     120  G4LorentzVector PEX = nuclei_target->getMomentum();
     121  G4double EEXS = nuclei_target->getExitationEnergy();
     122 
     123  if (verboseLevel > 3) G4cout << " after noeq: eexs " << EEXS << G4endl;
     124
     125  G4InuclElementaryParticle dummy(small_ekin, 1);
     126  G4LorentzConvertor toTheNucleiSystemRestFrame;
     127  //*** toTheNucleiSystemRestFrame.setVerbose(verboseLevel);
     128  toTheNucleiSystemRestFrame.setBullet(dummy);
     129
     130  G4LorentzVector ppout;
     131 
     132  // See if fragment should just be dispersed
     133  if (explosion(A, Z, EEXS)) {
     134    if (verboseLevel > 1) G4cout << " big bang in eql start " << G4endl;
     135    theBigBanger.collide(0, target, output);
     136
     137    validateOutput(0, target, output);          // Check energy conservation
     138    return;
     139  }
     140
     141  // If nucleus is in ground state, no evaporation
     142  if (EEXS < cut_off_energy) {
     143    if (verboseLevel > 1) G4cout << " no energy for evaporation" << G4endl;
     144    output.addOutgoingNucleus(*nuclei_target);
     145
     146    validateOutput(0, target, output);          // Check energy conservation
     147    return;
     148  }
     149
     150  // Initialize evaporation attempts
     151  G4double coul_coeff = (A >= 100.0) ? 1.4 : 1.2;
     152   
     153  G4LorentzVector pin = PEX;    // Save original target for testing
     154   
     155  G4bool try_again = true; 
     156  G4bool fission_open = true;
     157  G4int itry_global = 0;
     158   
     159  // Buffer for parameter sets
     160  std::pair<std::vector<G4double>, std::vector<G4double> > parms;
     161   
     162  while (try_again && itry_global < itry_global_max) {
     163    itry_global++;
     164
     165    // Set rest frame of current (recoiling) nucleus
     166    toTheNucleiSystemRestFrame.setTarget(PEX);
     167    toTheNucleiSystemRestFrame.toTheTargetRestFrame();
     168     
     169    if (verboseLevel > 2) {
     170      G4double nuc_mass = G4InuclNuclei::getNucleiMass(A, Z, EEXS);
     171      G4cout << " A " << A << " Z " << Z << " mass " << nuc_mass
     172             << " EEXS " << EEXS << G4endl;
     173    }
     174     
     175    if (explosion(A, Z, EEXS)) {                        // big bang
     176      if (verboseLevel > 2)
     177        G4cout << " big bang in eql step " << itry_global << G4endl;
     178       
     179      G4InuclNuclei nuclei(PEX, A, Z, EEXS, 6);       
     180      theBigBanger.collide(0, &nuclei, output);
     181
     182      validateOutput(0, target, output);        // Check energy conservation
     183      return;   
     184    }
     185
     186    if (EEXS < cut_off_energy) {        // Evaporation not possible
     187      if (verboseLevel > 2)
     188        G4cout << " no energy for evaporation in eql step " << itry_global
     189               << G4endl;
     190
     191      try_again = false;
     192      break;
     193    }
     194
     195    // Normal evaporation chain
     196    G4double E0 = getE0(A);
     197    G4double parlev = getPARLEVDEN(A, Z);
     198    G4double u1 = parlev * A;
     199
     200    paraMaker(Z, parms);
     201    const std::vector<G4double>& AK = parms.first;
     202    const std::vector<G4double>& CPA = parms.second;
     203
     204    G4double DM0 = bindingEnergy(A,Z);
     205    G4int i(0);
     206
     207    for (i = 0; i < 6; i++) {
     208      A1[i] = A - AN[i];
     209      Z1[i] = Z - Q[i];
     210      u[i] = parlev * A1[i];
     211      TM[i] = -0.1;
     212
     213      if (goodRemnant(A1[i], Z1[i])) {
     214        G4double QB = DM0 - bindingEnergy(A1[i],Z1[i]) - Q1[i];
     215        V[i] = coul_coeff * Z * Q[i] * AK[i] / (1.0 + EEXS / E0) /
     216          (G4cbrt(A1[i]) + G4cbrt(AN[i]));
     217        TM[i] = EEXS - QB - V[i] * A / A1[i]; 
     218      };
     219    };
     220     
     221    G4double ue = 2.0 * std::sqrt(u1 * EEXS);
     222    G4double prob_sum = 0.0;
     223
     224    W[0] = 0.0;
     225    if (TM[0] > cut_off_energy) {
     226      G4double AL = getAL(A);
     227      W[0] = BE * G4cbrt(A1[0]*A1[0]) * G[0] * AL;
     228      G4double TM1 = 2.0 * std::sqrt(u[0] * TM[0]) - ue;
     229
     230      if (TM1 > huge_num) TM1 = huge_num;
     231      else if (TM1 < small) TM1 = small;
     232
     233      W[0] *= std::exp(TM1);
     234      prob_sum += W[0];
     235    }
     236     
     237    for (i = 1; i < 6; i++) {
     238      W[i] = 0.0;
     239      if (TM[i] > cut_off_energy) {
     240        W[i] = BE * G4cbrt(A1[i]*A1[i]) * G[i] * (1.0 + CPA[i]);
     241        G4double TM1 = 2.0 * std::sqrt(u[i] * TM[i]) - ue;
     242
     243        if (TM1 > huge_num) TM1 = huge_num;
     244        else if (TM1 < small) TM1 = small;
     245
     246        W[i] *= std::exp(TM1);
     247        prob_sum += W[i];
     248      }
     249    }
     250
     251    // fisson part
     252    W[6] = 0.0;
     253    if (A >= 100.0 && fission_open) {
     254      G4double X2 = Z * Z / A;
     255      G4double X1 = 1.0 - 2.0 * Z / A;
     256      G4double X = 0.019316 * X2 / (1.0 - 1.79 * X1 * X1);
     257      G4double EF = EEXS - getQF(X, X2, A, Z, EEXS);
     258         
     259      if (EF > 0.0) {
     260        G4double AF = u1 * getAF(X, A, Z, EEXS);
     261        G4double TM1 = 2.0 * std::sqrt(AF * EF) - ue;
     262
     263        if (TM1 > huge_num) TM1 = huge_num;
     264        else if (TM1 < small) TM1 = small;
     265
     266        W[6] = BF * std::exp(TM1);
     267        if (W[6] > fisssion_cut*W[0]) W[6] = fisssion_cut*W[0];             
     268
     269        prob_sum += W[6];
     270      }
     271    }
     272
     273    // again time to decide what next
     274    if (verboseLevel > 2){
     275      G4cout << " wn " << W[0] << " wp " << W[1] << " wd " << W[2] << G4endl
     276             << " wh3 " << W[3] << " wt " << W[4] << " whe4 " << W[5] << G4endl
     277             << " wfi " << W[6] << G4endl;
     278    }
     279
     280    G4int icase = -1;
     281
     282    if (prob_sum < prob_cut_off) {              // photon emission chain
     283      G4double UCR0 = 2.5 + 150.0 / A;
     284      G4double T00 = 1.0 / (std::sqrt(u1 / UCR0) - 1.25 / UCR0);
     285      G4int itry_gam = 0;
     286
     287      while (EEXS > cut_off_energy && try_again) {
     288        itry_gam++;
     289        G4int itry = 0;
     290        G4double T04 = 4.0 * T00;
     291        G4double FMAX;
     292
     293        if (T04 < EEXS) {
     294          FMAX = (T04*T04*T04*T04) * std::exp((EEXS - T04) / T00);
     295        } else {
     296          FMAX = EEXS*EEXS*EEXS*EEXS;
     297        };
     298
     299        G4double S(0);
     300        while (itry < itry_max) {
     301          itry++;
     302          S = EEXS * inuclRndm();
     303          G4double X1 = (S*S*S*S) * std::exp((EEXS - S) / T00);
     304
     305          if (X1 > FMAX * inuclRndm()) break;
     306        };
     307
     308        if (itry == itry_max) {         // Maximum attempts exceeded
     309          try_again = false;
     310          break;
     311        }
     312
     313        if (verboseLevel > 2) G4cout << " photon escape ?" << G4endl;
     314
     315        if (S < EEXS) {         // Valid evaporate
     316          S /= GeV;                             // Convert to Bertini units
     317
     318          G4double pmod = S;
     319          G4LorentzVector mom = generateWithRandomAngles(pmod, 0.);
     320
     321          // Push evaporated particle into current rest frame
     322          mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
     323
     324          if (verboseLevel > 3) {
     325            G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
     326                   << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
     327                   << " evaporate px " << mom.px() << " py " << mom.py()
     328                   << " pz " << mom.pz() << " E " << mom.e() << G4endl;
     329          }
     330
     331          PEX -= mom;                   // Remaining four-momentum
     332          EEXS -= S*GeV;                // New excitation energy (in MeV)
     333
     334          G4InuclElementaryParticle particle(mom, 10, 6);
     335          output.addOutgoingParticle(particle);
     336         
     337          if (verboseLevel > 3) particle.printParticle();
     338         
     339          ppout += mom;
     340        } else {
     341          if (itry_gam == itry_gam_max) try_again = false;
     342        }
     343      }         // while (EEXS > cut_off
     344      try_again = false;
     345    } else {                    // if (prob_sum < prob_cut_off)
     346      G4double SL = prob_sum * inuclRndm();
     347      G4double S1 = 0.0;
     348
     349      for (G4int i = 0; i < 7; i++) {   // Select evaporation scenario
     350        S1 += W[i];
     351        if (SL <= S1) {
     352          icase = i;
     353          break;
     354        };
     355      };
     356
     357      if (icase < 6) { // particle or light nuclei escape
     358        if (verboseLevel > 2)
     359          G4cout << " particle/light-ion escape ?" << G4endl;
     360
     361        G4double uc = 2.0 * std::sqrt(u[icase] * TM[icase]);
     362        G4double ur = (uc > huge_num ? std::exp(huge_num) : std::exp(uc));
     363        G4double d1 = 1.0 / ur;
     364        G4double d2 = 1.0 / (ur - 1.0);     
     365        G4int itry1 = 0;
     366        G4bool bad = true;
     367
     368        while (itry1 < itry_max && bad) {
     369          itry1++;
     370          G4int itry = 0;
     371          G4double EPR = -1.0;
     372          G4double S = 0.0;
     373
     374          while (itry < itry_max && EPR < 0.0) {
     375            itry++;
     376            G4double uu = uc + std::log((1.0 - d1) * inuclRndm() + d2);
     377            S = 0.5 * (uc * uc - uu * uu) / u[icase];
     378            EPR = TM[icase] - S * A / (A - 1.0) + V[icase];
     379          };
     380           
     381          if (EPR > 0.0 && S > V[icase]) { // real escape
     382            if (verboseLevel > 2)
     383              G4cout << " escape itry1 " << itry1 << " icase "
     384                     << icase << " S (MeV) " << S << G4endl;
     385
     386            if (S < EEXS) {             // Valid evaporate
     387              S /= GeV;                         // Convert to Bertini units
     388
     389              if (icase < 2) {  // particle escape
     390                G4int ptype = 2 - icase;
     391                if (verboseLevel > 2)
     392                  G4cout << " particle " << ptype << " escape" << G4endl;
     393               
     394                G4InuclElementaryParticle particle(ptype);
     395                particle.setModel(6);
     396               
     397                // generate particle momentum
     398                G4double mass = particle.getMass();
     399                G4double pmod = std::sqrt((2.0 * mass + S) * S);
     400                G4LorentzVector mom = generateWithRandomAngles(pmod, mass);
     401
     402                // Push evaporated particle into current rest frame
     403                mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
     404
     405                if (verboseLevel > 2) {
     406                  G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
     407                         << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
     408                         << " evaporate px " << mom.px() << " py " << mom.py()
     409                         << " pz " << mom.pz() << " E " << mom.e() << G4endl;
     410                }
     411               
     412                // New excitation energy depends on residual nuclear state
     413                G4double mass_new =
     414                  G4InuclNuclei::getNucleiMass(A1[icase],Z1[icase]);
     415
     416                G4double EEXS_new = ((PEX-mom).m() - mass_new)*GeV;
     417                if (EEXS_new < 0.0) continue;   // Sanity check for new nucleus
     418
     419                PEX -= mom;             // Remaining four-momentum
     420                EEXS = EEXS_new;
     421
     422                A = A1[icase];
     423                Z = Z1[icase];       
     424
     425                particle.setMomentum(mom);
     426                output.addOutgoingParticle(particle);
     427                if (verboseLevel > 3) particle.printParticle();
     428
     429                ppout += mom;
     430                bad = false;
     431              } else {  // if (icase < 2)
     432                if (verboseLevel > 2) {
     433                  G4cout << " nucleus A " << AN[icase] << " Z " << Q[icase]
     434                         << " escape icase " << icase << G4endl;
     435                }
     436               
     437                G4InuclNuclei nuclei(AN[icase], Q[icase]);
     438                nuclei.setModel(6);
     439                G4double mass = nuclei.getMass();
     440                // generate particle momentum
     441                G4double pmod = std::sqrt((2.0 * mass + S) * S);
     442                G4LorentzVector mom = generateWithRandomAngles(pmod,mass);
     443               
     444                // Push evaporated particle into current rest frame
     445                mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
     446
     447                if (verboseLevel > 2) {
     448                  G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
     449                         << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
     450                         << " evaporate px " << mom.px() << " py " << mom.py()
     451                         << " pz " << mom.pz() << " E " << mom.e() << G4endl;
     452                }
     453               
     454                // New excitation energy depends on residual nuclear state
     455                G4double mass_new =
     456                  G4InuclNuclei::getNucleiMass(A1[icase],Z1[icase]);
     457
     458                G4double EEXS_new = ((PEX-mom).m() - mass_new)*GeV;
     459                if (EEXS_new < 0.0) continue;   // Sanity check for new nucleus
     460
     461                PEX -= mom;             // Remaining four-momentum
     462                EEXS = EEXS_new;
     463
     464                A = A1[icase];
     465                Z = Z1[icase];
     466
     467                nuclei.setMomentum(mom);
     468                output.addOutgoingNucleus(nuclei);
     469                if (verboseLevel > 3) nuclei.printParticle();
     470
     471                ppout += mom;
     472                bad = false;
     473              }         // if (icase < 2)
     474            }           // if (S < EEXS)
     475          }             // if (EPR > 0.0 ...
     476        }               // while (itry1 ...
     477
     478        if (itry1 == itry_max || bad) try_again = false;
     479      } else {  // if (icase < 6)
     480        G4InuclNuclei nuclei(A, Z, EEXS);       
     481        nuclei.setModel(6);
     482
     483        if (verboseLevel > 2) {
     484          G4cout << " fission: A " << A << " Z " << Z << " eexs " << EEXS
     485                 << " Wn " << W[0] << " Wf " << W[6] << G4endl;
     486        }
     487
     488        // Catch fission output separately for verification
     489        G4CollisionOutput foutput;
     490        theFissioner.collide(0, &nuclei, foutput);
     491
     492        if (foutput.getOutgoingNuclei().size() == 2) { // fission o'k
     493          if (verboseLevel > 2) G4cout << " fission done in eql" << G4endl;
     494
     495          // Move fission fragments to lab frame for processing
     496          foutput.boostToLabFrame(toTheNucleiSystemRestFrame);
     497
     498          // Now evaporate the fission fragments individually
     499          G4bool prevDoChecks = doConservationChecks;   // Turn off checking
     500          setConservationChecks(false);
     501
     502          std::vector<G4InuclNuclei> nuclea = foutput.getOutgoingNuclei();
     503          this->collide(0, &nuclea[0], output);
     504          this->collide(0, &nuclea[1], output);
     505
     506          setConservationChecks(prevDoChecks);  // Restore previous flag value
     507          validateOutput(0, target, output);    // Check energy conservation
     508          return;
     509        } else { // fission forbidden now
     510          fission_open = false;
     511        }
     512      }         // End of fission case
     513    }           // if (prob_sum < prob_cut_off)
     514  }             // while (try_again
     515
     516  // this time it's final nuclei
     517
     518  if (itry_global == itry_global_max) {
    123519    if (verboseLevel > 3) {
    124       if (EEXS < 0.0) G4cout << " after noeq: eexs " << EEXS << G4endl;
     520      G4cout << " ! itry_global " << itry_global_max << G4endl;
    125521    }
    126 
    127     G4InuclElementaryParticle dummy(small_ekin, 1);
    128     G4LorentzConvertor toTheNucleiSystemRestFrame;
    129     toTheNucleiSystemRestFrame.setBullet(dummy);
    130     G4LorentzVector ppout;
    131  
    132     if (explosion(A, Z, EEXS)) {
    133 
    134       if (verboseLevel > 3) {
    135         G4cout << " big bang in eql start " << G4endl;
    136       }
    137 
    138       theBigBanger->collide(0, target, output);
    139       return;
    140     } else {     
    141 
    142       if (A >= 100.0) {
    143         coul_coeff = 1.4;
    144 
    145       } else {
    146         coul_coeff = 1.2;
    147       };   
    148    
    149       G4InuclNuclei dummy_nuc;
    150       G4double EEXS_new;
    151       G4LorentzVector pin = PEX;
    152       pin.setE(pin.e() + 0.001 * EEXS);
    153       G4bool try_again = true; 
    154       G4bool fission_open = true;
    155       G4double nuc_mass; 
    156       G4int itry_global = 0;
    157 
    158       // Buffer for parameter sets
    159       std::pair<std::vector<G4double>, std::vector<G4double> > parms;
    160 
    161       while (try_again && itry_global < itry_global_max) {
    162         itry_global++;
    163 
    164         if (verboseLevel > 2){
    165           G4cout << " A " << A << " Z " << Z << " EEXS " << EEXS << G4endl;
    166         }
    167 
    168         nuc_mass = dummy_nuc.getNucleiMass(A, Z);
    169         PEX.setVectM(PEX.vect(), nuc_mass);     
    170         toTheNucleiSystemRestFrame.setTarget(PEX, nuc_mass);
    171         toTheNucleiSystemRestFrame.toTheTargetRestFrame();
    172 
    173         if (explosion(A, Z, EEXS)) { // big bang
    174      
    175           if (verboseLevel > 2){
    176             G4cout << " big bang in eql step " << G4endl;
    177           }
    178 
    179           G4InuclNuclei nuclei(PEX, A, Z);       
    180 
    181           nuclei.setModel(6);
    182           nuclei.setExitationEnergy(EEXS);     
    183 
    184           theBigBanger->collide(0, &nuclei, output);
    185           return;       
    186 
    187         } else { // normal chain
    188 
    189           if (EEXS > cut_off_energy) {
    190 
    191             G4double E0 = getE0(A);
    192             G4double parlev = getPARLEVDEN(A, Z);
    193             G4double u1 = parlev * A;
    194 
    195             paraMaker(Z, parms);
    196             const std::vector<G4double>& AK = parms.first;
    197             const std::vector<G4double>& CPA = parms.second;
    198 
    199             //      G4double DM0 = bindingEnergy(A, Z);   
    200             G4double DM0 = G4NucleiProperties::GetBindingEnergy(G4lrint(A), G4lrint(Z));
    201             G4int i(0);
    202 
    203             for (i = 0; i < 6; i++) {
    204               A1[i] = A - AN[i];
    205               Z1[i] = Z - Q[i];
    206               u[i] = parlev * A1[i];
    207               TM[i] = -0.1;
    208 
    209               if (goodRemnant(A1[i], Z1[i])) {
    210                 //              G4double QB = DM0 - bindingEnergy(A1[i], Z1[i]) - Q1[i];
    211                 G4double QB = DM0 - G4NucleiProperties::GetBindingEnergy(G4lrint(A1[i]), G4lrint(Z1[i])) - Q1[i];
    212                 V[i] = coul_coeff * Z * Q[i] * AK[i] / (1.0 + EEXS / E0) /
    213                   (G4cbrt(A1[i]) + G4cbrt(AN[i]));
    214                 TM[i] = EEXS - QB - V[i] * A / A1[i]; 
    215               };
    216             };
    217      
    218             G4double ue = 2.0 * std::sqrt(u1 * EEXS);
    219             G4double prob_sum = 0.0;
    220        
    221             if (TM[0] > cut_off_energy) {
    222               G4double AL = getAL(A);
    223               W[0] = BE * G4cbrt(A1[0]*A1[0]) * G[0] * AL;
    224               G4double TM1 = 2.0 * std::sqrt(u[0] * TM[0]) - ue;
    225 
    226               if (TM1 > huge_num) {
    227                 TM1 = huge_num;
    228 
    229               } else if (TM1 < small) {
    230                 TM1 = small;
    231               };
    232               W[0] = W[0] * std::exp(TM1);
    233               prob_sum += W[0];
    234 
    235             } else {
    236               W[0] = 0.0;
    237             };
    238      
    239             for (i = 1; i < 6; i++) {
    240 
    241               if (TM[i] > cut_off_energy) {
    242                 W[i] = BE * G4cbrt(A1[i]*A1[i]) * G[i] * (1.0 + CPA[i]);
    243                 G4double TM1 = 2.0 * std::sqrt(u[i] * TM[i]) - ue;
    244 
    245                 if (TM1 > huge_num) {
    246                   TM1 = huge_num;
    247 
    248                 } else if (TM1 < small) {
    249                   TM1 = small;
    250                 };
    251                 W[i] = W[i] * std::exp(TM1);
    252                 prob_sum += W[i];
    253 
    254               } else {
    255                 W[i] = 0.0;
    256               };
    257             };
    258 
    259             // fisson part
    260             W[6] = 0.0;
    261 
    262             if (A >= 100.0 && fission_open) {
    263               G4double X2 = Z * Z / A;
    264               G4double X1 = 1.0 - 2.0 * Z / A;
    265               G4double X = 0.019316 * X2 / (1.0 - 1.79 * X1 * X1);
    266               G4double EF = EEXS - getQF(X, X2, A, Z, EEXS);
    267          
    268               if (EF > 0.0) {
    269                 G4double AF = u1 * getAF(X, A, Z, EEXS);
    270                 G4double TM1 = 2.0 * std::sqrt(AF * EF) - ue;
    271 
    272                 if (TM1 > huge_num) {
    273                   TM1 = huge_num;
    274 
    275                 } else if (TM1 < small) {
    276                   TM1 = small;
    277                 };
    278                 W[6] = BF * std::exp(TM1);
    279 
    280                 if (W[6] > fisssion_cut * W[0]) W[6] = fisssion_cut * W[0];         
    281                 prob_sum += W[6];
    282               };
    283             }; 
    284             // again time to decide what next
    285 
    286             if (verboseLevel > 2){
    287             G4cout << " wn = " << W[0] << " , wp = " << W[1] << " , wd = " << W[2] << G4endl
    288                      << " wh3 " << W[3] << " wt " << W[4] << " whe4 " << W[5] << G4endl
    289                      << " wfi " << W[6] << G4endl;
    290             }
    291 
    292             G4int icase = -1;
    293 
    294             if (prob_sum < prob_cut_off) { // photon emission chain
    295               G4double UCR0 = 2.5 + 150.0 / A;
    296               G4double T00 = 1.0 / (std::sqrt(u1 / UCR0) - 1.25 / UCR0);
    297               G4int itry_gam = 0;
    298 
    299               while (EEXS > cut_off_energy && try_again) {
    300                 itry_gam++;
    301                 G4int itry = 0;
    302                 G4double T04 = 4.0 * T00;
    303                 G4double FMAX;
    304 
    305                 if (T04 < EEXS) {
    306                   FMAX = (T04*T04*T04*T04) * std::exp((EEXS - T04) / T00);
    307                 } else {
    308                   FMAX = EEXS*EEXS*EEXS*EEXS;
    309                 };
    310 
    311                 G4double S(0);
    312 
    313                 while (itry < itry_max) {
    314                   itry++;
    315                   S = EEXS * inuclRndm();
    316                   G4double X1 = (S*S*S*S) * std::exp((EEXS - S) / T00);
    317 
    318                   if (X1 > FMAX * inuclRndm()) break;
    319                 };
    320 
    321                 if (itry < itry_max) {
    322                   // new photon escape
    323                   G4InuclElementaryParticle particle(10);
    324 
    325                   particle.setModel(6);
    326                   G4double pmod = 0.001 * S;
    327                   G4LorentzVector mom = generateWithRandomAngles(pmod, 0.);
    328 
    329                   G4LorentzVector ex_mom;
    330                   ex_mom.setVectM(-mom.vect(), nuc_mass);
    331 
    332                   mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
    333                   ex_mom = toTheNucleiSystemRestFrame.backToTheLab(ex_mom);
    334 
    335                   EEXS_new = 1000.0 * (PEX.e() + 0.001 * EEXS -
    336                                        mom.e() - ex_mom.e());
    337 
    338                   if (EEXS_new > 0.0) { // everything ok
    339                     PEX = ex_mom;
    340                     EEXS = EEXS_new;
    341                     particle.setMomentum(mom);
    342                     output.addOutgoingParticle(particle);
    343 
    344                     ppout += mom;
    345 
    346                   } else {
    347 
    348                     if (itry_gam == itry_gam_max) try_again = false;
    349                   };
    350 
    351                 } else {
    352                   try_again = false;
    353                 };
    354               };
    355               try_again = false;
    356 
    357             } else {
    358               G4double SL = prob_sum * inuclRndm();
    359               G4double S1 = 0.0;
    360 
    361               for (G4int i = 0; i < 7; i++) {
    362                 S1 += W[i];
    363        
    364                 if (SL <= S1) {
    365                   icase = i;
    366 
    367                   break;
    368                 };
    369               };
    370 
    371               if (icase < 6) { // particle or light nuclei escape
    372                 G4double uc = 2.0 * std::sqrt(u[icase] * TM[icase]);
    373                 G4double ur = (uc > huge_num ? std::exp(huge_num) : std::exp(uc));
    374                 G4double d1 = 1.0 / ur;
    375                 G4double d2 = 1.0 / (ur - 1.0);     
    376                 G4int itry1 = 0;
    377                 G4bool bad = true;
    378 
    379                 while (itry1 < itry_max && bad) {
    380                   itry1++;
    381                   G4int itry = 0;
    382                   G4double EPR = -1.0;
    383                   G4double S = 0.0;
    384 
    385                   while (itry < itry_max && EPR < 0.0) {
    386                     itry++;
    387                     G4double uu = uc + std::log((1.0 - d1) * inuclRndm() + d2);
    388                     S = 0.5 * (uc * uc - uu * uu) / u[icase];
    389                     EPR = TM[icase] - S * A / (A - 1.0) + V[icase];
    390                   };
    391            
    392                   if (EPR > 0.0 && S > V[icase]) { // real escape
    393                     S = 0.001 * S;
    394 
    395                     if (icase < 2) { // particle escape
    396                       G4int ptype = 2 - icase;
    397                       G4InuclElementaryParticle particle(ptype);
    398 
    399                       particle.setModel(6);
    400                       G4double mass = particle.getMass();
    401                       // generate particle momentum
    402                       G4double pmod = std::sqrt((2.0 * mass + S) * S);
    403                       G4LorentzVector mom = generateWithRandomAngles(pmod, mass);
    404 
    405                       G4double new_nuc_mass =
    406                         dummy_nuc.getNucleiMass(A1[icase], Z1[icase]);
    407 
    408                       G4LorentzVector ex_mom;
    409                       ex_mom.setVectM(-mom.vect(), new_nuc_mass);
    410 
    411                       mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
    412                       ex_mom = toTheNucleiSystemRestFrame.backToTheLab(ex_mom);
    413 
    414                       EEXS_new = 1000.0 * (PEX.e() + 0.001 * EEXS -
    415                                            mom.e() - ex_mom.e());
    416 
    417                       if (EEXS_new > 0.0) { // everything ok
    418                         PEX = ex_mom;
    419                         EEXS = EEXS_new;
    420                         A = A1[icase];
    421                         Z = Z1[icase];       
    422                         particle.setMomentum(mom);
    423                         output.addOutgoingParticle(particle);
    424                         ppout += mom;
    425                         bad = false;
    426                       };
    427                     } else {
    428                       G4InuclNuclei nuclei(AN[icase], Q[icase]);
    429                       nuclei.setModel(6);
    430                       G4double mass = nuclei.getMass();
    431                       // generate particle momentum
    432                       G4double pmod = std::sqrt((2.0 * mass + S) * S);
    433                       G4LorentzVector mom = generateWithRandomAngles(pmod,mass);
    434 
    435                       G4double new_nuc_mass =
    436                         dummy_nuc.getNucleiMass(A1[icase], Z1[icase]);
    437 
    438                       G4LorentzVector ex_mom;
    439                       ex_mom.setVectM(-mom.vect(), new_nuc_mass);
    440 
    441                       mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
    442                       ex_mom = toTheNucleiSystemRestFrame.backToTheLab(ex_mom);
    443 
    444                       EEXS_new = 1000.0 * (PEX.e() + 0.001 * EEXS -
    445                                            mom.e() - ex_mom.e());
    446 
    447                       if (EEXS_new > 0.0) { // everything ok
    448                         PEX = ex_mom;
    449                         EEXS = EEXS_new;
    450                         A = A1[icase];
    451                         Z = Z1[icase];
    452              
    453                         ppout += mom;
    454                         nuclei.setExitationEnergy(0.0);
    455                         nuclei.setMomentum(mom);
    456                         output.addTargetFragment(nuclei);
    457                         bad = false;
    458                       };
    459                     };
    460                   };
    461                 };
    462 
    463                 if (itry1 == itry_max || bad)  try_again = false;
    464 
    465               } else { // fission
    466                 G4InuclNuclei nuclei(A, Z);       
    467                 nuclei.setModel(6);
    468                 nuclei.setExitationEnergy(EEXS);
    469 
    470                 if (verboseLevel > 2){
    471                   G4cout << " fission: A " << A << " Z " << Z << " eexs " << EEXS <<
    472                     " Wn " << W[0] << " Wf " << W[6] << G4endl;
    473                 }
    474 
    475                 // Catch fission output separately for verification
    476                 G4CollisionOutput foutput;
    477                 theFissioner->collide(0, &nuclei, foutput);
    478 
    479                 if (foutput.getNucleiFragments().size() == 2) { // fission o'k
    480                   // Copy fragment list and convert back to the lab
    481                   std::vector<G4InuclNuclei> nuclea(foutput.getNucleiFragments());
    482                   G4LorentzVector mom;
    483                   for(G4int i = 0; i < 2; i++) {
    484                     mom = toTheNucleiSystemRestFrame.backToTheLab(nuclea[i].getMomentum());
    485                     nuclea[i].setMomentum(mom);
    486                   }
    487 
    488                   this->collide(0, &nuclea[0], output);
    489                   this->collide(0, &nuclea[1], output);
    490                   return;
    491                 } else { // fission forbidden now
    492                   fission_open = false;
    493                 };
    494               };
    495             };
    496              
    497           } else {
    498             try_again = false;
    499           };
    500         };
    501       };
    502       // this time it's final nuclei
    503 
    504       if (itry_global == itry_global_max) {
    505 
    506         if (verboseLevel > 3) {
    507           G4cout << " ! itry_global " << itry_global_max << G4endl;
    508         }
    509 
    510       }
    511 
    512       G4LorentzVector pnuc = pin - ppout;
    513 
    514       G4InuclNuclei nuclei(pnuc, A, Z);
    515       nuclei.setModel(6);
    516       pnuc = nuclei.getMomentum();
    517       G4double eout = pnuc.e() + ppout.e(); 
    518       G4double eex_real = 1000.0 * (pin.e() - eout);       
    519    
    520       nuclei.setExitationEnergy(eex_real);
    521    
    522       output.addTargetFragment(nuclei);
    523     }
    524 
     522  }
     523
     524  G4LorentzVector pnuc = pin - ppout;
     525
     526  G4InuclNuclei nuclei(pnuc, A, Z, EEXS, 6);
     527
     528  /***** THIS SHOULD NOT BE NECESSARY IF EEXS WAS COMPUTED RIGHT
     529  pnuc = nuclei.getMomentum();
     530  G4double eout = pnuc.e() + ppout.e(); 
     531  G4double eex_real = 1000.0 * (pin.e() - eout);       
     532  nuclei.setExitationEnergy(eex_real);
     533  *****/
     534
     535  if (verboseLevel > 3) {
     536    G4cout << " remaining nucleus " << G4endl;
     537    nuclei.printParticle();
     538  }
     539
     540  output.addOutgoingNucleus(nuclei);
     541
     542  validateOutput(0, target, output);            // Check energy conservation
    525543  return;
    526544}                   
    527545
    528 G4bool G4EquilibriumEvaporator::explosion(G4double a,
    529                                           G4double z,
     546G4bool G4EquilibriumEvaporator::explosion(G4int a,
     547                                          G4int z,
    530548                                          G4double e) const {
    531549  if (verboseLevel > 3) {
     
    536554
    537555  // Different criteria from base class, since nucleus more "agitated"
    538   G4bool bigb = (!(a >= 12 && z >= 6.0 && z < 3.0 * (a - z)) &&
    539                  (e >= be_cut * G4NucleiProperties::GetBindingEnergy(G4lrint(a), G4lrint(z)))
     556  G4bool bigb = (!(a >= 12 && z >= 0 && z < 3*(a-z)) &&
     557                 (e >= be_cut * bindingEnergy(a,z))
    540558                 );
    541559
     
    543561}
    544562
    545 G4bool G4EquilibriumEvaporator::goodRemnant(G4double a,
    546                                             G4double z) const {
     563G4bool G4EquilibriumEvaporator::goodRemnant(G4int a,
     564                                            G4int z) const {
    547565  if (verboseLevel > 3) {
    548566    G4cout << " >>> G4EquilibriumEvaporator::goodRemnant" << G4endl;
    549567  }
    550568
    551   return a > 1.0 && z > 0.0 && a > z;
     569  return a > 1 && z > 0 && a > z;
    552570}
    553571
    554572G4double G4EquilibriumEvaporator::getQF(G4double x,
    555573                                        G4double x2,
    556                                         G4double a,
    557                                         G4double ,
     574                                        G4int a,
     575                                        G4int /*z*/,
    558576                                        G4double ) const {
    559577  if (verboseLevel > 3) {
     
    634652
    635653G4double G4EquilibriumEvaporator::getAF(G4double ,
    636                                         G4double ,
    637                                         G4double ,
     654                                        G4int /*a*/,
     655                                        G4int /*z*/,
    638656                                        G4double e) const {
    639657
     
    651669}       
    652670
    653 G4double G4EquilibriumEvaporator::getPARLEVDEN(G4double ,
    654                                                G4double ) const {
     671G4double G4EquilibriumEvaporator::getPARLEVDEN(G4int /*a*/,
     672                                               G4int /*z*/) const {
    655673
    656674  if (verboseLevel > 3) {
     
    663681}
    664682
    665 G4double G4EquilibriumEvaporator::getE0(G4double ) const {
     683G4double G4EquilibriumEvaporator::getE0(G4int /*a*/) const {
    666684
    667685  if (verboseLevel > 3) {
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4EvaporationInuclCollider.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EvaporationInuclCollider.cc,v 1.11 2010/06/25 09:44:28 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4EvaporationInuclCollider.cc,v 1.12 2010/07/14 15:41:13 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3232// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3333//              simple data members.  Eliminate unnecessary G4InuclNuclei ctor.
     34// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class
    3435
    3536#include "G4EvaporationInuclCollider.hh"
     
    4445         
    4546G4EvaporationInuclCollider::G4EvaporationInuclCollider()
    46   : G4VCascadeCollider("G4EvaporationInuclCollider"),
     47  : G4CascadeColliderBase("G4EvaporationInuclCollider"),
    4748    theEquilibriumEvaporator(new G4EquilibriumEvaporator) {}
    4849
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4FissionStore.cc

    r1315 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4FissionStore.cc,v 1.16 2010/10/19 21:33:58 mkelsey Exp $
    2526//
     27// 20100728  Move ::addConfig() implementation to .cc file
     28
    2629#include "G4FissionStore.hh"
     30#include "G4FissionConfiguration.hh"
    2731#include <cmath>
    2832
    29 G4FissionStore::G4FissionStore()
    30   : verboseLevel(0){
     33G4FissionStore::G4FissionStore() : verboseLevel(0) {
     34  if (verboseLevel > 1)
     35    G4cout << " >>> G4FissionStore::G4FissionStore" << G4endl;
     36}
    3137
    32   if (verboseLevel > 3) {
    33     G4cout << " >>> G4FissionStore::G4FissionStore" << G4endl;
    34   }
     38void G4FissionStore::addConfig(G4double a, G4double z, G4double ez,
     39                               G4double ek, G4double ev) {
     40  G4FissionConfiguration config(a, z, ez, ek, ev);
     41  configurations.push_back(config);
     42  if (verboseLevel > 2) config.print();
    3543}
    3644
    3745G4FissionConfiguration G4FissionStore::generateConfiguration(G4double amax,
    3846                                                             G4double rand) const {
    39 
    40   if (verboseLevel > 3) {
     47  if (verboseLevel > 1)
    4148    G4cout << " >>> G4FissionStore::generateConfiguration" << G4endl;
    42   }
    4349 
    4450  const G4double small = -30.0;
    4551
    4652  G4double totProb = 0.0;
    47   std::vector<G4double> probs(configurations.size());
     53  std::vector<G4double> probs(size());
    4854
    49 // G4cout << " amax " << amax << " ic " << configurations.size() << G4endl;
     55  if (verboseLevel > 3)
     56    G4cout << " amax " << amax << " ic " << size() << G4endl;
    5057
    51   for (G4int i = 0; i < G4int(configurations.size()); i++) {
     58  for (G4int i = 0; i < size(); i++) {
    5259    G4double ez = configurations[i].ezet;
    5360    G4double pr = ez - amax;
     
    6471  G4int igen = 0;
    6572
    66   while (probs[igen] <= st && igen < G4int(configurations.size())) igen++;
     73  while (probs[igen] <= st && igen < size()) igen++;
    6774
    68 // G4cout << " igen " << igen << G4endl;
     75  if (verboseLevel > 3) G4cout << " igen " << igen << G4endl;
    6976
    7077  return configurations[igen];
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4Fissioner.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4Fissioner.cc,v 1.28.2.1 2010/06/25 09:44:30 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4Fissioner.cc,v 1.37 2010/09/24 20:51:05 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3332// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
    3433// 20100517  M. Kelsey -- Inherit from common base class
     34// 20100622  M. Kelsey -- Use local "bindingEnergy()" to call through
     35// 20100711  M. Kelsey -- Add energy-conservation checking, reduce if-cascades
     36// 20100713  M. Kelsey -- Don't add excitation energy to mass (already there)
     37// 20100714  M. Kelsey -- Move conservation checking to base class
     38// 20100728  M. Kelsey -- Make fixed arrays static, move G4FissionStore to data
     39//              member and reuse
     40// 20100914  M. Kelsey -- Migrate to integer A and Z
    3541
    3642#include "G4Fissioner.hh"
    3743#include "G4CollisionOutput.hh"
     44#include "G4HadTmpUtil.hh"
    3845#include "G4InuclNuclei.hh"
    3946#include "G4InuclParticle.hh"
    4047#include "G4FissionStore.hh"
    4148#include "G4FissionConfiguration.hh"
    42 #include "G4NucleiProperties.hh"
    43 #include "G4HadTmpUtil.hh"
    4449#include "G4InuclSpecialFunctions.hh"
    4550
     
    4752
    4853
    49 G4Fissioner::G4Fissioner() : G4VCascadeCollider("G4Fissioner") {}
     54G4Fissioner::G4Fissioner() : G4CascadeColliderBase("G4Fissioner") {}
    5055
    5156void G4Fissioner::collide(G4InuclParticle* /*bullet*/,
    5257                          G4InuclParticle* target,
    5358                          G4CollisionOutput& output) {
    54   if (verboseLevel > 3) {
     59  if (verboseLevel) {
    5560    G4cout << " >>> G4Fissioner::collide" << G4endl;
    5661  }
     
    5863  //  const G4int itry_max = 1000;
    5964
    60   if (G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target)) {
    61 
    62     if (verboseLevel > 3) {
    63       G4cout << " Fissioner input " << G4endl;
    64 
    65       nuclei_target->printParticle();
    66     }
    67 
    68     G4double A = nuclei_target->getA();
    69     G4double Z = nuclei_target->getZ();
    70     G4double EEXS = nuclei_target->getExitationEnergy();
    71     G4double mass_in = nuclei_target->getMass();
    72     G4double e_in = mass_in + 0.001 * EEXS;
    73     G4double PARA = 0.055 * G4cbrt(A*A) * (G4cbrt(A - Z) + G4cbrt(Z));
    74     G4double TEM = std::sqrt(EEXS / PARA);
    75     G4double TETA = 0.494 * G4cbrt(A) * TEM;
    76 
    77     TETA = TETA / std::sinh(TETA);
    78 
    79     if (A < 246.0) PARA += (nucleiLevelDensity(A) - PARA) * TETA;
    80 
    81     G4double A1 = G4int(A / 2.0 + 1.1);
    82     G4double Z1;
    83     G4double A2 = A - A1;
    84     G4double ALMA = -1000.0;
    85     //    G4double DM1 = bindingEnergy(A, Z);
    86     G4double DM1 = G4NucleiProperties::GetBindingEnergy(G4lrint(A), G4lrint(Z));
    87     G4double EVV = EEXS - DM1;
    88     G4double DM2 = bindingEnergyAsymptotic(A, Z);
    89     G4double DTEM = (A < 220.0 ? 0.5 : 1.15);
    90 
    91     TEM += DTEM;
    92  
    93     std::vector<G4double> AL1(2, -0.15);
    94     std::vector<G4double> BET1(2, 0.05);
    95     G4FissionStore fissionStore;
    96     G4double R12 = G4cbrt(A1) + G4cbrt(A2);
    97  
    98     for (G4int i = 0; i < 50 && A1 > 30.0; i++) {
    99       A1 -= 1.0;
    100       A2 = A - A1;
    101       G4double X3 = 1.0 / G4cbrt(A1);
    102       G4double X4 = 1.0 / G4cbrt(A2);
    103       Z1 = G4int(getZopt(A1, A2, Z, X3, X4, R12)) - 1.0;
    104       std::vector<G4double> EDEF1(2);
    105       G4double Z2 = Z - Z1;
    106       G4double VPOT, VCOUL;
    107 
    108       potentialMinimization(VPOT, EDEF1, VCOUL, A1, A2, Z1, Z2, AL1, BET1, R12);
    109 
    110       //      G4double DM3 = bindingEnergy(A1, Z1);
    111       G4double DM3 = G4NucleiProperties::GetBindingEnergy(G4lrint(A1), G4lrint(Z1));
    112       G4double DM4 = bindingEnergyAsymptotic(A1, Z1);
    113       //      G4double DM5 = bindingEnergy(A2, Z2);
    114       G4double DM5 = G4NucleiProperties::GetBindingEnergy(G4lrint(A2), G4lrint(Z2));
    115       G4double DM6 = bindingEnergyAsymptotic(A2, Z2);
    116       G4double DMT1 = DM4 + DM6 - DM2;
    117       G4double DMT = DM3 + DM5 - DM1;
    118       G4double EZL = EEXS + DMT - VPOT;
     65  G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target);
     66  if (!nuclei_target) {
     67    G4cerr << " >>> G4Fissioner -> target is not nuclei " << G4endl;
     68    return;
     69  }
     70
     71  if (verboseLevel > 1) {
     72    G4cout << " Fissioner input " << G4endl;
     73    nuclei_target->printParticle();
     74  }
     75
     76  // Initialize buffer for fission possibilities
     77  fissionStore.setVerboseLevel(verboseLevel);
     78  fissionStore.clear();
     79
     80  G4int A = nuclei_target->getA();
     81  G4int Z = nuclei_target->getZ();
     82
     83  G4double EEXS = nuclei_target->getExitationEnergy();
     84  G4double mass_in = nuclei_target->getMass();
     85  G4double e_in = mass_in; /**** + 0.001 * EEXS; ****/  // Mass includes EEXS
     86  G4double PARA = 0.055 * G4cbrt(A*A) * (G4cbrt(A-Z) + G4cbrt(Z));
     87  G4double TEM = std::sqrt(EEXS / PARA);
     88  G4double TETA = 0.494 * G4cbrt(A) * TEM;
     89 
     90  TETA = TETA / std::sinh(TETA);
     91 
     92  if (A < 246) PARA += (nucleiLevelDensity(A) - PARA) * TETA;
     93 
     94  G4int A1 = A/2 + 1;
     95  G4int Z1;
     96  G4int A2 = A - A1;
     97
     98  G4double ALMA = -1000.0;
     99  G4double DM1 = bindingEnergy(A,Z);
     100  G4double EVV = EEXS - DM1;
     101  G4double DM2 = bindingEnergyAsymptotic(A, Z);
     102  G4double DTEM = (A < 220 ? 0.5 : 1.15);
     103 
     104  TEM += DTEM;
     105 
     106  static std::vector<G4double> AL1(2, -0.15);
     107  static std::vector<G4double> BET1(2, 0.05);
     108
     109  G4double R12 = G4cbrt(A1) + G4cbrt(A2);
     110 
     111  for (G4int i = 0; i < 50 && A1 > 30; i++) {
     112    A1--;
     113    A2 = A - A1;
     114    G4double X3 = 1.0 / G4cbrt(A1);
     115    G4double X4 = 1.0 / G4cbrt(A2);
     116    Z1 = G4lrint(getZopt(A1, A2, Z, X3, X4, R12) - 1.);
     117    std::vector<G4double> EDEF1(2);
     118    G4int Z2 = Z - Z1;
     119    G4double VPOT, VCOUL;
    119120   
    120       if(EZL > 0.0) { // generate fluctuations
    121         //  faster, using randomGauss
    122         G4double C1 = std::sqrt(getC2(A1, A2, X3, X4, R12) / TEM);
    123         G4double DZ = randomGauss(C1);
    124 
    125         DZ = DZ > 0.0 ? G4int(DZ + 0.5) : -G4int(std::fabs(DZ - 0.5));
    126         Z1 += DZ;
    127         Z2 -= DZ;
    128 
    129         G4double DEfin = randomGauss(TEM);     
    130         G4double EZ = (DMT1 + (DMT - DMT1) * TETA - VPOT + DEfin) / TEM;
    131 
    132         if (EZ >= ALMA) ALMA = EZ;
    133         G4double EK = VCOUL + DEfin + 0.5 * TEM;
    134         //      G4double EV = EVV + bindingEnergy(A1, Z1) + bindingEnergy(A2, Z2) - EK;
    135         G4double EV = EVV
    136                     + G4NucleiProperties::GetBindingEnergy(G4lrint(A1), G4lrint(Z1))
    137                     + G4NucleiProperties::GetBindingEnergy(G4lrint(A2), G4lrint(Z2))
    138                     - EK;
    139        
    140         if (EV > 0.0) fissionStore.addConfig(A1, Z1, EZ, EK, EV);
    141       };
    142     };
    143 
    144     G4int store_size = fissionStore.size();
    145 
    146     if (store_size > 0) {
    147 
    148       G4FissionConfiguration config =
    149         fissionStore.generateConfiguration(ALMA, inuclRndm());
    150 
    151       A1 = config.afirst;
    152       A2 = A - A1;
    153       Z1 = config.zfirst;
    154 
    155       G4double Z2 = Z - Z1;
    156       G4InuclNuclei nuclei1(A1, Z1);
    157       nuclei1.setModel(7); // sign in the modelId (=G4Fissioner)
    158       G4InuclNuclei nuclei2(A2, Z2);       
    159       nuclei2.setModel(7);
    160 
    161       G4double mass1 = nuclei1.getMass();
    162       G4double mass2 = nuclei2.getMass();
    163       G4double EK = config.ekin;
    164       G4double pmod = std::sqrt(0.001 * EK * mass1 * mass2 / mass_in);
    165 
    166       G4LorentzVector mom1 = generateWithRandomAngles(pmod, mass1);
    167       G4LorentzVector mom2; mom2.setVectM(-mom1.vect(), mass2);
    168 
    169       G4double e_out = mom1.e() + mom2.e();
    170       G4double EV = 1000.0 * (e_in - e_out) / A;
    171 
    172       if (EV > 0.0) {
    173         G4double EEXS1 = EV*A1;
    174         G4double EEXS2 = EV*A2;
    175         G4InuclNuclei nuclei1(mom1, A1, Z1);       
    176 
    177         nuclei1.setModel(7);
    178         nuclei1.setExitationEnergy(EEXS1);
    179         nuclei1.setEnergy();
    180         output.addTargetFragment(nuclei1);
    181 
    182         G4InuclNuclei nuclei2(mom2, A2, Z2);       
    183 
    184         nuclei2.setModel(7);
    185         nuclei2.setExitationEnergy(EEXS2);
    186         nuclei2.setEnergy();
    187         output.addTargetFragment(nuclei2);
    188 
    189         if (verboseLevel > 3) {
    190           nuclei1.printParticle();
    191           nuclei2.printParticle();
    192         }
    193       };
    194     };
    195 
    196   } else {
    197     G4cout << " Fissioner -> target is not nuclei " << G4endl;   
    198   };
    199 
    200   return;
     121    potentialMinimization(VPOT, EDEF1, VCOUL, A1, A2, Z1, Z2, AL1, BET1, R12);
     122   
     123    G4double DM3 = bindingEnergy(A1,Z1);
     124    G4double DM4 = bindingEnergyAsymptotic(A1, Z1);
     125    G4double DM5 = bindingEnergy(A2,Z2);
     126    G4double DM6 = bindingEnergyAsymptotic(A2, Z2);
     127    G4double DMT1 = DM4 + DM6 - DM2;
     128    G4double DMT = DM3 + DM5 - DM1;
     129    G4double EZL = EEXS + DMT - VPOT;
     130   
     131    if(EZL > 0.0) { // generate fluctuations
     132      //  faster, using randomGauss
     133      G4double C1 = std::sqrt(getC2(A1, A2, X3, X4, R12) / TEM);
     134      G4double DZ = randomGauss(C1);
     135     
     136      DZ = DZ > 0.0 ? DZ + 0.5 : -std::fabs(DZ - 0.5);
     137      Z1 += G4int(DZ);
     138      Z2 -= G4int(DZ);
     139     
     140      G4double DEfin = randomGauss(TEM);       
     141      G4double EZ = (DMT1 + (DMT - DMT1) * TETA - VPOT + DEfin) / TEM;
     142     
     143      if (EZ >= ALMA) ALMA = EZ;
     144      G4double EK = VCOUL + DEfin + 0.5 * TEM;
     145      G4double EV = EVV + bindingEnergy(A1,Z1) + bindingEnergy(A2,Z2) - EK;
     146     
     147      if (EV > 0.0) fissionStore.addConfig(A1, Z1, EZ, EK, EV);
     148    };
     149  };
     150 
     151  G4int store_size = fissionStore.size();
     152  if (store_size == 0) return;          // No fission products
     153
     154  G4FissionConfiguration config =
     155    fissionStore.generateConfiguration(ALMA, inuclRndm());
     156 
     157  A1 = G4int(config.afirst);
     158  A2 = A - A1;
     159  Z1 = G4int(config.zfirst);
     160 
     161  G4int Z2 = Z - Z1;
     162 
     163  G4double mass1 = G4InuclNuclei::getNucleiMass(A1,Z1);
     164  G4double mass2 = G4InuclNuclei::getNucleiMass(A2,Z2);
     165  G4double EK = config.ekin;
     166  G4double pmod = std::sqrt(0.001 * EK * mass1 * mass2 / mass_in);
     167 
     168  G4LorentzVector mom1 = generateWithRandomAngles(pmod, mass1);
     169  G4LorentzVector mom2; mom2.setVectM(-mom1.vect(), mass2);
     170 
     171  G4double e_out = mom1.e() + mom2.e();
     172  G4double EV = 1000.0 * (e_in - e_out) / A;
     173  if (EV <= 0.0) return;                // No fission energy
     174
     175  G4double EEXS1 = EV*A1;
     176  G4double EEXS2 = EV*A2;
     177
     178  G4InuclNuclei nuclei1(mom1, A1, Z1, EEXS1, 7);       
     179  G4InuclNuclei nuclei2(mom2, A2, Z2, EEXS2, 7);       
     180
     181  // Pass only last two nuclear fragments
     182  static std::vector<G4InuclNuclei> frags(2);           // Always the same size!
     183  frags[0] = nuclei1;
     184  frags[1] = nuclei2;
     185  validateOutput(0, target, frags);             // Check energy conservation
     186
     187  output.addOutgoingNuclei(frags);
    201188}
    202189
    203 G4double G4Fissioner::getC2(G4double A1,
    204                             G4double A2,
     190G4double G4Fissioner::getC2(G4int A1,
     191                            G4int A2,
    205192                            G4double X3,
    206193                            G4double X4,
     
    217204}
    218205
    219 G4double G4Fissioner::getZopt(G4double A1,
    220                               G4double A2,
    221                               G4double ZT,
     206G4double G4Fissioner::getZopt(G4int A1,
     207                              G4int A2,
     208                              G4int ZT,
    222209                              G4double X3,
    223210                              G4double X4,
     
    238225                                        std::vector<G4double> & ED,
    239226                                        G4double& VC,
    240                                         G4double AF,
    241                                         G4double AS,
    242                                         G4double ZF,
    243                                         G4double ZS,
     227                                        G4int AF,
     228                                        G4int AS,
     229                                        G4int ZF,
     230                                        G4int ZS,
    244231                                        std::vector<G4double>& AL1,
    245232                                        std::vector<G4double>& BET1,
     
    255242  const G4double DS1 = 0.3;
    256243  const G4double DS2 = 1.0 / DS1 / DS1;
    257   G4double A1[2];
    258   A1[0] = AF;
    259   A1[1] = AS;
    260   G4double Z1[2];
    261   Z1[0] = ZF;
    262   Z1[1] = ZS;
     244  G4int A1[2] = { AF, AS };
     245  G4int Z1[2] = { ZF, ZS };
    263246  G4double D = 1.01844 * ZF * ZS;
    264247  G4double D0 = 1.0e-3 * D;
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InteractionCase.cc

    r1337 r1340  
    2525//
    2626// $Id: G4InteractionCase.cc,v 1.2 2010/06/25 09:44:32 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100518  M. Kelsey -- Move code from Colliders' "bulletTargetSetter()"
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4IntraNucleiCascader.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4IntraNucleiCascader.cc,v 1.35.2.1 2010/06/25 09:44:34 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4IntraNucleiCascader.cc,v 1.68 2010/09/25 06:44:30 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3534// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3635//              simple data members
     36// 20100616  M. Kelsey -- Add reporting of final residual particle
     37// 20100617  M. Kelsey -- Remove "RUN" preprocessor flag and all "#else" code,
     38//              pass verbosity to collider.  Make G4NucleiModel a data member,
     39//              instead of creating and deleting on every cycle.
     40// 20100620  M. Kelsey -- Improved diagnostic messages.  Simplify kinematics
     41//              of recoil nucleus.
     42// 20100622  M. Kelsey -- Use local "bindingEnergy()" to call through.
     43// 20100623  M. Kelsey -- Undo G4NucleiModel change from 0617.  Does not work
     44//              properly across multiple interactions.
     45// 20100627  M. Kelsey -- Protect recoil nucleus energy from floating roundoff
     46//              by setting small +ve or -ve values to zero.
     47// 20100701  M. Kelsey -- Let excitation energy be handled by G4InuclNuclei,
     48//              allow for ground-state recoil (goodCase == true for Eex==0.)
     49// 20100702  M. Kelsey -- Negative energy recoil should be rejected
     50// 20100706  D. Wright -- Copy "abandoned" cparticles to output list, copy
     51//              mesonic "excitons" to output list; should be absorbed, fix up
     52//              diagnostic messages.
     53// 20100713  M. Kelsey -- Add more diagnostics for Dennis' changes.
     54// 20100714  M. Kelsey -- Switch to new G4CascadeColliderBase class, remove
     55//              sanity check on afin/zfin (not valid).
     56// 20100715  M. Kelsey -- Add diagnostic for ekin_in vs. actual ekin; reduce
     57//              KE across Coulomb barrier.  Rearrange end-of-loop if blocks,
     58//              add conservation check at end.
     59// 20100716  M. Kelsey -- Eliminate inter_case; use base-class functionality.
     60//              Add minimum-fragment requirement for recoil, in order to
     61//              allow for momentum balancing
     62// 20100720  M. Kelsey -- Make EPCollider pointer member
     63// 20100721  M. Kelsey -- Turn on conservation checks unconditionally (override
     64//              new G4CASCADE_CHECK_ECONS setting
     65// 20100722  M. Kelsey -- Move cascade output buffers to .hh file
     66// 20100728  M. Kelsey -- Make G4NucleiModel data member for persistence,
     67//              delete colliders in destructor
     68// 20100906  M. Kelsey -- Hide "non-physical fragment" behind verbose flag
     69// 20100907  M. Kelsey -- Add makeResidualFragment function to create object
     70// 20100909  M. Kelsey -- Remove all local "fragment" stuff, use RecoilMaker.
     71//              move goodCase() to RecoilMaker.
     72// 20100910  M. Kelsey -- Use RecoilMaker::makeRecoilFragment().
     73// 20100915  M. Kelsey -- Define functions to deal with trapped particles,
     74//              move the exciton container to a data member
     75// 20100916  M. Kelsey -- Put decay photons directly onto output list
     76// 20100921  M. Kelsey -- Migrate to RecoilMaker::makeRecoilNuclei().
     77// 20100924  M. Kelsey -- Minor shuffling of post-cascade recoil building.
     78//              Create G4Fragment for recoil and store in output.
    3779
    3880#include "G4IntraNucleiCascader.hh"
    39 #define RUN
    40 
    4181#include "G4CascadParticle.hh"
     82#include "G4CascadeRecoilMaker.hh"
     83#include "G4ElementaryParticleCollider.hh"
    4284#include "G4CollisionOutput.hh"
    43 #include "G4ElementaryParticleCollider.hh"
     85#include "G4DecayTable.hh"
     86#include "G4DecayProducts.hh"
    4487#include "G4HadTmpUtil.hh"
    4588#include "G4InuclElementaryParticle.hh"
    4689#include "G4InuclNuclei.hh"
    4790#include "G4InuclSpecialFunctions.hh"
     91#include "G4LorentzConvertor.hh"
    4892#include "G4NucleiModel.hh"
    49 #include "G4NucleiProperties.hh"
    5093#include "G4ParticleLargerEkin.hh"
    5194#include "Randomize.hh"
     
    58101
    59102G4IntraNucleiCascader::G4IntraNucleiCascader()
    60   : G4VCascadeCollider("G4IntraNucleiCascader"),
    61     theElementaryParticleCollider(new G4ElementaryParticleCollider) {}
     103  : G4CascadeColliderBase("G4IntraNucleiCascader"),
     104    model(new G4NucleiModel),
     105    theElementaryParticleCollider(new G4ElementaryParticleCollider),
     106    theRecoilMaker(new G4CascadeRecoilMaker) {}
    62107
    63108G4IntraNucleiCascader::~G4IntraNucleiCascader() {
     109  delete model;
    64110  delete theElementaryParticleCollider;
     111  delete theRecoilMaker;
    65112}
    66113
     
    68115void G4IntraNucleiCascader::collide(G4InuclParticle* bullet,
    69116                                    G4InuclParticle* target,
    70                                     G4CollisionOutput& output) {
    71 
    72   if (verboseLevel > 3) {
    73     G4cout << " >>> G4IntraNucleiCascader::collide inter_case " << inter_case
    74            << G4endl;
    75   }
     117                                    G4CollisionOutput& globalOutput) {
     118  if (verboseLevel) G4cout << " >>> G4IntraNucleiCascader::collide " << G4endl;
    76119
    77120  const G4int itry_max = 1000;
    78121  const G4int reflection_cut = 500;
    79   //  const G4double eexs_cut = 0.0001;
     122
     123  const G4double small_ekin = 0.001*MeV;        // Tolerance for round-off zero
     124  const G4double quasielast_cut = 1*MeV;        // To recover elastic scatters
     125
     126  // Configure processing modules
     127  model->setVerboseLevel(verboseLevel);
     128  theElementaryParticleCollider->setVerboseLevel(verboseLevel);
     129  theRecoilMaker->setVerboseLevel(verboseLevel);
     130  theRecoilMaker->setTolerance(small_ekin);
     131
     132  // Energy/momentum conservation usually requires a recoiling nuclear fragment
     133  // This cut will be increased on each "itry" if momentum could not balance.
     134  G4double minimum_recoil_A = 0.;               // Nuclear fragment required
    80135
    81136  if (verboseLevel > 3) {
     
    84139  }
    85140
    86 #ifdef RUN
    87141  G4InuclNuclei* tnuclei = dynamic_cast<G4InuclNuclei*>(target);
     142  if (!tnuclei) {
     143    if (verboseLevel)
     144      G4cerr << " Target is not a nucleus.  Abandoning." << G4endl;
     145    return;
     146  }
     147
     148  interCase.set(bullet,target);         // Classify collision type
     149
     150  model->generateModel(tnuclei);
     151
     152  G4double coulombBarrier = 0.00126*tnuclei->getZ()/
     153                                      (1.+G4cbrt(tnuclei->getA()));
     154
     155  G4LorentzVector momentum_in = bullet->getMomentum() + target->getMomentum();
     156
     157  if (verboseLevel > 3) {
     158    model->printModel();
     159    G4cout << " intitial momentum  E " << momentum_in.e() << " Px "
     160           << momentum_in.x() << " Py " << momentum_in.y() << " Pz "
     161           << momentum_in.z() << G4endl;
     162  }
     163
     164  // Bullet may be nucleus or simple particle
    88165  G4InuclNuclei* bnuclei = dynamic_cast<G4InuclNuclei*>(bullet);
    89166  G4InuclElementaryParticle* bparticle =
    90167                          dynamic_cast<G4InuclElementaryParticle*>(bullet);
    91   G4NucleiModel model(tnuclei);
    92   G4double coulombBarrier = 0.00126*tnuclei->getZ()/
    93                                       (1.+G4cbrt(tnuclei->getA()));
    94 
    95   G4LorentzVector momentum_in = bullet->getMomentum();
    96 
    97   momentum_in.setE(momentum_in.e()+tnuclei->getMass());
    98 
    99   G4double ekin_in;
    100 
    101   if (verboseLevel > 3) {
    102     model.printModel();
    103     G4cout << " intitial momentum  E " << momentum_in.e() << " Px "
    104            << momentum_in.x() << " Py " << momentum_in.y() << " Pz "
    105            << momentum_in.z() << G4endl;
    106   }
    107168
    108169  G4int itry = 0;
    109 
    110170  while (itry < itry_max) {
    111171    itry++;
    112     model.reset();
    113 
    114     std::vector<G4CascadParticle> cascad_particles;
    115     G4ExitonConfiguration theExitonConfiguration;
    116     std::vector<G4InuclElementaryParticle> output_particles;
    117     G4double afin = tnuclei->getA();
    118     G4double zfin = tnuclei->getZ();
    119    
    120     if (inter_case == 1) { // particle with nuclei
    121       ekin_in = bparticle->getKineticEnergy();
    122       zfin += bparticle->getCharge();
    123 
    124       if (bparticle->baryon()) afin += 1.0;
    125 
    126       cascad_particles.push_back(model.initializeCascad(bparticle));
    127 
    128     } else { // nuclei with nuclei
    129 
    130       ekin_in = bnuclei->getKineticEnergy();
    131 
    132       G4double ab = bnuclei->getA();
    133       G4double zb = bnuclei->getZ();
    134 
    135       afin += ab;
    136       zfin += zb;
     172    if (verboseLevel > 2) {
     173      G4cout << " itry " << itry << " inter_case " << interCase.code()
     174             << G4endl;
     175    }
     176
     177    model->reset();                     // Start new cascade process
     178    output.reset();
     179    cascad_particles.clear();
     180    output_particles.clear();
     181    theExitonConfiguration.clear();
     182
     183    if (interCase.hadNucleus()) {               // particle with nuclei
     184      if (verboseLevel > 3)
     185        G4cout << " bparticle charge " << bparticle->getCharge()
     186               << " baryon number " << bparticle->baryon() << G4endl;
     187
     188      cascad_particles.push_back(model->initializeCascad(bparticle));
     189    } else {                            // nuclei with nuclei
     190      G4int ab = bnuclei->getA();
     191      G4int zb = bnuclei->getZ();
    137192
    138193      G4NucleiModel::modelLists all_particles;    // Buffer to receive lists
    139       model.initializeCascad(bnuclei, tnuclei, all_particles);
     194      model->initializeCascad(bnuclei, tnuclei, all_particles);
    140195
    141196      cascad_particles = all_particles.first;
    142197
    143       for (G4int ip = 0; ip < G4int(all_particles.second.size()); ip++)
    144         output_particles.push_back(all_particles.second[ip]);
     198      output_particles.insert(output_particles.end(),
     199                              all_particles.second.begin(),
     200                              all_particles.second.end());
    145201
    146202      if (cascad_particles.size() == 0) { // compound nuclei
    147         G4int ia = G4int(ab + 0.5);
    148         G4int iz = G4int(zb + 0.5);
    149203        G4int i;
    150204
    151         for (i = 0; i < ia; i++) {
    152           G4int knd = i < iz ? 1 : 2;
     205        for (i = 0; i < ab; i++) {
     206          G4int knd = i < zb ? 1 : 2;
    153207          theExitonConfiguration.incrementQP(knd);
    154208        };
    155209
    156         G4int ihn = G4int(2.0 * (ab - zb) * inuclRndm() + 0.5);
    157         G4int ihz = G4int(2.0 * zb * inuclRndm() + 0.5);
     210        G4int ihn = G4int(2 * (ab-zb) * inuclRndm() + 0.5);
     211        G4int ihz = G4int(2 * zb * inuclRndm() + 0.5);
    158212
    159213        for (i = 0; i < ihn; i++) theExitonConfiguration.incrementHoles(2);
    160214        for (i = 0; i < ihz; i++) theExitonConfiguration.incrementHoles(1);
    161       };
    162     };
    163 
    164     std::vector<G4CascadParticle> new_cascad_particles;
     215      }
     216    }   // if (interCase ...
     217
     218    new_cascad_particles.clear();
    165219    G4int iloop = 0;
    166220
    167     while (!cascad_particles.empty() && !model.empty()) {
     221    while (!cascad_particles.empty() && !model->empty()) {
    168222      iloop++;
    169223
    170       if (verboseLevel > 3) {
    171         G4cout << " Number of cparticles " << cascad_particles.size() << G4endl;
     224      if (verboseLevel > 2) {
     225        G4cout << " Iteration " << iloop << ": Number of cparticles "
     226               << cascad_particles.size() << " last one: " << G4endl;
    172227        cascad_particles.back().print();
    173228      }
    174229
    175       new_cascad_particles = model.generateParticleFate(cascad_particles.back(),
     230      new_cascad_particles = model->generateParticleFate(cascad_particles.back(),
    176231                                                        theElementaryParticleCollider);
    177232      if (verboseLevel > 2) {
    178         G4cout << " ew particles " << new_cascad_particles.size() << G4endl;
    179       }
     233        G4cout << " After generate fate: New particles "
     234               << new_cascad_particles.size() << G4endl
     235               << " Discarding last cparticle from list " << G4endl;
     236      }
     237
     238      cascad_particles.pop_back();
    180239
    181240      // handle the result of a new step
    182241
    183242      if (new_cascad_particles.size() == 1) { // last particle goes without interaction
    184         cascad_particles.pop_back();
    185 
    186         if (model.stillInside(new_cascad_particles[0])) { // particle survives
    187 
    188           if (verboseLevel > 3) {
    189             G4cout << " still inside " << G4endl;
    190           }
    191 
    192           if (new_cascad_particles[0].getNumberOfReflections() < reflection_cut &&
    193              model.worthToPropagate(new_cascad_particles[0])) { // it's ok
    194 
    195             if (verboseLevel > 3) {
    196               G4cout << " survives " << G4endl;
    197             }
    198 
    199             cascad_particles.push_back(new_cascad_particles[0]);
    200 
    201           } else { // it becomes an exiton
    202 
    203             if (verboseLevel > 3) {
    204               G4cout << " becomes an exiton " << G4endl;
    205             }
    206 
    207             theExitonConfiguration.incrementQP(new_cascad_particles[0].getParticle().type());
    208           }; 
     243        const G4CascadParticle& currentCParticle = new_cascad_particles[0];
     244
     245        if (model->stillInside(currentCParticle)) {
     246          if (verboseLevel > 3)
     247            G4cout << " particle still inside nucleus " << G4endl;
     248
     249          if (currentCParticle.getNumberOfReflections() < reflection_cut &&
     250              model->worthToPropagate(currentCParticle)) {
     251            if (verboseLevel > 3) G4cout << " continue reflections " << G4endl;
     252            cascad_particles.push_back(currentCParticle);
     253          } else {
     254            processTrappedParticle(currentCParticle);
     255          }     // reflection or exciton
    209256
    210257        } else { // particle about to leave nucleus - check for Coulomb barrier
    211 
    212           if (verboseLevel > 3) {
    213             G4cout << " Goes out " << G4endl;
    214             new_cascad_particles[0].print();
    215           }
    216           G4InuclElementaryParticle currentParticle = new_cascad_particles[0].getParticle();
     258          if (verboseLevel > 3) G4cout << " possible escape " << G4endl;
     259
     260          const G4InuclElementaryParticle& currentParticle =
     261            currentCParticle.getParticle();
     262
    217263          G4double KE = currentParticle.getKineticEnergy();
    218264          G4double mass = currentParticle.getMass();
    219265          G4double Q = currentParticle.getCharge();
     266
     267          if (verboseLevel > 3)
     268            G4cout << " KE " << KE << " barrier " << Q*coulombBarrier << G4endl;
     269
    220270          if (KE < Q*coulombBarrier) {
    221271            // Calculate barrier penetration
    222272            G4double CBP = 0.0;
     273
    223274            // if (KE > 0.0001) CBP = std::exp(-0.00126*tnuclei->getZ()*0.25*
    224275            //   (1./KE - 1./coulombBarrier));
     
    228279
    229280            if (G4UniformRand() < CBP) {
     281              if (verboseLevel > 3) {
     282                G4cout << " tunneled " << G4endl;
     283                currentParticle.printParticle();
     284              }
     285              // Tunnelling through barrier leaves KE unchanged
    230286              output_particles.push_back(currentParticle);
    231287            } else {
    232               theExitonConfiguration.incrementQP(currentParticle.type());
     288              processTrappedParticle(currentCParticle);
    233289            }
    234290          } else {
     291            if (verboseLevel > 3) G4cout << " Goes out " << G4endl;
     292
    235293            output_particles.push_back(currentParticle);
     294
     295            /*****
     296            // Adjust kinetic energy by height of potential (+ve or -ve)
     297            G4double newKE = KE - Q*coulombBarrier;
     298            output_particles.back().setKineticEnergy(newKE);
     299            *****/
     300
     301            if (verboseLevel > 3) output_particles.back().printParticle();
    236302          }
    237303        }
    238 
    239304      } else { // interaction
    240 
    241         cascad_particles.pop_back();
    242 
    243         for (G4int i = 0; i < G4int(new_cascad_particles.size()); i++)
    244           cascad_particles.push_back(new_cascad_particles[i]);
    245 
    246         std::pair<G4int, G4int> holes = model.getTypesOfNucleonsInvolved();
     305        if (verboseLevel > 3)
     306          G4cout << " interacted, adding new to list " << G4endl;
     307
     308        cascad_particles.insert(cascad_particles.end(),
     309                                new_cascad_particles.begin(),
     310                                new_cascad_particles.end());
     311
     312        std::pair<G4int, G4int> holes = model->getTypesOfNucleonsInvolved();
     313        if (verboseLevel > 3)
     314          G4cout << " adding new exciton holes " << holes.first << ","
     315                 << holes.second << G4endl;
    247316
    248317        theExitonConfiguration.incrementHoles(holes.first);
    249318
    250         if (holes.second > 0) theExitonConfiguration.incrementHoles(holes.second);
    251 
    252       };
    253     };
    254 
     319        if (holes.second > 0)
     320          theExitonConfiguration.incrementHoles(holes.second);
     321      }         // if (new_cascad_particles ...
     322
     323      // Evaluate nuclear residue
     324      theRecoilMaker->collide(bullet,target,output_particles,cascad_particles);
     325
     326      G4double aresid = theRecoilMaker->getRecoilA();
     327      if (verboseLevel > 2) {
     328        G4cout << " cparticles remaining " << cascad_particles.size()
     329               << " nucleus (model) has "
     330               << model->getNumberOfNeutrons() << " n, "
     331               << model->getNumberOfProtons() << " p "
     332               << " residual fragment A " << aresid << G4endl;
     333      }
     334
     335      if (aresid <= minimum_recoil_A) break;    // Must have minimum fragment
     336    }           // while cascade-list and model
     337
     338    // Add left-over cascade particles to output
     339    for (G4int i = 0; i < G4int(cascad_particles.size()); i++)
     340      output_particles.push_back(cascad_particles[i].getParticle());
     341 
    255342    // Cascade is finished. Check if it's OK.
    256 
    257343    if (verboseLevel > 3) {
    258344      G4cout << " Cascade finished  " << G4endl
    259345             << " output_particles  " << output_particles.size() <<  G4endl;
    260     }
    261 
    262     G4LorentzVector momentum_out;
    263     particleIterator ipart;
    264 
    265     for (ipart = output_particles.begin(); ipart != output_particles.end(); ipart++) {
    266       momentum_out += ipart->getMomentum();
    267 
    268       zfin -= ipart->getCharge();
    269       if (ipart->baryon()) afin -= 1.0;
    270     };
    271 
     346
     347      particleIterator ipart = output_particles.begin();
     348      for (; ipart != output_particles.end(); ipart++) {
     349        ipart->printParticle();
     350        G4cout << "  charge " << ipart->getCharge() << " baryon number "
     351               << ipart->baryon() << G4endl;
     352      }
     353    }
     354
     355    // Use last created recoil fragment instead of re-constructing
     356    G4int afin = theRecoilMaker->getRecoilA();
     357    G4int zfin = theRecoilMaker->getRecoilZ();
     358
     359    // Sanity check before proceeding
     360    if (!theRecoilMaker->goodFragment() && !theRecoilMaker->wholeEvent()) {
     361      if (verboseLevel > 1)
     362        G4cerr << " Recoil nucleus is not physical: A=" << afin << " Z="
     363               << zfin << G4endl;
     364      continue;                         // Discard event and try again
     365    }
     366
     367    const G4LorentzVector& presid = theRecoilMaker->getRecoilMomentum();
     368
     369    if (verboseLevel > 1) {
     370      G4cout << "  afin " << afin << " zfin " << zfin <<  G4endl;
     371    }
     372
     373    if (afin == 0) break;               // Whole event fragmented, exit
     374
     375    if (afin == 1) {                    // Add bare nucleon to particle list
     376      G4int last_type = (zfin==1) ? 1 : 2;      // proton=1, neutron=2
     377
     378      G4double mass = G4InuclElementaryParticle::getParticleMass(last_type);
     379      G4double mres = presid.m();
     380
     381      // Check for sensible kinematics
     382      if (mres-mass < -small_ekin) {            // Insufficient recoil energy
     383        if (verboseLevel > 2) G4cerr << " unphysical recoil nucleon" << G4endl;
     384        continue;
     385      }
     386
     387      if (mres-mass > small_ekin) {             // Too much extra energy
     388        if (verboseLevel > 2)
     389          G4cerr << " extra energy with recoil nucleon" << G4endl;
     390
     391        // FIXME:  For now, we add the nucleon as unbalanced, and let
     392        //         "SetOnShell" fudge things.  This should be abandoned.
     393      }
     394
     395      G4InuclElementaryParticle last_particle(presid, last_type, 4);
     396
     397      if (verboseLevel > 3) {
     398        G4cout << " adding recoiling nucleon to output list" << G4endl;
     399        last_particle.printParticle();
     400      }
     401
     402      output_particles.push_back(last_particle);
     403    }
     404
     405    // Process recoil fragment for consistency, exit or reject
     406    if (output_particles.size() == 1) {
     407      G4double Eex = theRecoilMaker->getRecoilExcitation();
     408      if (std::abs(Eex) < quasielast_cut) {
     409        if (verboseLevel > 3) {
     410          G4cout << " quasi-elastic scatter with " << Eex << " MeV recoil"
     411                 << G4endl;
     412        }
     413       
     414        theRecoilMaker->setRecoilExcitation(Eex=0.);
     415        if (verboseLevel > 3) {
     416          G4cout << " Eex reset to " << theRecoilMaker->getRecoilExcitation()
     417                 << G4endl;
     418        }
     419      }
     420    }
     421   
     422    if (theRecoilMaker->goodNucleus()) {
     423      theRecoilMaker->addExcitonConfiguration(theExitonConfiguration);
     424   
     425      G4Fragment* recoilFrag = theRecoilMaker->makeRecoilFragment();
     426      if (!recoilFrag) {
     427        G4cerr << "Got null pointer for recoil fragment!" << G4endl;
     428        continue;
     429      }
     430      output.addRecoilFragment(*recoilFrag);
     431
     432      // TEMPORARY:  Add both frag and nuclei, for code validation
     433      G4InuclNuclei* recoilNucl = theRecoilMaker->makeRecoilNuclei(4);
     434      if (!recoilFrag) {
     435        G4cerr << "Got null pointer for recoil nucleus!" << G4endl;
     436        continue;
     437      }
     438      output.addOutgoingNucleus(*recoilNucl);
     439     
     440      if (verboseLevel > 2)
     441        G4cout << " adding recoil nucleus/fragment to output list" << G4endl;
     442    }
     443
     444    // Put final-state particle in "leading order" for return
     445    std::sort(output_particles.begin(), output_particles.end(), G4ParticleLargerEkin());
     446    output.addOutgoingParticles(output_particles);
     447
     448    // Adjust final state without fragment to balance momentum and energy
     449    if (afin <= 1) {
     450      output.setVerboseLevel(verboseLevel);
     451      output.setOnShell(bullet, target);
     452      output.setVerboseLevel(0);
     453
     454      if (output.acceptable()) break;
     455    } else if (theRecoilMaker->goodNucleus()) break;
     456
     457    // Cascade not physically reasonable
     458    if (afin <= minimum_recoil_A && minimum_recoil_A < tnuclei->getA()) {
     459      ++minimum_recoil_A;
     460      if (verboseLevel > 3) {
     461        G4cout << " minimum recoil fragment increased to A " << minimum_recoil_A
     462               << G4endl;
     463      }
     464    }
     465  }     // while (itry < itry_max)
     466
     467  // Cascade completed, for good or ill
     468  if (itry == itry_max) {
    272469    if (verboseLevel > 3) {
    273       G4cout << "  afin " << afin << " zfin " << zfin <<  G4endl;
    274     }
    275 
    276     if (afin > 1.0) {
    277       G4InuclNuclei outgoing_nuclei(afin, zfin);
    278       G4double mass = outgoing_nuclei.getMass();
    279       momentum_out.setE(momentum_out.e()+mass);
    280 
    281       momentum_out = momentum_in - momentum_out;
    282 
    283       if (verboseLevel > 3) {
    284         G4cout << "  Eex + Ekin " << momentum_out.e()  <<  G4endl;
    285       }
    286 
    287       if (momentum_out.e() > 0.0) { // Eex + Ekin > 0.0
    288         G4double pnuc = momentum_out.vect().mag2();
    289         G4double ekin = std::sqrt(mass * mass + pnuc) - mass;
    290         G4double Eex = 1000.0 * (momentum_out.e() - ekin);
    291 
    292         if (verboseLevel > 3) {
    293           G4cout << "  Eex  " << Eex  <<  G4endl;
    294         }
    295 
    296         if (goodCase(afin, zfin, Eex, ekin_in)) { // ok, exitation energy > cut
    297           std::sort(output_particles.begin(), output_particles.end(), G4ParticleLargerEkin());
    298           output.addOutgoingParticles(output_particles);
    299           outgoing_nuclei.setMomentum(momentum_out);
    300           outgoing_nuclei.setExitationEnergy(Eex);
    301           outgoing_nuclei.setExitonConfiguration(theExitonConfiguration);                                         
    302           output.addTargetFragment(outgoing_nuclei);
    303 
    304           return;
    305         };
    306       };
    307 
    308     } else { // special case, when one has no nuclei after the cascad
    309 
    310       if (afin == 1.0) { // recoiling nucleon
    311 
    312         momentum_out = momentum_in - momentum_out;
    313 
    314         G4InuclElementaryParticle  last_particle;
    315 
    316         if (zfin == 1.0) { // recoiling proton
    317           last_particle.setType(1);
    318 
    319         } else { // neutron
    320           last_particle.setType(2);
    321         };
    322 
    323         last_particle.setMomentum(momentum_out);
    324         output_particles.push_back(last_particle);
    325       };
    326 
    327       std::sort(output_particles.begin(), output_particles.end(), G4ParticleLargerEkin());
    328       output.addOutgoingParticles(output_particles);
    329 
    330       return;
    331     };
    332   };
    333 
    334 #else
    335 
    336   // special branch to avoid the cascad generation but to get the input for evaporation etc
    337 
    338   G4LorentzVector momentum_out;
    339   G4InuclNuclei outgoing_nuclei(169, 69);
    340 
    341   outgoing_nuclei.setMomentum(momentum_out);
    342   outgoing_nuclei.setExitationEnergy(150.0);
    343 
    344   G4ExitonConfiguration theExitonConfiguration(3.0, 3.0, 5.0, 6.0);
    345 
    346   outgoing_nuclei.setExitonConfiguration(theExitonConfiguration);                                 
    347   output.addTargetFragment(outgoing_nuclei);
    348 
    349   return;
    350 
    351   /*
    352     G4InuclElementaryParticle* bparticle = dynamic_cast<G4InuclElementaryParticle*>
    353     (bullet);
    354     G4InuclNuclei* tnuclei = dynamic_cast<G4InuclNuclei*>(target);
    355     output.addOutgoingParticle(*bparticle);
    356     output.addTargetFragment(*tnuclei);
    357     return;
    358   */
    359 
    360 #endif
    361 
    362   if (verboseLevel > 3) {
    363     G4cout << " IntraNucleiCascader-> no inelastic interaction after " << itry_max << " attempts "
    364            << G4endl;
    365   }
    366 
    367   output.trivialise(bullet, target);
    368 
     470      G4cout << " IntraNucleiCascader-> no inelastic interaction after "
     471             << itry_max << " attempts " << G4endl;
     472    }
     473
     474    output.trivialise(bullet, target);
     475  } else if (verboseLevel) {
     476    G4cout << " IntraNucleiCascader output after trials " << itry << G4endl;
     477  }
     478
     479  // Copy final generated cascade to output buffer for return
     480  globalOutput.add(output);
    369481  return;
    370482}
    371483
    372 G4bool G4IntraNucleiCascader::goodCase(G4double a,
    373                                        G4double z,
    374                                        G4double eexs,
    375                                        G4double ein) const {
    376 
     484
     485// Convert particles which cannot escape into excitons (or eject/decay them)
     486
     487void G4IntraNucleiCascader::
     488processTrappedParticle(const G4CascadParticle& trapped) {
     489  const G4InuclElementaryParticle& trappedP = trapped.getParticle();
     490
     491  G4int xtype = trappedP.type();
     492  if (verboseLevel > 3) G4cout << " exciton of type " << xtype << G4endl;
     493 
     494  if (trappedP.nucleon()) {     // normal exciton (proton or neutron)
     495    theExitonConfiguration.incrementQP(xtype);
     496    return;
     497  }
     498
     499  if (trappedP.hyperon()) {     // Not nucleon, so must be hyperon
     500    decayTrappedParticle(trapped);
     501    return;
     502  }
     503
     504  // non-standard exciton; release it
     505  // FIXME: this is a meson, so need to absorb it
    377506  if (verboseLevel > 3) {
    378     G4cout << " >>> G4IntraNucleiCascader::goodCase" << G4endl;
    379   }
    380 
    381   const G4double eexs_cut = 0.0001;
    382   const G4double reason_cut = 7.0;
    383   const G4double ediv_cut = 5.0;
    384 
    385   G4bool good = false;
    386 
    387   if (eexs > eexs_cut) {
    388     G4double eexs_max0z = 1000.0 * ein / ediv_cut;
    389     //    G4double dm = bindingEnergy(a, z);
    390     G4double dm = G4NucleiProperties::GetBindingEnergy(G4lrint(a), G4lrint(z));
    391     G4double eexs_max = eexs_max0z > reason_cut*dm ? eexs_max0z : reason_cut * dm;
    392 
    393     if(eexs < eexs_max) good = true;
    394 
    395     if (verboseLevel > 3) {
    396       G4cout << " eexs " << eexs << " max " << eexs_max << " dm " << dm << G4endl;
    397     }
    398 
    399   };
    400 
    401   return good;
     507    G4cout << " non-standard should be absorbed, now released" << G4endl;
     508    trapped.print();
     509  }
     510 
     511  output_particles.push_back(trappedP);
    402512}
     513
     514
     515// Decay unstable trapped particles, and add secondaries to processing list
     516
     517void G4IntraNucleiCascader::
     518decayTrappedParticle(const G4CascadParticle& trapped) {
     519  if (verboseLevel > 3)
     520    G4cout << " unstable must be decayed in flight" << G4endl;
     521
     522  const G4InuclElementaryParticle& trappedP = trapped.getParticle();
     523
     524  G4DecayTable* unstable = trappedP.getDefinition()->GetDecayTable();
     525  if (!unstable) {                      // No decay table; cannot decay!
     526    if (verboseLevel > 3)
     527      G4cerr << " no decay table!  Releasing trapped particle" << G4endl;
     528
     529    output_particles.push_back(trappedP);
     530    return;
     531  }
     532
     533  // Get secondaries from decay in particle's rest frame
     534  G4DecayProducts* daughters = unstable->SelectADecayChannel()->DecayIt();
     535  if (!daughters) {                     // No final state; cannot decay!
     536    if (verboseLevel > 3)
     537      G4cerr << " no daughters from trapped particle decay" << G4endl;
     538
     539    output_particles.push_back(trappedP);
     540    return;
     541  }
     542
     543  if (verboseLevel > 3) daughters->DumpInfo();
     544
     545  // Convert secondaries to lab frame
     546  G4double decayEnergy = trappedP.getEnergy();
     547  G4ThreeVector decayDir = trappedP.getMomentum().vect().unit();
     548  daughters->Boost(decayEnergy, decayDir);
     549
     550  // Put all the secondaries onto the list for propagation
     551  const G4ThreeVector& decayPos = trapped.getPosition();
     552  G4int zone = trapped.getCurrentZone();
     553  G4int gen = trapped.getGeneration()+1;
     554
     555  for (G4int i=0; i<daughters->entries(); i++) {
     556    G4DynamicParticle* idaug = (*daughters)[i];
     557
     558    G4InuclElementaryParticle idaugEP(*idaug, 4);
     559
     560    // Only hadronic secondaries can be propagated; photons escape
     561    if (idaugEP.isPhoton()) output_particles.push_back(idaugEP);
     562    else {
     563      G4CascadParticle idaugCP(idaugEP, decayPos, zone, 0., gen);
     564      cascad_particles.push_back(idaugCP);
     565    }
     566  }
     567}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclCollider.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclCollider.cc,v 1.30.2.1 2010/06/25 09:44:36 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclCollider.cc,v 1.51 2010/10/19 19:48:39 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3434// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
    3535//              simple data members, consolidate code
     36// 20100620  M. Kelsey -- Reorganize top level if-blocks to reduce nesting,
     37//              use new four-vector conservation check.
     38// 20100701  M. Kelsey -- Bug fix energy-conservation after equilibrium evap,
     39//              pass verbosity through to G4CollisionOutput
     40// 20100714  M. Kelsey -- Move conservation checking to base class, report
     41//              number of iterations at end
     42// 20100715  M. Kelsey -- Remove all the "Before xxx" and "After xxx"
     43//              conservation checks, as the colliders now all do so.  Move
     44//              local buffers outside while() loop, use new "combined add()"
     45//              interface for copying local buffers to global.
     46// 20100716  M. Kelsey -- Drop G4IntraNucleiCascader::setInteractionCase()
     47// 20100720  M. Kelsey -- Make all the collders pointer members (to reducde
     48//              external compile dependences).
     49// 20100915  M. Kelsey -- Move post-cascade colliders to G4CascadeDeexcitation,
     50//              simplify operational code somewhat
     51// 20100922  M. Kelsey -- Add functions to select de-excitation method;
     52//              default is G4CascadeDeexcitation (i.e., built-in modules)
     53// 20100924  M. Kelsey -- Migrate to integer A and Z
     54// 20101019  M. Kelsey -- CoVerity report: check dynamic_cast<> for null
    3655
    3756#include "G4InuclCollider.hh"
    38 #include "G4BigBanger.hh"
     57#include "G4CascadeDeexcitation.hh"
     58#include "G4PreCompoundDeexcitation.hh"
    3959#include "G4CollisionOutput.hh"
    4060#include "G4ElementaryParticleCollider.hh"
    41 #include "G4EquilibriumEvaporator.hh"
    4261#include "G4IntraNucleiCascader.hh"
    4362#include "G4InuclElementaryParticle.hh"
     63#include "G4InuclNuclei.hh"
    4464#include "G4LorentzConvertor.hh"
    45 #include "G4NonEquilibriumEvaporator.hh"
    4665
    4766
    4867G4InuclCollider::G4InuclCollider()
    49   : G4VCascadeCollider("G4InuclCollider"),
     68  : G4CascadeColliderBase("G4InuclCollider"),
    5069    theElementaryParticleCollider(new G4ElementaryParticleCollider),
    5170    theIntraNucleiCascader(new G4IntraNucleiCascader),
    52     theNonEquilibriumEvaporator(new G4NonEquilibriumEvaporator),
    53     theEquilibriumEvaporator(new G4EquilibriumEvaporator),
    54     theBigBanger(new G4BigBanger) {}
     71    theDeexcitation(new G4CascadeDeexcitation) {}
    5572
    5673G4InuclCollider::~G4InuclCollider() {
    5774  delete theElementaryParticleCollider;
    5875  delete theIntraNucleiCascader;
    59   delete theNonEquilibriumEvaporator;
    60   delete theEquilibriumEvaporator;
    61   delete theBigBanger;
    62 }
    63 
     76  delete theDeexcitation;
     77}
     78
     79
     80// Select post-cascade processing (default will be CascadeDeexcitation)
     81
     82void G4InuclCollider::useCascadeDeexcitation() {
     83  delete theDeexcitation;
     84  theDeexcitation = new G4CascadeDeexcitation;
     85}
     86
     87void G4InuclCollider::usePreCompoundDeexcitation() {
     88  delete theDeexcitation;
     89  theDeexcitation = new G4PreCompoundDeexcitation;
     90}
     91
     92
     93// Main action
    6494
    6595void G4InuclCollider::collide(G4InuclParticle* bullet, G4InuclParticle* target,
    6696                              G4CollisionOutput& globalOutput) {
     97  if (verboseLevel) G4cout << " >>> G4InuclCollider::collide" << G4endl;
     98
     99  // Initialize colliders verbosity
     100  theElementaryParticleCollider->setVerboseLevel(verboseLevel);
     101  theIntraNucleiCascader->setVerboseLevel(verboseLevel);
     102  theDeexcitation->setVerboseLevel(verboseLevel);
     103
     104  output.setVerboseLevel(verboseLevel);
     105  DEXoutput.setVerboseLevel(verboseLevel);
     106
     107  const G4int itry_max = 1000;
     108
     109  // Particle-on-particle collision; no nucleus involved
     110  if (useEPCollider(bullet,target)) {
     111    if (verboseLevel > 2)
     112      G4cout << " InuclCollider -> particle on particle collision" << G4endl;
     113 
     114    theElementaryParticleCollider->collide(bullet, target, globalOutput);
     115    return;
     116  }
     117 
     118  interCase.set(bullet,target);         // Classify collision type
     119  if (verboseLevel > 2) {
     120    G4cout << " InuclCollider -> inter case " << interCase.code() << G4endl;
     121  }
     122
     123  if (!interCase.valid()) {
     124    if (verboseLevel > 1)
     125      G4cerr << " InuclCollider -> no collision possible " << G4endl;
     126
     127    globalOutput.trivialise(bullet, target);
     128    return;
     129  }
     130
     131  // Target must be a nucleus
     132  G4InuclNuclei* ntarget = dynamic_cast<G4InuclNuclei*>(interCase.getTarget());
     133  if (!ntarget) {
     134    G4cerr << " InuclCollider -> ERROR target is not a nucleus " << G4endl;
     135
     136    globalOutput.trivialise(bullet, target);
     137    return;
     138  }
     139
     140  G4int btype = 0;
     141  G4int ab = 0;
     142  G4int zb = 0;
     143 
     144  if (interCase.hadNucleus()) {         // particle with nuclei
     145    G4InuclElementaryParticle* pbullet =
     146      dynamic_cast<G4InuclElementaryParticle*>(interCase.getBullet());
     147    if (!pbullet) {
     148      G4cerr << " InuclCollider -> ERROR bullet is not a hadron " << G4endl;
     149      globalOutput.trivialise(bullet, target);
     150      return;
     151    } else if (pbullet->isPhoton()) {
     152      G4cerr << " InuclCollider -> can not collide with photon " << G4endl;
     153      globalOutput.trivialise(bullet, target);
     154      return;
     155    } else {
     156      btype = pbullet->type();
     157    }
     158  } else {                              // nuclei with nuclei
     159    G4InuclNuclei* nbullet =
     160      dynamic_cast<G4InuclNuclei*>(interCase.getBullet());
     161    if (!nbullet) {
     162      G4cerr << " InuclCollider -> ERROR bullet is not a nucleus " << G4endl;
     163      globalOutput.trivialise(bullet, target);
     164      return;
     165    }
     166   
     167    ab = nbullet->getA();
     168    zb = nbullet->getZ();
     169  }
     170
     171  G4LorentzConvertor convertToTargetRestFrame(bullet, ntarget);
     172  G4double ekin = convertToTargetRestFrame.getKinEnergyInTheTRS();
     173 
     174  if (verboseLevel > 3) G4cout << " ekin in trs " << ekin << G4endl;
     175
     176  if (!inelasticInteractionPossible(bullet, target, ekin)) {
     177    if (verboseLevel > 3)
     178      G4cout << " InuclCollider -> inelastic interaction is impossible\n"
     179             << " due to the coulomb barirer " << G4endl;
     180
     181    globalOutput.trivialise(bullet, target);
     182    return;
     183  }
     184
     185  // Generate interaction secondaries in rest frame of target nucleus
     186  convertToTargetRestFrame.toTheTargetRestFrame();
    67187  if (verboseLevel > 3) {
    68     G4cout << " >>> G4InuclCollider::collide" << G4endl;
    69   }
    70 
    71   const G4int itry_max = 1000;
    72                      
    73   if (useEPCollider(bullet,target)) {
    74     if (verboseLevel > 2) {
    75       bullet->printParticle();
    76       target->printParticle();
     188    G4cout << " degenerated? " << convertToTargetRestFrame.trivial()
     189           << G4endl;
     190  }
     191 
     192  G4LorentzVector bmom;                 // Bullet is along local Z
     193  bmom.setZ(convertToTargetRestFrame.getTRSMomentum());
     194
     195  // Need to make copy of bullet with momentum realigned
     196  G4InuclParticle* zbullet = 0;
     197  if (interCase.hadNucleus())
     198    zbullet = new G4InuclElementaryParticle(bmom, btype);
     199  else
     200    zbullet = new G4InuclNuclei(bmom, ab, zb);
     201
     202  G4int itry = 0;
     203  while (itry < itry_max) {
     204    itry++;
     205    if (verboseLevel > 2)
     206      G4cout << " IntraNucleiCascader itry " << itry << G4endl;
     207
     208    globalOutput.reset();               // Clear buffers for this attempt
     209    output.reset();     
     210    DEXoutput.reset();
     211
     212    theIntraNucleiCascader->collide(zbullet, target, output);
     213   
     214    if (verboseLevel > 1) G4cout << " After Cascade " << G4endl;
     215
     216    // FIXME:  The code below still does too much copying!  Would rather
     217    //         remove initial fragment from list (or get it a different way)
     218    DEXoutput.addOutgoingParticles(output.getOutgoingParticles());
     219   
     220    if (output.numberOfOutgoingNuclei() == 1) { // Residual fragment
     221      // FIXME:  Making a copy here because of constness issues
     222      G4InuclNuclei recoil_nucleus = output.getOutgoingNuclei()[0];
     223      theDeexcitation->collide(0, &recoil_nucleus, DEXoutput);
    77224    }
    78225
    79     theElementaryParticleCollider->collide(bullet, target, globalOutput);
    80   } else { // needs to call all machinery       
    81     G4LorentzConvertor convertToTargetRestFrame;
    82 
    83     interCase.set(bullet,target);
    84     if (interCase.valid()) { // ok
    85       G4InuclNuclei* ntarget =
    86         dynamic_cast<G4InuclNuclei*>(interCase.getTarget());
    87 
    88       convertToTargetRestFrame.setTarget(ntarget);
    89       G4int btype = 0;
    90       G4double ab = 0.0;
    91       G4double zb = 0.0;
    92       G4double at = ntarget->getA();
    93       G4double zt = ntarget->getZ();
    94        
    95       if (interCase.hadNucleus()) { // particle with nuclei
    96         G4InuclElementaryParticle* pbullet =
    97           dynamic_cast<G4InuclElementaryParticle*>(interCase.getBullet());
    98          
    99         if (pbullet->isPhoton()) {
    100           G4cerr << " InuclCollider -> can not collide with photon " << G4endl;
    101 
    102           globalOutput.trivialise(bullet, target);
    103           return;
    104         } else {
    105           convertToTargetRestFrame.setBullet(pbullet);   
    106           btype = pbullet->type();
    107         };
    108 
    109       } else { // nuclei with nuclei
    110         G4InuclNuclei* nbullet =
    111           dynamic_cast<G4InuclNuclei*>(interCase.getBullet());
    112 
    113         convertToTargetRestFrame.setBullet(nbullet);   
    114         ab = nbullet->getA();
    115         zb = nbullet->getZ();
    116       };
    117        
    118       G4double ekin = convertToTargetRestFrame.getKinEnergyInTheTRS();
    119 
    120       if (verboseLevel > 3) {
    121         G4cout << " ekin in trs " << ekin << G4endl;
    122       }
    123 
    124       if (inelasticInteractionPossible(bullet, target, ekin)) {
    125         convertToTargetRestFrame.toTheTargetRestFrame();
    126 
    127         if (verboseLevel > 3) {
    128           G4cout << " degenerated? " << convertToTargetRestFrame.trivial() << G4endl;
    129         }
    130 
    131         G4LorentzVector bmom;
    132         bmom.setZ(convertToTargetRestFrame.getTRSMomentum());
    133 
    134         G4InuclNuclei ntarget(at, zt);          // Default is at rest
    135 
    136         theIntraNucleiCascader->setInteractionCase(interCase.code());
    137          
    138         G4bool bad = true;
    139         G4int itry = 0;
    140          
    141         G4CollisionOutput TRFoutput;
    142         G4CollisionOutput output;
    143         while (bad && itry < itry_max) {
    144           itry++;
    145 
    146           output.reset();       // Clear buffers for this attempt
    147           TRFoutput.reset();
    148 
    149           if (interCase.hadNucleus()) {
    150             G4InuclElementaryParticle pbullet(bmom, btype);
    151 
    152             theIntraNucleiCascader->collide(&pbullet, &ntarget, output);
    153           } else {
    154             G4InuclNuclei nbullet(bmom, ab, zb);
    155             theIntraNucleiCascader->collide(&nbullet, &ntarget, output);
    156           };   
    157 
    158           if (verboseLevel > 3) {
    159             G4cout << " After Cascade " << G4endl;
    160             output.printCollisionOutput();
    161           }
    162          
    163           // the rest, if any
    164           // FIXME:  The code below still does too much copying!
    165           TRFoutput.addOutgoingParticles(output.getOutgoingParticles());
    166 
    167           if (output.numberOfNucleiFragments() == 1) { // there is smth. after
    168             G4InuclNuclei cascad_rec_nuclei = output.getNucleiFragments()[0];
    169             if (explosion(&cascad_rec_nuclei)) {
    170               if (verboseLevel > 3) {
    171                 G4cout << " big bang after cascade " << G4endl;
    172               };
    173 
    174               theBigBanger->collide(0,&cascad_rec_nuclei, TRFoutput);
    175             } else {
    176               output.reset();
    177               theNonEquilibriumEvaporator->collide(0, &cascad_rec_nuclei, output);
    178 
    179               if (verboseLevel > 3) {
    180                 G4cout << " After NonEquilibriumEvaporator " << G4endl;
    181                 output.printCollisionOutput();
    182               };
    183 
    184               TRFoutput.addOutgoingParticles(output.getOutgoingParticles());
    185               G4InuclNuclei exiton_rec_nuclei = output.getNucleiFragments()[0];
    186 
    187               output.reset();
    188               theEquilibriumEvaporator->collide(0, &exiton_rec_nuclei, output);
    189 
    190               if (verboseLevel > 3) {
    191                 G4cout << " After EquilibriumEvaporator " << G4endl;
    192                 output.printCollisionOutput();
    193               };
    194 
    195               TRFoutput.addOutgoingParticles(output.getOutgoingParticles()); 
    196               TRFoutput.addTargetFragments(output.getNucleiFragments());
    197             };
    198           };
    199          
    200           // convert to the LAB
    201           TRFoutput.boostToLabFrame(convertToTargetRestFrame);
    202 
    203           globalOutput.addOutgoingParticles(TRFoutput.getOutgoingParticles());
    204           globalOutput.addTargetFragments(TRFoutput.getNucleiFragments());
    205           globalOutput.setOnShell(bullet, target);
    206           if (globalOutput.acceptable()) return;
    207 
    208           globalOutput.reset();         // Clear and try again
    209         };
    210 
    211         if (verboseLevel > 3) {
    212           G4cout << " InuclCollider -> can not generate acceptable inter. after "
    213                  << itry_max << " attempts " << G4endl;
    214         }
    215       } else {
    216         if (verboseLevel > 3) {
    217           G4cout << " InuclCollider -> inelastic interaction is impossible " << G4endl
    218                  << " due to the coulomb barirer " << G4endl;
    219         }
    220       }
    221 
    222       globalOutput.trivialise(bullet, target);
    223       return;
    224     } else {
    225       if (verboseLevel > 3) {
    226         G4cout << " InuclCollider -> inter case " << interCase.code() << G4endl;
    227       };
    228     };       
    229   };
    230 
     226    if (verboseLevel > 2)
     227      G4cout << " itry " << itry << " finished, moving to lab frame" << G4endl;
     228
     229    // convert to the LAB frame and add to final result
     230    DEXoutput.boostToLabFrame(convertToTargetRestFrame);
     231    globalOutput.add(DEXoutput);
     232
     233    // Adjust final state particles to balance momentum and energy
     234    // FIXME:  This should no longer be necessary!
     235    globalOutput.setOnShell(bullet, target);
     236    if (globalOutput.acceptable()) {
     237      if (verboseLevel)
     238        G4cout << " InuclCollider output after trials " << itry << G4endl;
     239      return;
     240    }
     241  }     // while (itry < itry_max)
     242 
     243  if (verboseLevel) {
     244    G4cout << " InuclCollider -> can not generate acceptable inter. after "
     245           << itry_max << " attempts " << G4endl;
     246  }
     247 
     248  globalOutput.trivialise(bullet, target);
    231249  return;
    232250}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclElementaryParticle.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclElementaryParticle.cc,v 1.7 2010/06/25 09:44:38 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclElementaryParticle.cc,v 1.10 2010/09/23 05:33:56 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100428  M. Kelsey -- Use G4InuclParticleNames enums instead of numbers,
    3030//              add Omega and antinucleons.
    3131// 20100429  M. Kelsey -- Change "case gamma:" to "case photon:"
     32// 20100923  M. Kelsey -- Drop "uups" message when converting G4PartDef to code
    3233
    3334#include "G4InuclElementaryParticle.hh"
     
    120121  if (pd == G4Dineutron::Definition())    return dineutron; // Bertini class!
    121122
    122   G4cerr << " uups, unknown G4ParticleDefinition type" << G4endl;
    123   return 0;
     123  return 0;     // Unknown objects return zero (e.g., nuclei)
    124124}
    125125
     
    147147  return pd ? pd->GetPDGMass()*MeV/GeV : 0.0;   // From G4 to Bertini units
    148148}
     149
     150
     151// Print particle parameters
     152
     153void G4InuclElementaryParticle::printParticle() const {
     154  G4InuclParticle::printParticle();
     155  G4cout << " Particle: " << getDefinition()->GetParticleName()
     156         << " type " << type() << " mass " << getMass()
     157         << " ekin " << getKineticEnergy() << G4endl;
     158}
     159
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclEvaporation.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclEvaporation.cc,v 1.19 2010/06/25 09:44:40 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclEvaporation.cc,v 1.22 2010/09/24 21:09:01 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3838//              G4CollisionOutput, copy G4DynamicParticle directly from
    3939//              G4InuclParticle, no switch-block required.  Fix scaling factors.
     40// 20100914  M. Kelsey -- Migrate to integer A and Z
     41// 20100924  M. Kelsey -- Migrate to "OutgoingNuclei" names in CollisionOutput
    4042
     43#include "G4InuclEvaporation.hh"
    4144#include <numeric>
    4245#include "G4IonTable.hh"
     
    4548#include "G4DynamicParticleVector.hh"
    4649#include "G4EvaporationInuclCollider.hh"
    47 #include "G4InuclEvaporation.hh"
    4850#include "G4InuclNuclei.hh"
    4951#include "G4Track.hh"
     
    102104  }
    103105
    104   G4double A = theNucleus.GetA();
    105   G4double Z = theNucleus.GetZ();
     106  G4int A = theNucleus.GetA_asInt();
     107  G4int Z = theNucleus.GetZ_asInt();
    106108  G4double mTar  = G4NucleiProperties::GetNuclearMass(A, Z); // Mass of the target nucleus
    107109
     
    131133  evaporator->collide(0, nucleus, output);
    132134
    133   const std::vector<G4InuclNuclei>& nucleiFragments = output.getNucleiFragments();
     135  const std::vector<G4InuclNuclei>& outgoingNuclei = output.getOutgoingNuclei();
    134136  const std::vector<G4InuclElementaryParticle>& particles = output.getOutgoingParticles();
    135137
     
    158160  }
    159161
    160   //  G4cout << "# fragments " << output.getNucleiFragments().size() << G4endl;
     162  //  G4cout << "# fragments " << output.getOutgoingNuclei().size() << G4endl;
    161163  i=1;
    162   if (!nucleiFragments.empty()) {
    163     nucleiIterator ifrag = nucleiFragments.begin();
    164     for (; ifrag != nucleiFragments.end(); ifrag++) {
     164  if (!outgoingNuclei.empty()) {
     165    nucleiIterator ifrag = outgoingNuclei.begin();
     166    for (; ifrag != outgoingNuclei.end(); ifrag++) {
    165167      if (verboseLevel > 2) {
    166168        G4cout << " Nuclei fragment: " << i << G4endl; i++;
     
    171173      G4LorentzVector vlab = ifrag->getMomentum().boost(boostToLab);
    172174 
    173       G4int A = G4int(ifrag->getA());
    174       G4int Z = G4int(ifrag->getZ());
     175      G4int A = ifrag->getA();
     176      G4int Z = ifrag->getZ();
    175177      if (verboseLevel > 2) {
    176178        G4cout << "boosted v" << vlab << G4endl;
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclNuclei.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4InuclNuclei.cc,v 1.8.2.1 2010/06/25 09:44:42 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4InuclNuclei.cc,v 1.22 2010/09/25 06:44:30 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100301  M. Kelsey -- Add function to create unphysical nuclei for use
     
    3130// 20100319  M. Kelsey -- Add information message to makeNuclearFragment().
    3231//           Use new GetBindingEnergy() function instead of bindingEnergy().
     32// 20100622  M. Kelsey -- Use local "bindingEnergy()" function to call through.
     33// 20100627  M. Kelsey -- Test for non-physical fragments and abort job.
     34// 20100630  M. Kelsey -- Use excitation energy in G4Ions
     35// 20100714  M. Kelsey -- Use G4DynamicParticle::theDynamicalMass to deal with
     36//           excitation energy without instantianting "infinite" G4PartDefns.
     37// 20100719  M. Kelsey -- Change excitation energy without altering momentum
     38// 20100906  M. Kelsey -- Add fill() functions to rewrite contents
     39// 20100910  M. Kelsey -- Add clearExitonConfiguration() to fill() functions
     40// 20100914  M. Kelsey -- Make printout symmetric with G4InuclElemPart,
     41//              migrate to integer A and Z
     42// 20100924  M. Kelsey -- Add constructor to copy G4Fragment input, and output
     43//              functions to create G4Fragment
    3344
    3445#include "G4InuclNuclei.hh"
     46#include "G4Fragment.hh"
     47#include "G4HadronicException.hh"
    3548#include "G4InuclSpecialFunctions.hh"
    3649#include "G4Ions.hh"
     50#include "G4IonTable.hh"
     51#include "G4NucleiProperties.hh"
    3752#include "G4ParticleDefinition.hh"
    3853#include "G4ParticleTable.hh"
    39 #include "G4HadTmpUtil.hh"
    40 #include "G4NucleiProperties.hh"
    4154#include <assert.h>
    4255#include <sstream>
     
    4659
    4760
     61// Convert contents from (via constructor) and to G4Fragment
     62
     63G4InuclNuclei::G4InuclNuclei(const G4Fragment& aFragment, G4int model)
     64  : G4InuclParticle(makeDefinition(aFragment.GetA_asInt(),
     65                                   aFragment.GetZ_asInt()),
     66                    aFragment.GetMomentum()/GeV) {      // Bertini units
     67  setExitationEnergy(aFragment.GetExcitationEnergy());
     68  setModel(model);
     69
     70  // Exciton configuration must be set by hand
     71  theExitonConfiguration.protonQuasiParticles = aFragment.GetNumberOfCharged();
     72
     73  theExitonConfiguration.neutronQuasiParticles =
     74    aFragment.GetNumberOfCharged() - aFragment.GetNumberOfCharged();
     75
     76  // Split hole count evenly between protons and neutrons (arbitrary!)
     77  theExitonConfiguration.protonHoles = aFragment.GetNumberOfHoles()/2;
     78
     79  theExitonConfiguration.neutronHoles =
     80    aFragment.GetNumberOfHoles() - theExitonConfiguration.protonHoles;
     81}
     82
     83// FIXME:  Should we have a local buffer and return by const-reference instead?
     84G4Fragment G4InuclNuclei::makeG4Fragment() const {
     85  G4Fragment frag(getA(), getZ(), getMomentum()*GeV);   // From Bertini units
     86
     87  // Note:  exciton configuration has to be set piece by piece
     88  frag.SetNumberOfHoles(theExitonConfiguration.protonHoles
     89                        + theExitonConfiguration.neutronHoles);
     90
     91  frag.SetNumberOfParticles(theExitonConfiguration.protonQuasiParticles
     92                            + theExitonConfiguration.neutronQuasiParticles);
     93
     94  frag.SetNumberOfCharged(theExitonConfiguration.protonQuasiParticles);
     95
     96  return frag;
     97}
     98
     99G4InuclNuclei::operator G4Fragment() const {
     100  return makeG4Fragment();
     101}
     102
     103
     104// Overwrite data structure (avoids creating/copying temporaries)
     105
     106void G4InuclNuclei::fill(const G4LorentzVector& mom, G4int a, G4int z,
     107                         G4double exc, G4int model) {
     108  setDefinition(makeDefinition(a,z));
     109  setMomentum(mom);
     110  setExitationEnergy(exc);
     111  clearExitonConfiguration();
     112  setModel(model);
     113}
     114
     115void G4InuclNuclei::fill(G4double ekin, G4int a, G4int z, G4double exc,
     116                         G4int model) {
     117  setDefinition(makeDefinition(a,z));
     118  setKineticEnergy(ekin);
     119  setExitationEnergy(exc);
     120  clearExitonConfiguration();
     121  setModel(model);
     122}
     123
     124
     125// Change excitation energy while keeping momentum vector constant
     126
     127void G4InuclNuclei::setExitationEnergy(G4double e) {
     128  G4double ekin = getKineticEnergy();           // Current kinetic energy
     129
     130  G4double emass = getNucleiMass() + e*MeV/GeV; // From Bertini to G4 units
     131
     132  // Directly compute new kinetic energy from old
     133  G4double ekin_new = std::sqrt(emass*emass + ekin*(2.*getMass()+ekin)) - emass;
     134
     135  setMass(emass);              // Momentum is computed from mass and Ekin
     136  setKineticEnergy(ekin_new);
     137}
     138
     139
    48140// Convert nuclear configuration to standard GEANT4 pointer
    49141
     
    51143//        G4ParticleTable::GetIon() uses (Z,A)!
    52144
    53 G4ParticleDefinition*
    54 G4InuclNuclei::makeDefinition(G4double a, G4double z, G4double exc) {
     145G4ParticleDefinition* G4InuclNuclei::makeDefinition(G4int a, G4int z) {
    55146  G4ParticleTable* pTable = G4ParticleTable::GetParticleTable();
    56   G4ParticleDefinition *pd = pTable->GetIon(G4int(z), G4int(a), exc);
     147  G4ParticleDefinition *pd = pTable->GetIon(z, a, 0.);
    57148
    58149  // SPECIAL CASE:  Non-physical nuclear fragment, for final-state return
    59   if (!pd) pd = makeNuclearFragment(a,z,exc);
    60 
    61   return pd;
    62 }
     150  if (!pd) pd = makeNuclearFragment(a,z);
     151
     152  return pd;            // This could return a null pointer if above fails
     153}
     154
     155// Creates a non-standard excited nucleus
    63156
    64157// Creates a non-physical pseudo-nucleus, for return as final-state fragment
     
    66159
    67160G4ParticleDefinition*
    68 G4InuclNuclei::makeNuclearFragment(G4double a, G4double z, G4double exc) {
    69   G4int na=G4int(a), nz=G4int(z), nn=na-nz;     // # nucleon, proton, neutron
    70 
    71   // See G4IonTable.hh::GetNucleusEncoding for explanation
    72   G4int code = ((100+nz)*1000 + na)*10 + (exc>0.)?1:0;
     161G4InuclNuclei::makeNuclearFragment(G4int a, G4int z) {
     162  if (a<=0 || z<0 || a<z) {
     163    G4cerr << " >>> G4InuclNuclei::makeNuclearFragment() called with"
     164           << " impossible arguments A=" << a << " Z=" << z << G4endl;
     165    throw G4HadronicException(__FILE__, __LINE__,
     166                              "G4InuclNuclei impossible A/Z arguments");
     167  }
     168
     169  G4int code = G4IonTable::GetNucleusEncoding(z, a);
    73170
    74171  // Use local lookup table (see G4IonTable.hh) to maintain singletons
    75172  // NOTE:  G4ParticleDefinitions don't need to be explicitly deleted
    76173  //        (see comments in G4IonTable.cc::~G4IonTable)
     174
     175  // If correct nucleus already created return it
    77176  static std::map<G4int, G4ParticleDefinition*> fragmentList;
    78 
    79177  if (fragmentList.find(code) != fragmentList.end()) return fragmentList[code];
    80178
    81179  // Name string follows format in G4IonTable.cc::GetIonName(Z,A,E)
    82   std::stringstream zstr, astr, estr;
    83   zstr << nz;
    84   astr << na;
    85   estr << G4int(1000*exc+0.5);  // keV in integer form
    86 
     180  std::stringstream zstr, astr;
     181  zstr << z;
     182  astr << a;
     183 
    87184  G4String name = "Z" + zstr.str() + "A" + astr.str();
    88   if (exc>0.) name += "["+estr.str()+"]";
    89 
    90   // Simple minded mass calculation use constants in CLHEP (all in MeV)
    91   G4double mass = nz*proton_mass_c2 + nn*neutron_mass_c2
    92     + G4NucleiProperties::GetBindingEnergy(G4lrint(a),G4lrint(z)) + exc;
    93 
     185 
     186  G4double mass = getNucleiMass(a,z) *GeV/MeV;  // From Bertini to GEANT4 units
     187 
    94188  //    Arguments for constructor are as follows
    95189  //               name             mass          width         charge
     
    99193  //             stable         lifetime    decay table
    100194  //             shortlived      subType    anti_encoding Excitation-energy
    101 
     195 
    102196  G4cout << " >>> G4InuclNuclei creating temporary fragment for evaporation "
    103197         << "with non-standard PDGencoding." << G4endl;
    104 
     198 
    105199  G4Ions* fragPD = new G4Ions(name,       mass, 0., z*eplus,
    106                               0,          +1,   0,
     200                              0,          +1,   0,
    107201                              0,          0,    0,
    108                               "nucleus",  0,    na, code,
     202                              "nucleus",  0,    a, code,
    109203                              true,       0.,   0,
    110                               true, "generic",  0,  exc);
     204                              true, "generic",  0,  0.);
    111205  fragPD->SetAntiPDGEncoding(0);
    112206
    113   fragmentList[code] = fragPD;          // Store in table for next lookup
    114   return fragPD;
    115 }
    116 
    117 G4double G4InuclNuclei::getNucleiMass(G4double a, G4double z) {
    118   G4ParticleDefinition* pd = makeDefinition(a,z);
    119   return pd ? pd->GetPDGMass()*MeV/GeV : 0.;    // From G4 to Bertini units
     207  return (fragmentList[code] = fragPD);     // Store in table for next lookup
     208}
     209
     210G4double G4InuclNuclei::getNucleiMass(G4int a, G4int z, G4double exc) {
     211  // Simple minded mass calculation use constants in CLHEP (all in MeV)
     212  G4double mass = G4NucleiProperties::GetNuclearMass(a,z) + exc;
     213
     214  return mass*MeV/GeV;          // Convert from GEANT4 to Bertini units
    120215}
    121216
    122217// Assignment operator for use with std::sort()
    123218G4InuclNuclei& G4InuclNuclei::operator=(const G4InuclNuclei& right) {
    124   exitationEnergy = right.exitationEnergy;
    125219  theExitonConfiguration = right.theExitonConfiguration;
    126220  G4InuclParticle::operator=(right);
    127221  return *this;
    128222}
     223
     224// Dump particle properties for diagnostics
     225
     226void G4InuclNuclei::printParticle() const {
     227  G4InuclParticle::printParticle();
     228  G4cout << " Nucleus: " << getDefinition()->GetParticleName()
     229         << " A " << getA() << " Z " << getZ() << " mass " << getMass()
     230         << " Eex (MeV) " << getExitationEnergy() << G4endl;
     231}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclParticle.cc

    r1337 r1340  
    2525//
    2626// $Id: G4InuclParticle.cc,v 1.7 2010/06/25 09:44:44 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100409  M. Kelsey -- Drop unused string argument from ctors.
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclSpecialFunctions.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4InuclSpecialFunctions.cc,v 1.20 2010/06/25 09:44:46 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4InuclSpecialFunctions.cc,v 1.21 2010/09/14 17:51:36 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     30// 20100914  M. Kelsey -- Migrate to integer A and Z.  Discard pointless
     31//              verbosity.
    3032
    3133#include "G4InuclSpecialFunctions.hh"
     
    3537#include <cmath>
    3638
    37 G4double G4InuclSpecialFunctions::getAL(G4double A) {
    38   G4int verboseLevel = 2;
    3939
    40   if (verboseLevel > 3) {
    41     G4cout << " >>> G4InuclSpecialFunctions::getAL" << G4endl;
    42   }
    43 
     40G4double G4InuclSpecialFunctions::getAL(G4int A) {
    4441  return 0.76 + 2.2 / G4cbrt(A);
    4542}
    4643
    4744G4double G4InuclSpecialFunctions::csNN(G4double e) {
    48   G4int verboseLevel = 2;
    49  
    50   if (verboseLevel > 3) {
    51     G4cout << " >>> G4InuclSpecialFunctions::csNN" << G4endl;
    52   }
    53 
    5445  G4double snn;
    5546
    5647  if (e < 40.0) {
    5748    snn = -1174.8 / (e * e) + 3088.5 / e + 5.3107;
    58 
    5949  } else {
    6050    snn = 93074.0 / (e * e) - 11.148 / e + 22.429;
    61   };
     51  }
    6252
    6353  return snn;
     
    6555
    6656G4double G4InuclSpecialFunctions::csPN(G4double e) {
    67   G4int verboseLevel = 2;
    68 
    69   if (verboseLevel > 3) {
    70     G4cout << " >>> G4InuclSpecialFunctions::csPN" << G4endl;
    71   }
    72 
    7357  G4double spn;
    7458
    7559  if (e < 40.0) {
    7660    spn = -5057.4 / (e * e) + 9069.2 / e + 6.9466;
    77 
    7861  } else {
    7962    spn = 239380.0 / (e * e) + 1802.0 / e + 27.147;
    80   };
     63  }
    8164
    8265  return spn;
    8366}
    8467
    85 G4double G4InuclSpecialFunctions::FermiEnergy(G4double A, G4double Z, G4int ntype) {
    86   // calculates the nuclei Fermi energy for 0 - neutron and 1 - proton
    87   G4int verboseLevel = 2;
     68// calculates the nuclei Fermi energy for 0 - neutron and 1 - proton
    8869
    89   if (verboseLevel > 3) {
    90     G4cout << " >>> G4InuclSpecialFunctions::FermiEnergy" << G4endl;
    91   }
    92 
     70G4double G4InuclSpecialFunctions::FermiEnergy(G4int A, G4int Z, G4int ntype) {
    9371  const G4double C = 55.4;
    94   G4double arg = (ntype==0) ? (A-Z)/A : Z/A;
     72  G4double arg = (ntype==0) ? G4double(A-Z)/A : G4double(Z)/A;
    9573
    9674  return C * G4cbrt(arg*arg);   // 2/3 power
     
    10280
    10381G4double G4InuclSpecialFunctions::inuclRndm() {
    104   G4int verboseLevel = 2;
    105 
    106   if (verboseLevel > 3) {
    107     G4cout << " >>> G4InuclSpecialFunctions::inuclRndm" << G4endl;
    108   }
    109 
    11082  G4double rnd = G4UniformRand();
    111 
    11283  return rnd;
    11384}
    11485
    11586G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
    116   G4int verboseLevel = 2;
    117 
    118   if (verboseLevel > 3) {
    119     G4cout << " >>> G4InuclSpecialFunctions::randomGauss" << G4endl;
    120   }
    121 
    12287  const G4double eps = 1.0e-6;
    12388  const G4double twopi = 6.2831854;
     
    13297
    13398G4double G4InuclSpecialFunctions::randomPHI() {
    134   G4int verboseLevel = 2;
    135 
    136   if (verboseLevel > 3) {
    137     G4cout << " >>> G4InuclSpecialFunctions::randomPHI" << G4endl;
    138   }
    139 
    14099  const G4double twopi = 6.2831853;
    141 
    142100  return twopi * inuclRndm();
    143101}
    144102
    145103std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN() {
    146   G4int verboseLevel = 2;
    147 
    148   if (verboseLevel > 3) {
    149     G4cout << " >>> G4InuclSpecialFunctions::randomCOS_SIN" << G4endl;
    150   }
    151 
    152104  G4double CT = 1.0 - 2.0 * inuclRndm();
    153105
    154   return std::pair<G4double, G4double>(CT, std::sqrt(1.0 - CT * CT));
     106  return std::pair<G4double, G4double>(CT, std::sqrt(1.0 - CT*CT));
    155107}
    156108
     
    158110G4InuclSpecialFunctions::generateWithFixedTheta(G4double ct, G4double p,
    159111                                                G4double m) {
    160   const G4int verboseLevel = 0;
    161   if (verboseLevel > 3) {
    162     G4cout << " >>> G4InuclSpecialFunctions::generateWithFixedTheta" << G4endl;
    163   }
    164 
    165112  G4double phi = randomPHI();
    166113  G4double pt = p * std::sqrt(std::fabs(1.0 - ct * ct));
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4KaonHypSampler.cc

    r1337 r1340  
    2525//
    2626// $Id: G4KaonHypSampler.cc,v 1.2 2010/06/25 09:44:48 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100512  M. Kelsey -- Replaces (old, untemplated) G4CascadeSampler
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4LorentzConvertor.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4LorentzConvertor.cc,v 1.23.2.1 2010/06/25 09:44:50 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4LorentzConvertor.cc,v 1.29 2010/09/15 20:16:16 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100108  Michael Kelsey -- Use G4LorentzVector internally
     
    3332// 20100409  M. Kelsey -- Protect std::sqrt(ga) against round-off negatives
    3433// 20100519  M. Kelsey -- Add interfaces to pass G4InuclParticles directly
     34// 20100617  M. Kelsey -- Add more diagnostic messages with multiple levels
     35// 20100713  M. Kelsey -- All diagnostic messages should be verbose > 1
    3536
    3637#include "G4LorentzConvertor.hh"
     
    4344
    4445G4LorentzConvertor::G4LorentzConvertor()
    45   : verboseLevel(0), degenerated(false) {
    46 
    47   if (verboseLevel > 3) {
     46  : verboseLevel(0), velocity(0.), gamma(0.), v2(0.), ecm_tot(0.),
     47    ga(0.), gb(0.), gbpp(0.), gapp(0.), degenerated(false) {
     48  if (verboseLevel)
    4849    G4cout << " >>> G4LorentzConvertor::G4LorentzConvertor" << G4endl;
    49   }
     50}
     51
     52G4LorentzConvertor::
     53G4LorentzConvertor(const G4LorentzVector& bmom, G4double bmass,
     54                   const G4LorentzVector& tmom, G4double tmass)
     55  : verboseLevel(0), velocity(0.), gamma(0.), v2(0.), ecm_tot(0.),
     56    ga(0.), gb(0.), gbpp(0.), gapp(0.), degenerated(false) {
     57  setBullet(bmom, bmass);
     58  setTarget(tmom, tmass);
     59}
     60
     61G4LorentzConvertor::
     62G4LorentzConvertor(const G4InuclParticle* bullet,
     63                   const G4InuclParticle* target)
     64  : verboseLevel(0), velocity(0.), gamma(0.), v2(0.), ecm_tot(0.),
     65    ga(0.), gb(0.), gbpp(0.), gapp(0.), degenerated(false) {
     66  setBullet(bullet);
     67  setTarget(target);
    5068}
    5169
     
    5977}
    6078
     79
    6180// Boost bullet and target four-vectors into destired frame
    6281
    6382void G4LorentzConvertor::toTheCenterOfMass() {
    64   if (verboseLevel > 3) {
     83  if (verboseLevel > 2)
    6584    G4cout << " >>> G4LorentzConvertor::toTheCenterOfMass" << G4endl;
    66   }
    6785
    6886  G4LorentzVector cm4v = target_mom + bullet_mom;
    6987  velocity = cm4v.boostVector();
     88  if (verboseLevel > 3)
     89    G4cout << " boost " << velocity.x() << " " << velocity.y() << " "
     90           << velocity.z() << G4endl;
    7091
    7192  // "SCM" is reverse target momentum in the CM frame
     
    7596
    7697  if (verboseLevel > 3)
    77     G4cout << " i 1 pscm(i) " << scm_momentum.x() << G4endl
    78            << " i 2 pscm(i) " << scm_momentum.y() << G4endl
    79            << " i 3 pscm(i) " << scm_momentum.z() << G4endl;
     98    G4cout << " pscm " << scm_momentum.x() << " " << scm_momentum.y()
     99           << " " << scm_momentum.z() << G4endl;
    80100
    81101  // Compute kinematic quantities for rotate() functions
    82102  v2 = velocity.mag2();
    83   gamma = cm4v.e()/cm4v.m();
    84 
    85103  ecm_tot = cm4v.m();
     104  gamma = cm4v.e()/ecm_tot;
    86105
    87106  G4double pscm = scm_momentum.rho();
    88   G4double pa   = scm_momentum.vect().mag2();
     107  G4double pa   = pscm*pscm;
    89108  G4double pb   = scm_momentum.vect().dot(velocity);
    90109
     
    97116
    98117  degenerated = (ga < small);
    99   if (degenerated && verboseLevel > 3)
    100     G4cout << " degenerated case " << G4endl;
     118  if (degenerated && verboseLevel > 2)
     119    G4cout << " degenerated case (already in CM frame) " << G4endl;
    101120
    102121  if (verboseLevel > 3) {
     
    108127
    109128void G4LorentzConvertor::toTheTargetRestFrame() {
    110   if (verboseLevel > 3) {
     129  if (verboseLevel > 2)
    111130    G4cout << " >>> G4LorentzConvertor::toTheTargetRestFrame" << G4endl;
    112   }
    113131
    114132  velocity = target_mom.boostVector();
     133  if (verboseLevel > 3)
     134    G4cout << " boost " << velocity.x() << " " << velocity.y() << " "
     135           << velocity.z() << G4endl;
    115136
    116137  // "SCM" is bullet momentum in the target's frame
     
    119140
    120141  if (verboseLevel > 3)
    121     G4cout << " rf: i 1 pscm(i) " << scm_momentum.x() << G4endl
    122            << " rf: i 2 pscm(i) " << scm_momentum.y() << G4endl
    123            << " rf: i 3 pscm(i) " << scm_momentum.z() << G4endl;
     142    G4cout << " pseudo-pscm " << scm_momentum.x() << " " << scm_momentum.y()
     143           << " " << scm_momentum.z() << G4endl;
    124144
    125145  // Compute kinematic quantities for rotate() functions
     
    128148
    129149  G4double pscm = scm_momentum.rho();
    130   G4double pa   = scm_momentum.vect().mag2();
     150  G4double pa   = pscm*pscm;
    131151  G4double pb   = velocity.dot(scm_momentum.vect());
    132152
     
    139159
    140160  degenerated = (ga < small);
    141   if (degenerated && verboseLevel > 3)
    142     G4cout << " degenerated case " << G4endl;
     161  if (degenerated && verboseLevel > 2)
     162    G4cout << " degenerated case (already in target frame) " << G4endl;
     163
     164  if (verboseLevel > 3) {
     165    G4cout << " ga " << ga << " v2 " << v2 << " pb " << pb
     166           << " pb * pb / pa " << pb * pb / pa << G4endl;
     167  }
    143168}
    144169
    145170G4LorentzVector
    146171G4LorentzConvertor::backToTheLab(const G4LorentzVector& mom) const {
    147   if (verboseLevel > 3) {
    148     G4cout << " >>> G4LorentzConvertor::backToTheLab" << G4endl
    149            << " at rest: px " << mom.x() << " py " << mom.y() << " pz "
     172  if (verboseLevel > 2)
     173    G4cout << " >>> G4LorentzConvertor::backToTheLab" << G4endl;
     174
     175  if (verboseLevel > 3)
     176    G4cout << " at rest: px " << mom.x() << " py " << mom.y() << " pz "
    150177           << mom.z() << " e " << mom.e() << G4endl
    151178           << " v2 " << v2 << G4endl;
    152   }
    153179
    154180  G4LorentzVector mom1 = mom;
     
    166192
    167193G4double G4LorentzConvertor::getKinEnergyInTheTRS() const {
     194  if (verboseLevel > 2)
     195    G4cout << " >>> G4LorentzConvertor::getKinEnergyInTheTRS" << G4endl;
     196
    168197  G4double pv = bullet_mom.vect().dot(target_mom.vect());
    169198 
     
    176205
    177206G4double G4LorentzConvertor::getTRSMomentum() const {
     207  if (verboseLevel > 2)
     208    G4cout << " >>> G4LorentzConvertor::getTRSMomentum" << G4endl;
     209
    178210  G4LorentzVector bmom = bullet_mom;
    179211  bmom.boost(-target_mom.boostVector());
     
    182214
    183215G4LorentzVector G4LorentzConvertor::rotate(const G4LorentzVector& mom) const {
    184   if (verboseLevel > 3) {
    185     G4cout << " >>> G4LorentzConvertor::rotate(G4LorentzVector)" << G4endl
    186            << " ga " << ga << " gbpp " << gbpp << " gapp " << gapp << G4endl
     216  if (verboseLevel > 2)
     217    G4cout << " >>> G4LorentzConvertor::rotate(G4LorentzVector)" << G4endl;
     218
     219  if (verboseLevel > 3) {
     220    G4cout << " ga " << ga << " gbpp " << gbpp << " gapp " << gapp << G4endl
    187221           << " degenerated " << degenerated << G4endl
    188222           << " before rotation: px " << mom.x() << " py " << mom.y()
     
    192226  G4LorentzVector mom_rot = mom;
    193227  if (!degenerated) {
     228    if (verboseLevel > 2)
     229      G4cout << " rotating to align with reference z axis " << G4endl;
     230
    194231    G4ThreeVector vscm = velocity - gbpp*scm_momentum.vect();
    195232    G4ThreeVector vxcm = scm_momentum.vect().cross(velocity);
     
    209246G4LorentzVector G4LorentzConvertor::rotate(const G4LorentzVector& mom1,
    210247                                           const G4LorentzVector& mom) const {
    211   if (verboseLevel > 3) {
     248  if (verboseLevel > 2)
    212249    G4cout << " >>> G4LorentzConvertor::rotate(G4LorentzVector,G4LorentzVector)"
    213            << G4endl
    214            << " before rotation: px " << mom.x() << " py " << mom.y()
     250           << G4endl;
     251
     252  if (verboseLevel > 3) {
     253    G4cout << " before rotation: px " << mom.x() << " py " << mom.y()
    215254           << " pz " << mom.z() << G4endl;
    216255  }
     
    228267  if (ga1 > small) {
    229268    ga1 = std::sqrt(ga1);
    230 
    231269    G4double gb1 = pv / pp;
    232270
    233271    pp = std::sqrt(pp);
    234 
    235272    G4double ga1pp = ga1 * pp;
    236273
     
    239276    }
    240277
     278    if (verboseLevel > 2)
     279      G4cout << " rotating to align with first z axis " << G4endl;
     280
    241281    G4ThreeVector vmom1 = velocity - gb1*mom1;
    242282    G4ThreeVector vxm1  = mom1.vect().cross(velocity);
     
    255295
    256296G4bool G4LorentzConvertor::reflectionNeeded() const {
    257   if (verboseLevel > 3) {
    258     G4cout << " >>> G4LorentzConvertor::reflectionNeeded: v2 = " << v2
    259            << " SCM z = " << scm_momentum.z() << " degenerated? "
    260            << degenerated << G4endl;
     297  if (verboseLevel > 2)
     298    G4cout << " >>> G4LorentzConvertor::reflectionNeeded (query)" << G4endl;
     299
     300  if (verboseLevel > 3) {
     301    G4cout << " v2 = " << v2 << " SCM z = " << scm_momentum.z()
     302           << " degenerated? " << degenerated << G4endl;
    261303  }
    262304
     
    264306    throw G4HadronicException(__FILE__, __LINE__, "G4LorentzConvertor::reflectionNeeded - return value undefined");
    265307
    266   return (v2>=small && (!degenerated || scm_momentum.z() < 0.0));
    267 }
    268 
    269 
    270 
    271 
    272 
    273 
    274 
     308  if (verboseLevel > 2) {
     309    G4cout << " reflection across XY is"
     310           << ((v2>=small && (!degenerated || scm_momentum.z()<0.0))?"":" NOT")
     311           << " needed" << G4endl;
     312  }
     313
     314  return (v2>=small && (!degenerated || scm_momentum.z()<0.0));
     315}
     316
     317
     318// Reporting functions for diagnostics
     319
     320void G4LorentzConvertor::printBullet() const {
     321  G4cout << " G4LC bullet: px " << bullet_mom.px() << " py " << bullet_mom.py()
     322         << " pz " << bullet_mom.pz() << " e " << bullet_mom.e()
     323         << " mass " << bullet_mom.m() << G4endl;
     324  }
     325
     326void G4LorentzConvertor::printTarget() const {
     327  G4cout << " G4LC target: px " << target_mom.px() << " py " << target_mom.py()
     328         << " pz " << target_mom.pz() << " e " << target_mom.e()
     329         << " mass " << target_mom.m() << G4endl;
     330}
     331
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4NonEquilibriumEvaporator.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4NonEquilibriumEvaporator.cc,v 1.29.2.1 2010/06/25 09:44:52 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4NonEquilibriumEvaporator.cc,v 1.40 2010/09/24 20:51:05 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2827//
    2928// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    3332// 20100413  M. Kelsey -- Pass buffers to paraMaker[Truncated]
    3433// 20100517  M. Kelsey -- Inherit from common base class
    35 
    36 #define RUN
    37 
    38 #include <cmath>
     34// 20100617  M. Kelsey -- Remove "RUN" preprocessor flag and all "#else" code
     35// 20100622  M. Kelsey -- Use local "bindingEnergy()" function to call through.
     36// 20100701  M. Kelsey -- Don't need to add excitation to nuclear mass; compute
     37//              new excitation energies properly (mass differences)
     38// 20100713  M. Kelsey -- Add conservation checking, diagnostic messages.
     39// 20100714  M. Kelsey -- Move conservation checking to base class
     40// 20100719  M. Kelsey -- Simplify EEXS calculations with particle evaporation.
     41// 20100724  M. Kelsey -- Replace std::vector<> D with trivial D[3] array.
     42// 20100914  M. Kelsey -- Migrate to integer A and Z: this involves replacing
     43//              a number of G4double terms with G4int, with consequent casts.
     44
    3945#include "G4NonEquilibriumEvaporator.hh"
    4046#include "G4CollisionOutput.hh"
     
    4349#include "G4InuclSpecialFunctions.hh"
    4450#include "G4LorentzConvertor.hh"
    45 #include "G4NucleiProperties.hh"
    46 #include "G4HadTmpUtil.hh"
     51#include <cmath>
    4752
    4853using namespace G4InuclSpecialFunctions;
     
    5055
    5156G4NonEquilibriumEvaporator::G4NonEquilibriumEvaporator()
    52   : G4VCascadeCollider("G4NonEquilibriumEvaporator") {}
     57  : G4CascadeColliderBase("G4NonEquilibriumEvaporator") {}
    5358
    5459
     
    5762                                         G4CollisionOutput& output) {
    5863
    59   if (verboseLevel > 3) {
     64  if (verboseLevel) {
    6065    G4cout << " >>> G4NonEquilibriumEvaporator::collide" << G4endl;
    6166  }
     
    6873  }
    6974
    70   const G4double a_cut = 5.0;
    71   const G4double z_cut = 3.0;
    72 
    73 #ifdef RUN
     75  if (verboseLevel > 2) {
     76    G4cout << " evaporating target: " << G4endl;
     77    target->printParticle();
     78  }
     79 
     80  const G4int a_cut = 5;
     81  const G4int z_cut = 3;
     82
    7483  const G4double eexs_cut = 0.1;
    75 #else
    76   const G4double eexs_cut = 100000.0;
    77 #endif
    7884
    7985  const G4double coul_coeff = 1.4;
     
    8288  const G4double width_cut = 0.005;
    8389
    84     G4double A = nuclei_target->getA();
    85     G4double Z = nuclei_target->getZ();
    86     G4LorentzVector PEX = nuclei_target->getMomentum();
    87     G4LorentzVector pin = PEX;
    88     G4double EEXS = nuclei_target->getExitationEnergy();
    89     pin.setE(pin.e() + 0.001 * EEXS);
    90     G4InuclNuclei dummy_nuc;
    91     G4ExitonConfiguration config = nuclei_target->getExitonConfiguration(); 
    92 
    93     G4double QPP = config.protonQuasiParticles;
    94 
    95     G4double QNP = config.neutronQuasiParticles;
    96 
    97     G4double QPH = config.protonHoles;
    98 
    99     G4double QNH = config.neutronHoles;
    100 
    101     G4double QP = QPP + QNP;
    102     G4double QH = QPH + QNH;
    103     G4double QEX = QP + QH;
    104     G4InuclElementaryParticle dummy(small_ekin, 1);
    105     G4LorentzConvertor toTheExitonSystemRestFrame;
    106 
    107     toTheExitonSystemRestFrame.setBullet(dummy);
    108 
    109     G4double EFN = FermiEnergy(A, Z, 0);
    110     G4double EFP = FermiEnergy(A, Z, 1);
    111 
    112     G4double AR = A - QP;
    113     G4double ZR = Z - QPP; 
    114     G4int NEX = G4int(QEX + 0.5);
    115     G4LorentzVector ppout;
    116     G4bool try_again = (NEX > 0);
    117  
    118     // Buffer for parameter sets
    119     std::pair<G4double, G4double> parms;
    120 
    121     while (try_again) {
    122 
    123       if (A >= a_cut && Z >= z_cut && EEXS > eexs_cut) { // ok
    124 
    125         if (verboseLevel > 2) {
    126           G4cout << " A " << A << " Z " << Z << " EEXS " << EEXS << G4endl;
    127         }
    128 
    129         // update exiton system
    130         G4double nuc_mass = dummy_nuc.getNucleiMass(A, Z);
    131         PEX.setVectM(PEX.vect(), nuc_mass);
    132         toTheExitonSystemRestFrame.setTarget(PEX, nuc_mass);
    133         toTheExitonSystemRestFrame.toTheTargetRestFrame();
    134         G4double MEL = getMatrixElement(A);
    135         G4double E0 = getE0(A);
    136         G4double PL = getParLev(A, Z);
    137         G4double parlev = PL / A;
    138         G4double EG = PL * EEXS;
    139 
    140         if (QEX < std::sqrt(2.0 * EG)) { // ok
    141 
    142           paraMakerTruncated(Z, parms);
    143           const G4double& AK1 = parms.first;
    144           const G4double& CPA1 = parms.second;
    145 
    146           G4double VP = coul_coeff * Z * AK1 / (G4cbrt(A - 1.0) + 1.0) /
    147             (1.0 + EEXS / E0);
    148           //      G4double DM1 = bindingEnergy(A, Z);
    149           //      G4double BN = DM1 - bindingEnergy(A - 1.0, Z);
    150           //      G4double BP = DM1 - bindingEnergy(A - 1.0, Z - 1.0);
    151           G4double DM1 = G4NucleiProperties::GetBindingEnergy(G4lrint(A), G4lrint(Z));
    152           G4double BN = DM1 - G4NucleiProperties::GetBindingEnergy(G4lrint(A-1.0), G4lrint(Z));
    153           G4double BP = DM1 - G4NucleiProperties::GetBindingEnergy(G4lrint(A-1.0), G4lrint(Z-1.0));
    154           G4double EMN = EEXS - BN;
    155           G4double EMP = EEXS - BP - VP * A / (A - 1.0);
    156           G4double ESP = 0.0;
     90  G4int A = nuclei_target->getA();
     91  G4int Z = nuclei_target->getZ();
     92 
     93  G4LorentzVector PEX = nuclei_target->getMomentum();
     94  G4LorentzVector pin = PEX;            // Save original four-vector for later
     95 
     96  G4double EEXS = nuclei_target->getExitationEnergy();
     97 
     98  G4ExitonConfiguration config = nuclei_target->getExitonConfiguration(); 
     99 
     100  G4int QPP = config.protonQuasiParticles;
     101  G4int QNP = config.neutronQuasiParticles;
     102  G4int QPH = config.protonHoles;
     103  G4int QNH = config.neutronHoles;
     104 
     105  G4int QP = QPP + QNP;
     106  G4int QH = QPH + QNH;
     107  G4int QEX = QP + QH;
     108 
     109  G4InuclElementaryParticle dummy(small_ekin, 1);
     110  G4LorentzConvertor toTheExitonSystemRestFrame;
     111  //*** toTheExitonSystemRestFrame.setVerbose(verboseLevel);
     112  toTheExitonSystemRestFrame.setBullet(dummy);
     113 
     114  G4double EFN = FermiEnergy(A, Z, 0);
     115  G4double EFP = FermiEnergy(A, Z, 1);
     116 
     117  G4int AR = A - QP;
     118  G4int ZR = Z - QPP; 
     119  G4int NEX = QEX;
     120  G4LorentzVector ppout;
     121  G4bool try_again = (NEX > 0);
     122 
     123  // Buffer for parameter sets
     124  std::pair<G4double, G4double> parms;
     125 
     126  while (try_again) {
     127    if (A >= a_cut && Z >= z_cut && EEXS > eexs_cut) { // ok
     128      // update exiton system (include excitation energy!)
     129      G4double nuc_mass = G4InuclNuclei::getNucleiMass(A, Z, EEXS);
     130      PEX.setVectM(PEX.vect(), nuc_mass);
     131      toTheExitonSystemRestFrame.setTarget(PEX);
     132      toTheExitonSystemRestFrame.toTheTargetRestFrame();
     133     
     134      if (verboseLevel > 2) {
     135        G4cout << " A " << A << " Z " << Z << " mass " << nuc_mass
     136               << " EEXS " << EEXS << G4endl;
     137      }
     138     
     139      G4double MEL = getMatrixElement(A);
     140      G4double E0 = getE0(A);
     141      G4double PL = getParLev(A, Z);
     142      G4double parlev = PL / A;
     143      G4double EG = PL * EEXS;
     144     
     145      if (QEX < std::sqrt(2.0 * EG)) { // ok
     146        if (verboseLevel > 3)
     147          G4cout << " QEX " << QEX << " < sqrt(2*EG) " << std::sqrt(2.*EG)
     148                 << G4endl;
    157149       
    158           if (EMN > eexs_cut) { // ok
    159             G4int icase = 0;
     150        paraMakerTruncated(Z, parms);
     151        const G4double& AK1 = parms.first;
     152        const G4double& CPA1 = parms.second;
     153       
     154        G4double VP = coul_coeff * Z * AK1 / (G4cbrt(A-1) + 1.0) /
     155          (1.0 + EEXS / E0);
     156        G4double DM1 = bindingEnergy(A,Z);
     157        G4double BN = DM1 - bindingEnergy(A-1,Z);
     158        G4double BP = DM1 - bindingEnergy(A-1,Z-1);
     159        G4double EMN = EEXS - BN;
     160        G4double EMP = EEXS - BP - VP * A / (A-1);
     161        G4double ESP = 0.0;
     162       
     163        if (EMN > eexs_cut) { // ok
     164          G4int icase = 0;
    160165         
    161             if (NEX > 1) {
    162               G4double APH = 0.25 * (QP * QP + QH * QH + QP - 3.0 * QH);
    163               G4double APH1 = APH + 0.5 * (QP + QH);
    164               ESP = EEXS / QEX;
    165               G4double MELE = MEL / ESP / (A*A*A);
    166 
    167               if (ESP > 15.0) {
    168                 MELE *= std::sqrt(15.0 / ESP);
    169 
    170               } else if(ESP < 7.0) {
    171                 MELE *= std::sqrt(ESP / 7.0);
    172 
    173                 if (ESP < 2.0) MELE *= std::sqrt(ESP / 2.0);
    174               };   
     166          if (NEX > 1) {
     167            G4double APH = 0.25 * (QP * QP + QH * QH + QP - 3 * QH);
     168            G4double APH1 = APH + 0.5 * (QP + QH);
     169            ESP = EEXS / QEX;
     170            G4double MELE = MEL / ESP / (A*A*A);
     171           
     172            if (ESP > 15.0) {
     173              MELE *= std::sqrt(15.0 / ESP);
     174             
     175            } else if(ESP < 7.0) {
     176              MELE *= std::sqrt(ESP / 7.0);
     177             
     178              if (ESP < 2.0) MELE *= std::sqrt(ESP / 2.0);
     179            };   
    175180           
    176               G4double F1 = EG - APH;
    177               G4double F2 = EG - APH1;
     181            G4double F1 = EG - APH;
     182            G4double F2 = EG - APH1;
    178183           
    179               if (F1 > 0.0 && F2 > 0.0) {
    180                 G4double F = F2 / F1;
    181                 G4double M1 = 2.77 * MELE * PL;
    182                 std::vector<G4double> D(3, 0.0);
    183                 D[0] = M1 * F2 * F2 * std::pow(F, NEX - 1) / (QEX + 1.0);
    184 
    185                 if (D[0] > 0.0) {
    186 
    187                   if (NEX >= 2) {
    188                     D[1] = 0.0462 / parlev / G4cbrt(A) * QP * EEXS / QEX;
    189 
    190                     if (EMP > eexs_cut)
    191                       D[2] = D[1] * std::pow(EMP / EEXS, NEX) * (1.0 + CPA1);
    192                     D[1] *= std::pow(EMN / EEXS, NEX) * getAL(A);   
    193 
    194                     if (QNP < 1.0) D[1] = 0.0;
    195 
    196                     if (QPP < 1.0) D[2] = 0.0;
    197 
    198                     try_again = NEX > 1 && (D[1] > width_cut * D[0] ||
    199                                             D[2] > width_cut * D[0]);
    200 
    201                     if (try_again) {
    202                       G4double D5 = D[0] + D[1] + D[2];
    203                       G4double SL = D5 * inuclRndm();
    204                       G4double S1 = 0.;
    205 
    206                       for (G4int i = 0; i < 3; i++) {
    207                         S1 += D[i];     
    208 
    209                         if (SL <= S1) {
    210                           icase = i;
    211 
    212                           break;
    213                         };
     184            if (F1 > 0.0 && F2 > 0.0) {
     185              G4double F = F2 / F1;
     186              G4double M1 = 2.77 * MELE * PL;
     187              G4double D[3] = { 0., 0., 0. };
     188              D[0] = M1 * F2 * F2 * std::pow(F, NEX-1) / (QEX+1);
     189             
     190              if (D[0] > 0.0) {
     191               
     192                if (NEX >= 2) {
     193                  D[1] = 0.0462 / parlev / G4cbrt(A) * QP * EEXS / QEX;
     194                 
     195                  if (EMP > eexs_cut)
     196                    D[2] = D[1] * std::pow(EMP / EEXS, NEX) * (1.0 + CPA1);
     197                  D[1] *= std::pow(EMN / EEXS, NEX) * getAL(A);   
     198                 
     199                  if (QNP < 1) D[1] = 0.0;
     200                  if (QPP < 1) D[2] = 0.0;
     201                 
     202                  try_again = NEX > 1 && (D[1] > width_cut * D[0] ||
     203                                          D[2] > width_cut * D[0]);
     204                 
     205                  if (try_again) {
     206                    G4double D5 = D[0] + D[1] + D[2];
     207                    G4double SL = D5 * inuclRndm();
     208                    G4double S1 = 0.;
     209                   
     210                    for (G4int i = 0; i < 3; i++) {
     211                      S1 += D[i];       
     212                      if (SL <= S1) {
     213                        icase = i;
     214                        break;
    214215                      };
    215                     };
    216                   };
    217 
     216                    };
     217                  };
     218                };
     219              } else try_again = false;
     220            } else try_again = false;
     221          }
     222         
     223          if (try_again) {
     224            if (icase > 0) { // N -> N - 1 with particle escape
     225              if (verboseLevel > 3)
     226                G4cout << " try_again icase " << icase << G4endl;
     227             
     228              G4double V = 0.0;
     229              G4int ptype = 0;
     230              G4double B = 0.0;
     231             
     232              if (A < 3.0) try_again = false;
     233             
     234              if (try_again) {
     235               
     236                if (icase == 1) { // neutron escape
     237                 
     238                  if (QNP < 1) {
     239                    icase = 0;
     240                   
     241                  } else {
     242                    B = BN;
     243                    V = 0.0;
     244                    ptype = 2;           
     245                  };   
     246                 
     247                } else { // proton esape
     248                  if (QPP < 1) {
     249                    icase = 0;
     250                   
     251                  } else {
     252                    B = BP;
     253                    V = VP;
     254                    ptype = 1;
     255                   
     256                    if (Z-1 < 1) try_again = false;
     257                  };   
     258                };
     259               
     260                if (try_again && icase != 0) {
     261                  G4double EB = EEXS - B;
     262                  G4double E = EB - V * A / (A-1);
     263                 
     264                  if (E < 0.0) icase = 0;
     265                  else {
     266                    G4double E1 = EB - V;
     267                    G4double EEXS_new = -1.;
     268                    G4double EPART = 0.0;
     269                    G4int itry1 = 0;
     270                    G4bool bad = true;
     271                   
     272                    while (itry1 < itry_max && icase > 0 && bad) {
     273                      itry1++;
     274                      G4int itry = 0;               
     275                     
     276                      while (EEXS_new < 0.0 && itry < itry_max) {
     277                        itry++;
     278                        G4double R = inuclRndm();
     279                        G4double X;
     280                       
     281                        if (NEX == 2) {
     282                          X = 1.0 - std::sqrt(R);
     283                         
     284                        } else {                         
     285                          G4double QEX2 = 1.0 / QEX;
     286                          G4double QEX1 = 1.0 / (QEX-1);
     287                          X = std::pow(0.5 * R, QEX2);
     288                         
     289                          for (G4int i = 0; i < 1000; i++) {
     290                            G4double DX = X * QEX1 *
     291                              (1.0 + QEX2 * X * (1.0 - R / std::pow(X, NEX)) / (1.0 - X));
     292                            X -= DX;
     293                           
     294                            if (std::fabs(DX / X) < 0.01) break; 
     295                           
     296                          };
     297                        };
     298                        EPART = EB - X * E1;
     299                        EEXS_new = EB - EPART * A / (A-1);
     300                      } // while (EEXS_new < 0.0...
     301                     
     302                      if (itry == itry_max || EEXS_new < 0.0) {
     303                        icase = 0;
     304                        continue;
     305                      }
     306                     
     307                      if (verboseLevel > 2)
     308                        G4cout << " particle " << ptype << " escape " << G4endl;
     309                     
     310                      EPART /= GeV;             // From MeV to GeV
     311                     
     312                      G4InuclElementaryParticle particle(ptype);
     313                      particle.setModel(5);
     314                     
     315                      // generate particle momentum
     316                      G4double mass = particle.getMass();
     317                      G4double pmod = std::sqrt(EPART * (2.0 * mass + EPART));
     318                      G4LorentzVector mom = generateWithRandomAngles(pmod,mass);
     319                     
     320                      // Push evaporated paricle into current rest frame
     321                      mom = toTheExitonSystemRestFrame.backToTheLab(mom);
     322                     
     323                      // Adjust quasiparticle and nucleon counts
     324                      G4int QPP_new = QPP;
     325                      G4int QNP_new = QNP;
     326                     
     327                      G4int A_new = A-1;
     328                      G4int Z_new = Z;
     329                     
     330                      if (ptype == 1) {
     331                        QPP_new--;
     332                        Z_new--;
     333                      };
     334                     
     335                      if (ptype == 2) QNP_new--;
     336                     
     337                if (verboseLevel > 3) {
     338                  G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
     339                         << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
     340                         << " evaporate px " << mom.px() << " py " << mom.py()
     341                         << " pz " << mom.pz() << " E " << mom.e() << G4endl;
     342                }
     343               
     344                      // New excitation energy depends on residual nuclear state
     345                      G4double mass_new = G4InuclNuclei::getNucleiMass(A_new, Z_new);
     346                     
     347                      G4double EEXS_new = ((PEX-mom).m() - mass_new)*GeV;
     348                      if (EEXS_new < 0.) continue;      // Sanity check for new nucleus
     349                     
     350                      if (verboseLevel > 3)
     351                        G4cout << " EEXS_new " << EEXS_new << G4endl;
     352                     
     353                      PEX -= mom;
     354                      EEXS = EEXS_new;
     355                     
     356                      A = A_new;
     357                      Z = Z_new;
     358                     
     359                      NEX--;
     360                      QEX--;
     361                      QP--;
     362                      QPP = QPP_new;
     363                      QNP = QNP_new;
     364                     
     365                      particle.setMomentum(mom);
     366                      output.addOutgoingParticle(particle);
     367                      if (verboseLevel > 3) particle.printParticle();
     368                     
     369                      ppout += mom;
     370                      if (verboseLevel > 3) {
     371                        G4cout << " ppout px " << ppout.px() << " py " << ppout.py()
     372                               << " pz " << ppout.pz() << " E " << ppout.e() << G4endl;
     373                      }
     374
     375                      bad = false;
     376                    }           // while (itry1<itry_max && icase>0
     377                   
     378                    if (itry1 == itry_max) icase = 0;
     379                  }     // if (E < 0.) [else]
     380                }       // if (try_again && icase != 0)
     381              }         // if (try_again)
     382            }           // if (icase > 0)
     383           
     384            if (icase == 0 && try_again) { // N -> N + 2
     385              G4double TNN = 1.6 * EFN + ESP;
     386              G4double TNP = 1.6 * EFP + ESP;
     387              G4double XNUN = 1.0 / (1.6 + ESP / EFN);
     388              G4double XNUP = 1.0 / (1.6 + ESP / EFP);
     389              G4double SNN1 = csNN(TNP) * XNUP;
     390              G4double SNN2 = csNN(TNN) * XNUN;
     391              G4double SPN1 = csPN(TNP) * XNUP;
     392              G4double SPN2 = csPN(TNN) * XNUN;
     393              G4double PP = (QPP * SNN1 + QNP * SPN1) * ZR;
     394              G4double PN = (QPP * SPN2 + QNP * SNN2) * (AR - ZR);
     395              G4double PW = PP + PN;
     396              NEX += 2;
     397              QEX += 2;
     398              QP++;
     399              QH++;
     400              AR--;
     401             
     402              if (AR > 1) {
     403                G4double SL = PW * inuclRndm();
     404               
     405                if (SL > PP) {
     406                  QNP++;
     407                  QNH++;
    218408                } else {
    219                   try_again = false;
    220                 };
    221 
    222               } else {
    223                 try_again = false;
    224               };
    225             };           
    226 
    227             if (try_again) {
    228 
    229               if (icase > 0) { // N -> N - 1 with particle escape           
    230                 G4double V = 0.0;
    231                 G4int ptype = 0;
    232                 G4double B = 0.0;
    233 
    234                 if (A < 3.0) try_again = false;
    235 
    236                 if (try_again) {
    237 
    238                   if (icase == 1) { // neutron escape
    239 
    240                     if (QNP < 1.0) {
    241                       icase = 0;
    242 
    243                     } else {
    244                       B = BN;
    245                       V = 0.0;
    246                       ptype = 2;                 
    247                     };   
    248 
    249                   } else { // proton esape
    250                     if (QPP < 1.0) {
    251                       icase = 0;
    252 
    253                     } else {
    254                       B = BP;
    255                       V = VP;
    256                       ptype = 1;
    257 
    258                       if (Z - 1.0 < 1.0) try_again = false;
    259                     };   
    260                   };
    261                
    262                   if (try_again && icase != 0) {
    263                     G4double EB = EEXS - B;
    264                     G4double E = EB - V * A / (A - 1.0);
    265 
    266                     if (E < 0.0) {
    267                       icase = 0;
    268 
    269                     } else {
    270                       G4double E1 = EB - V;
    271                       G4double EEXS_new = -1.;
    272                       G4double EPART = 0.0;
    273                       G4int itry1 = 0;
    274                       G4bool bad = true;
    275 
    276                       while (itry1 < itry_max && icase > 0 && bad) {
    277                         itry1++;
    278                         G4int itry = 0;             
    279 
    280                         while (EEXS_new < 0.0 && itry < itry_max) {
    281                           itry++;
    282                           G4double R = inuclRndm();
    283                           G4double X;
    284 
    285                           if (NEX == 2) {
    286                             X = 1.0 - std::sqrt(R);
    287 
    288                           } else {                       
    289                             G4double QEX2 = 1.0 / QEX;
    290                             G4double QEX1 = 1.0 / (QEX - 1.0);
    291                             X = std::pow(0.5 * R, QEX2);
    292 
    293                             for (G4int i = 0; i < 1000; i++) {
    294                               G4double DX = X * QEX1 *
    295                                 (1.0 + QEX2 * X * (1.0 - R / std::pow(X, NEX)) / (1.0 - X));
    296                               X -= DX;
    297 
    298                               if (std::fabs(DX / X) < 0.01) break; 
    299 
    300                             };
    301                           };
    302                           EPART = EB - X * E1;
    303                           EEXS_new = EB - EPART * A / (A - 1.0);
    304                         };
    305                    
    306                         if (itry == itry_max || EEXS_new < 0.0) {
    307                           icase = 0;
    308 
    309                         } else { // real escape                 
    310                           G4InuclElementaryParticle particle(ptype);
    311 
    312                           particle.setModel(5);
    313                           G4double mass = particle.getMass();
    314                           EPART *= 0.001; // to the GeV
    315                           // generate particle momentum
    316                           G4double pmod = std::sqrt(EPART * (2.0 * mass + EPART));
    317                           G4LorentzVector mom = generateWithRandomAngles(pmod,mass);
    318                           G4LorentzVector mom_at_rest;
    319 
    320                           G4double QPP_new = QPP;
    321                           G4double Z_new = Z;
    322                        
    323                           if (ptype == 1) {
    324                             QPP_new -= 1.;
    325                             Z_new -= 1.0;
    326                           };
    327 
    328                           G4double QNP_new = QNP;
    329 
    330                           if (ptype == 2) QNP_new -= 1.0;
    331 
    332                           G4double A_new = A - 1.0;
    333                           G4double new_exiton_mass =
    334                             dummy_nuc.getNucleiMass(A_new, Z_new);
    335                           mom_at_rest.setVectM(-mom.vect(), new_exiton_mass);
    336 
    337                           G4LorentzVector part_mom =
    338                             toTheExitonSystemRestFrame.backToTheLab(mom);
    339                           part_mom.setVectM(part_mom.vect(), mass);
    340 
    341                           G4LorentzVector ex_mom =
    342                             toTheExitonSystemRestFrame.backToTheLab(mom_at_rest);
    343                           ex_mom.setVectM(ex_mom.vect(), new_exiton_mass);   
    344 
    345                           //             check energy conservation and set new exitation energy
    346                           EEXS_new = 1000.0 * (PEX.e() + 0.001 * EEXS -
    347                                                part_mom.e() - ex_mom.e());
    348 
    349                           if (EEXS_new > 0.0) { // everything ok
    350                             particle.setMomentum(part_mom);
    351                             output.addOutgoingParticle(particle);
    352                             ppout += part_mom;
    353 
    354                             A = A_new;
    355                             Z = Z_new;
    356                             PEX = ex_mom;
    357                             EEXS = EEXS_new;
    358                             NEX -= 1;
    359                             QEX -= 1;
    360                             QP -= 1.0;
    361                             QPP = QPP_new;
    362                             QNP = QNP_new;
    363                             bad = false;
    364                           };
    365                         };     
    366                       };   
    367 
    368                       if (itry1 == itry_max) icase = 0;
    369                     };   
    370                   };
    371                 };
    372               };
    373 
    374               if (icase == 0 && try_again) { // N -> N + 2
    375                 G4double TNN = 1.6 * EFN + ESP;
    376                 G4double TNP = 1.6 * EFP + ESP;
    377                 G4double XNUN = 1.0 / (1.6 + ESP / EFN);
    378                 G4double XNUP = 1.0 / (1.6 + ESP / EFP);
    379                 G4double SNN1 = csNN(TNP) * XNUP;
    380                 G4double SNN2 = csNN(TNN) * XNUN;
    381                 G4double SPN1 = csPN(TNP) * XNUP;
    382                 G4double SPN2 = csPN(TNN) * XNUN;
    383                 G4double PP = (QPP * SNN1 + QNP * SPN1) * ZR;
    384                 G4double PN = (QPP * SPN2 + QNP * SNN2) * (AR - ZR);
    385                 G4double PW = PP + PN;
    386                 NEX += 2;
    387                 QEX += 2.0;
    388                 QP += 1.0;
    389                 QH += 1.0;
    390                 AR -= 1.0;
    391 
    392                 if (AR > 1.0) {
    393                   G4double SL = PW * inuclRndm();
    394 
    395                   if (SL > PP) {
    396                     QNP += 1.0;
    397                     QNH += 1.0;
    398 
    399                   } else {
    400                     QPP += 1.0;
    401                     QPH += 1.0;
    402                     ZR -= 1.0;
    403 
    404                     if (ZR < 2.0) try_again = false;
    405 
    406                   };   
    407 
    408                 } else {
    409                   try_again = false;
    410                 };
    411               };
    412             };
    413 
    414           } else {
    415             try_again = false;
    416           };
    417 
    418         } else {
    419           try_again = false;
    420         };
    421 
    422       } else {
    423         try_again = false;
    424       }; 
    425     };
    426     // everything finished, set output nuclei
    427     // the exitation energy has to be re-set properly for the energy
    428     // conservation
    429 
     409                  QPP++;
     410                  QPH++;
     411                  ZR--;
     412                  if (ZR < 2) try_again = false;
     413                } 
     414              } else try_again = false;
     415            }   // if (icase==0 && try_again)
     416          }     // if (try_again)
     417        } else try_again = false;       // if (EMN > eexs_cut)
     418      } else try_again = false;         // if (QEX < sqrg(2*EG)
     419    } else try_again = false;           // if (A > a_cut ...
     420  }             // while (try_again)
     421 
     422  // everything finished, set output nuclei
     423
     424  if (output.numberOfOutgoingParticles() == 0) {
     425    output.addOutgoingNucleus(*nuclei_target);
     426  } else {
    430427    G4LorentzVector pnuc = pin - ppout;
    431     G4InuclNuclei nuclei(pnuc, A, Z);
    432 
    433     nuclei.setModel(5);
    434     nuclei.setEnergy();
    435 
    436     pnuc = nuclei.getMomentum();
    437     G4double eout = pnuc.e() + ppout.e(); 
    438     G4double eex_real = 1000.0 * (pin.e() - eout);       
    439 
    440     nuclei.setExitationEnergy(eex_real);
    441     output.addTargetFragment(nuclei);
    442 
     428    G4InuclNuclei nuclei(pnuc, A, Z, EEXS, 5);
     429   
     430    if (verboseLevel > 3) {
     431      G4cout << " remaining nucleus " << G4endl;
     432      nuclei.printParticle();
     433    }
     434    output.addOutgoingNucleus(nuclei);
     435  }
     436
     437  validateOutput(0, target, output);    // Check energy conservation, etc.
    443438  return;
    444439}
    445440
    446 G4double G4NonEquilibriumEvaporator::getMatrixElement(G4double A) const {
     441G4double G4NonEquilibriumEvaporator::getMatrixElement(G4int A) const {
    447442
    448443  if (verboseLevel > 3) {
     
    452447  G4double me;
    453448
    454   if (A > 150.0) {
    455     me = 100.0;
    456 
    457   } else if(A > 20.0) {
    458     me = 140.0;
    459 
    460   } else {
    461     me = 70.0;
    462   };
     449  if (A > 150) me = 100.0;
     450  else if (A > 20) me = 140.0;
     451  else me = 70.0;
    463452 
    464453  return me;
    465454}
    466455
    467 G4double G4NonEquilibriumEvaporator::getE0(G4double ) const {
    468 
     456G4double G4NonEquilibriumEvaporator::getE0(G4int ) const {
    469457  if (verboseLevel > 3) {
    470458    G4cout << " >>> G4NonEquilibriumEvaporator::getEO" << G4endl;
     
    476464}
    477465
    478 G4double G4NonEquilibriumEvaporator::getParLev(G4double A,
    479                                                G4double ) const {
     466G4double G4NonEquilibriumEvaporator::getParLev(G4int A,
     467                                               G4int ) const {
    480468
    481469  if (verboseLevel > 3) {
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4NuclWatcher.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4NuclWatcher.cc,v 1.3 2010/06/25 09:44:54 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4NuclWatcher.cc,v 1.5 2010/10/19 19:48:57 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100202  M. Kelsey -- Move most code here from .hh file, clean up
    3030// 20100405  M. Kelsey -- Pass const-ref std::vector<>
     31// 20101010  M. Kelsey -- Migrate to integer A and Z
     32// 20101019  M. Kelsey -- CoVerity report: "!true" should be "!here"
    3133
    3234#include "G4NuclWatcher.hh"
     
    3739#include <cmath>
    3840
    39 G4NuclWatcher::G4NuclWatcher(G4double z,
     41G4NuclWatcher::G4NuclWatcher(G4int z,
    4042                             const std::vector<G4double>& expa,
    4143                             const std::vector<G4double>& expcs,
     
    4749    exper_err(experr), checkable(check), nucleable(nucl) {}
    4850
    49 void G4NuclWatcher::watch(G4double a, G4double z) {
     51void G4NuclWatcher::watch(G4int a, G4int z) {
    5052  const G4double small = 0.001;
    5153 
    52   if (std::fabs(z-nuclz) >= small) return;
     54  if (std::abs(z-nuclz) >= small) return;
    5355
    5456  G4bool here = false;          // Increment specified nucleus count
    5557  G4int  simulatedAsSize = simulated_as.size();
    56   for (G4int i = 0; i<simulatedAsSize && !true; i++) {
    57     if (std::fabs(simulated_as[i] - a) < small) {
     58  for (G4int i = 0; i<simulatedAsSize && !here; i++) {
     59    if (std::abs(simulated_as[i] - a) < small) {
    5860      simulated_cs[i] += 1.0;
    5961      here = true;              // Terminates loop
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4NucleiModel.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
    25 //
    26 // $Id: G4NucleiModel.cc,v 1.48.2.1 2010/06/25 09:44:56 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     25// $Id: G4NucleiModel.cc,v 1.87 2010/09/24 06:26:06 mkelsey Exp $
     26// Geant4 tag: $Name: geant4-09-03-ref-09 $
    2827//
    2928// 20100112  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
     
    4140//              calculations.  use G4Cascade*Channel for total xsec in pi-N
    4241//              N-N channels.  Move absorptionCrossSection() from SpecialFunc.
    43 
    44 //#define CHC_CHECK
     42// 20100610  M. Kelsey -- Replace another random-angle code block; add some
     43//              diagnostic output for partner-list production.
     44// 20100617  M. Kelsey -- Replace preprocessor flag CHC_CHECK with
     45//              G4CASCADE_DEBUG_CHARGE
     46// 20100620  M. Kelsey -- Improve error message on empty partners list, add
     47//              four-momentum checking after EPCollider
     48// 20100621  M. Kelsey -- In boundaryTransition() account for momentum transfer
     49//              to secondary by boosting into recoil nucleus "rest" frame.
     50//              Don't need temporaries to create dummy "partners" for list.
     51// 20100622  M. Kelsey -- Restore use of "bindingEnergy()" function name, which
     52//              is now a wrapper for G4NucleiProperties::GetBindingEnergy().
     53// 20100623  M. Kelsey -- Eliminate some temporaries terminating partner-list,
     54//              discard recoil boost for now. Initialize all data
     55//              members in ctors.  Allow generateModel() to be called
     56//              mutliple times, by clearing vectors each time through;
     57//              avoid extra work by returning if A and Z are same as
     58//              before.
     59// 20100628  M. Kelsey -- Two momentum-recoil bugs; don't subtract energies!
     60// 20100715  M. Kelsey -- Make G4InuclNuclei in generateModel(), use for
     61//              balance checking (only verbose>2) in generateParticleFate().
     62// 20100721  M. Kelsey -- Use new G4CASCADE_CHECK_ECONS for conservation checks
     63// 20100723  M. Kelsey -- Move G4CollisionOutput buffer to .hh for reuse
     64// 20100726  M. Kelsey -- Preallocate arrays with number_of_zones dimension.
     65// 20100902  M. Kelsey -- Remove resize(3) directives from qdeutron/acsecs
     66// 20100907  M. Kelsey -- Limit interaction targets based on current nucleon
     67//              counts (e.g., no pp if protonNumberCurrent < 2!)
     68// 20100914  M. Kelsey -- Migrate to integer A and Z
    4569
    4670#include "G4NucleiModel.hh"
     71#include "G4CascadeCheckBalance.hh"
    4772#include "G4CascadeInterpolator.hh"
    4873#include "G4CascadeNNChannel.hh"
     
    6388#include "G4LorentzConvertor.hh"
    6489#include "G4Neutron.hh"
    65 #include "G4NucleiProperties.hh"
    6690#include "G4Proton.hh"
    6791
     
    6993using namespace G4InuclSpecialFunctions;
    7094
    71 
    7295typedef std::vector<G4InuclElementaryParticle>::iterator particleIterator;
    7396
    74 G4NucleiModel::G4NucleiModel() : verboseLevel(0) {
    75   if (verboseLevel > 3) {
    76     G4cout << " >>> G4NucleiModel::G4NucleiModel" << G4endl;
    77   }
    78 }
    79 
    80 G4NucleiModel::G4NucleiModel(G4InuclNuclei* nuclei) : verboseLevel(0) {
     97G4NucleiModel::G4NucleiModel()
     98  : verboseLevel(0), A(0), Z(0), theNucleus(0),
     99    neutronNumber(0), protonNumber(0),
     100    neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
     101    current_nucl2(0) {}
     102
     103G4NucleiModel::G4NucleiModel(G4int a, G4int z)
     104  : verboseLevel(0), A(0), Z(0), theNucleus(0),
     105    neutronNumber(0), protonNumber(0),
     106    neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
     107    current_nucl2(0) {
     108  generateModel(a,z);
     109}
     110
     111G4NucleiModel::G4NucleiModel(G4InuclNuclei* nuclei)
     112  : verboseLevel(0), A(0), Z(0), theNucleus(0),
     113    neutronNumber(0), protonNumber(0),
     114    neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
     115    current_nucl2(0) {
     116  generateModel(nuclei);
     117}
     118
     119
     120void
     121G4NucleiModel::generateModel(G4InuclNuclei* nuclei) {
    81122  generateModel(nuclei->getA(), nuclei->getZ());
    82123}
     
    84125
    85126void
    86 G4NucleiModel::generateModel(G4double a, G4double z) {
    87   if (verboseLevel > 3) {
    88     G4cout << " >>> G4NucleiModel::generateModel" << G4endl;
     127G4NucleiModel::generateModel(G4int a, G4int z) {
     128  if (verboseLevel) {
     129    G4cout << " >>> G4NucleiModel::generateModel A " << a << " Z " << z
     130           << G4endl;
    89131  }
    90132
     
    95137  const G4double pion_vp = 0.007; // in GeV
    96138  const G4double pion_vp_small = 0.007;
    97   const G4double radForSmall = 8.0; // fermi
    98   const G4double piTimes4thirds = 4.189; // 4 Pi/3
     139  const G4double radForSmall = 8.0;     // Units 0.f fm?  R_p = 0.8768 fm
     140  const G4double piTimes4thirds = 4.189; // 4 Pi/3      FIXME!
    99141  const G4double mproton = G4Proton::Definition()->GetPDGMass() / GeV;
    100142  const G4double mneutron = G4Neutron::Definition()->GetPDGMass() / GeV;
     
    102144  const G4double alfa6[6] = { 0.9, 0.6, 0.4, 0.2, 0.1, 0.05 };
    103145
     146  // If model already built, just return; otherwise intialize everything
     147  if (a == A && z == Z) {
     148    if (verboseLevel > 1)
     149      G4cout << " model already generated for A=" << a << ", Z=" << z << G4endl;
     150
     151    reset();            // Zeros out neutron/proton evaporates
     152    return;
     153  }
     154
    104155  A = a;
    105156  Z = z;
     157  delete theNucleus;
     158  theNucleus = new G4InuclNuclei(A,Z);          // For conservation checking
     159
    106160  neutronNumber = a - z;
    107161  protonNumber = z;
    108   neutronNumberCurrent = neutronNumber;
    109   protonNumberCurrent = protonNumber;
    110 
    111 // Set binding energies
    112 //  G4double dm = bindingEnergy(a, z);
    113   G4double dm = G4NucleiProperties::GetBindingEnergy(G4lrint(a), G4lrint(z));
    114 
    115   binding_energies.push_back(0.001 * std::fabs(G4NucleiProperties::GetBindingEnergy(G4lrint(a-1), G4lrint(z-1)) - dm)); // for P
    116   binding_energies.push_back(0.001 * std::fabs(G4NucleiProperties::GetBindingEnergy(G4lrint(a-1), G4lrint(z)) - dm)); // for N
     162  reset();
     163
     164  // Clear all parameters arrays for reloading
     165  binding_energies.clear();
     166  nucleon_densities.clear();
     167  zone_potentials.clear();
     168  fermi_momenta.clear();
     169  zone_radii.clear();
     170
     171  // Set binding energies
     172  G4double dm = bindingEnergy(a,z);
     173
     174  binding_energies.push_back(0.001 * std::fabs(bindingEnergy(a-1,z-1)-dm)); // for P
     175  binding_energies.push_back(0.001 * std::fabs(bindingEnergy(a-1,z)-dm));   // for N
    117176
    118177  G4double CU = cuu*G4cbrt(a); // half-density radius * 2.8197
     
    121180  G4double CU2 = 0.0;
    122181
    123   if (a > 4.5) {
    124     std::vector<G4double> ur;
     182  // This will be used to pre-allocate lots of arrays below
     183  number_of_zones = (a < 5) ? 1 : (a < 100) ? 3 : 6;
     184
     185  // Buffers used for zone-by-zone calculations
     186  G4double ur[7];
     187  G4double v[6];
     188  G4double v1[6];
     189
     190  // These are passed into nested vectors, so can't be made C arrays
     191  std::vector<G4double> rod(number_of_zones);
     192  std::vector<G4double> pf(number_of_zones);
     193  std::vector<G4double> vz(number_of_zones);
     194
     195  if (a > 4) {
    125196    G4int icase = 0;
    126197
    127     if (a > 99.5) {
    128       number_of_zones = 6;
    129       ur.push_back(-D1);
    130 
     198    if (a > 99) {
     199      ur[0] = -D1;
    131200      for (G4int i = 0; i < number_of_zones; i++) {
    132201        G4double y = std::log((1.0 + D) / alfa6[i] - 1.0);
    133202        zone_radii.push_back(CU + AU * y);
    134         ur.push_back(y);
     203        ur[i+1] = y;
    135204      }
    136 
    137     } else if (a > 11.5) {
    138       number_of_zones = 3;
    139       ur.push_back(-D1);
    140 
     205    } else if (a > 11) {
     206      ur[0] = -D1;
    141207      for (G4int i = 0; i < number_of_zones; i++) {
    142208        G4double y = std::log((1.0 + D)/alfa3[i] - 1.0);
    143209        zone_radii.push_back(CU + AU * y);
    144         ur.push_back(y);
     210        ur[i+1] = y;
    145211      }
    146 
    147212    } else {
    148       number_of_zones = 3;
    149213      icase = 1;
    150       ur.push_back(0.0);
    151214 
    152215      G4double CU1 = CU * CU;
    153216      CU2 = std::sqrt(CU1 * (1.0 - 1.0 / a) + 6.4);
    154217
     218      ur[0] = 0.0;
    155219      for (G4int i = 0; i < number_of_zones; i++) {
    156220        G4double y = std::sqrt(-std::log(alfa3[i]));
    157221        zone_radii.push_back(CU2 * y);
    158         ur.push_back(y);
     222        ur[i+1] = y;
    159223      }
    160224    }
    161225
    162226    G4double tot_vol = 0.0;
    163     std::vector<G4double> v;
    164     std::vector<G4double> v1;
    165 
    166227    G4int i(0);
    167228    for (i = 0; i < number_of_zones; i++) {
     
    169230
    170231      if (icase == 0) {
    171         v0 = volNumInt(ur[i], ur[i + 1], CU, D1);
    172 
     232        v0 = volNumInt(ur[i], ur[i+1], CU, D1);
    173233      } else {
    174         v0 = volNumInt1(ur[i], ur[i + 1], CU2);
    175       };
     234        v0 = volNumInt1(ur[i], ur[i+1], CU2);
     235      }
    176236 
    177       v.push_back(v0);
     237      v[i] = v0;
    178238      tot_vol += v0;
    179239
     
    181241      if (i > 0) v0 -= zone_radii[i-1]*zone_radii[i-1]*zone_radii[i-1];
    182242
    183       v1.push_back(v0);
     243      v1[i] = v0;
    184244    }
    185245
    186246    // Protons
    187     G4double dd0 = z/tot_vol/piTimes4thirds;
    188     std::vector<G4double> rod;
    189     std::vector<G4double> pf;
    190     std::vector<G4double> vz;
     247    G4double dd0 = G4double(z)/tot_vol/piTimes4thirds;
     248    rod.clear();
     249    pf.clear();
     250    vz.clear();
    191251
    192252    for (i = 0; i < number_of_zones; i++) {
     
    203263
    204264    // Neutrons
    205     dd0 = (a - z)/tot_vol/piTimes4thirds;
     265    dd0 = G4double(a-z)/tot_vol/piTimes4thirds;
    206266    rod.clear();
    207267    pf.clear();
     
    214274      pf.push_back(pff);
    215275      vz.push_back(0.5 * pff * pff / mneutron + binding_energies[1]);
    216     };
     276    }
    217277
    218278    nucleon_densities.push_back(rod);
     
    221281
    222282    // pion stuff (primitive)
    223     std::vector<G4double> vp(number_of_zones, pion_vp);
     283    const std::vector<G4double> vp(number_of_zones, pion_vp);
    224284    zone_potentials.push_back(vp);
    225285
    226286    // kaon potential (primitive)
    227     std::vector<G4double> kp(number_of_zones, -0.015);
     287    const std::vector<G4double> kp(number_of_zones, -0.015);
    228288    zone_potentials.push_back(kp);
    229289
    230290    // hyperon potential (primitive)
    231     std::vector<G4double> hp(number_of_zones, 0.03);
     291    const std::vector<G4double> hp(number_of_zones, 0.03);
    232292    zone_potentials.push_back(hp);
    233293
    234294  } else { // a < 5
    235     number_of_zones = 1;
    236295    G4double smallRad = radForSmall;
    237296    if (a == 4) smallRad *= 0.7;
     
    240299
    241300    // proton
    242     std::vector<G4double> rod;
    243     std::vector<G4double> pf;
    244     std::vector<G4double> vz;
    245301    for (G4int i = 0; i < number_of_zones; i++) {
    246302      G4double rd = vol*z;
     
    272328
    273329    // pion (primitive)
    274     std::vector<G4double> vp(number_of_zones, pion_vp_small);
     330    const std::vector<G4double> vp(number_of_zones, pion_vp_small);
    275331    zone_potentials.push_back(vp);
    276332 
    277333    // kaon potential (primitive)
    278     std::vector<G4double> kp(number_of_zones, -0.015);
     334    const std::vector<G4double> kp(number_of_zones, -0.015);
    279335    zone_potentials.push_back(kp);
    280336
    281337    // hyperon potential (primitive)
    282     std::vector<G4double> hp(number_of_zones, 0.03);
     338    const std::vector<G4double> hp(number_of_zones, 0.03);
    283339    zone_potentials.push_back(hp);
    284340  }
    285341
    286342  nuclei_radius = zone_radii[zone_radii.size() - 1];
    287 
    288   /*
    289   // Print nuclear radii and densities
    290   G4cout << " For A = " << a << " zone radii = ";
    291   for (G4int i = 0; i < number_of_zones; i++) G4cout << zone_radii[i] << "  ";
    292   G4cout << "  " << G4endl;
    293 
    294   G4cout << " proton densities: ";
    295   for (G4int i = 0; i < number_of_zones; i++)
    296      G4cout << nucleon_densities[0][i] << "  ";
    297   G4cout << G4endl;
    298 
    299   G4cout << " neutron densities: ";
    300   for (G4int i = 0; i < number_of_zones; i++)
    301      G4cout << nucleon_densities[1][i] << "  ";
    302   G4cout << G4endl;
    303 
    304   G4cout << " protons per shell " ;
    305   G4double rinner = 0.0;
    306   G4double router = 0.0;
    307   G4double shellVolume = 0.0;
    308   for (G4int i = 0; i < number_of_zones; i++) {  // loop over zones
    309     router = zone_radii[i];
    310     shellVolume = piTimes4thirds*(router*router*router - rinner*rinner*rinner);
    311     G4cout << G4lrint(shellVolume*nucleon_densities[0][i]) << "  ";
    312     rinner = router;
    313   }
    314   G4cout << G4endl;
    315 
    316   G4cout << " neutrons per shell " ;
    317   rinner = 0.0;
    318   router = 0.0;
    319   shellVolume = 0.0;
    320   for (G4int i = 0; i < number_of_zones; i++) {  // loop over zones
    321     router = zone_radii[i];
    322     shellVolume = piTimes4thirds*(router*router*router - rinner*rinner*rinner);
    323     G4cout << G4lrint(shellVolume*nucleon_densities[1][i]) << "  ";
    324     rinner = router;
    325   }
    326   G4cout << G4endl;
    327   */
    328343}
    329344
     
    345360G4NucleiModel::volNumInt(G4double r1, G4double r2,
    346361                         G4double, G4double d1) const {
    347 
    348   if (verboseLevel > 3) {
     362  if (verboseLevel > 1) {
    349363    G4cout << " >>> G4NucleiModel::volNumInt" << G4endl;
    350364  }
     
    373387      r += dr1;
    374388      fi += r * (r + d2) / (1.0 + std::exp(r));
    375     };
     389    }
    376390
    377391    fun = 0.5 * fun1 + fi * dr;
     
    398412G4NucleiModel::volNumInt1(G4double r1, G4double r2,
    399413                          G4double cu2) const {
    400   if (verboseLevel > 3) {
     414  if (verboseLevel > 1) {
    401415    G4cout << " >>> G4NucleiModel::volNumInt1" << G4endl;
    402416  }
     
    447461
    448462void G4NucleiModel::printModel() const {
    449 
    450   if (verboseLevel > 3) {
     463  if (verboseLevel > 1) {
    451464    G4cout << " >>> G4NucleiModel::printModel" << G4endl;
    452465  }
    453466
    454467  G4cout << " nuclei model for A " << A << " Z " << Z << G4endl
    455          << " proton binding energy " << binding_energies[0] <<
    456     " neutron binding energy " << binding_energies[1] << G4endl
    457          << " Nculei radius " << nuclei_radius << " number of zones " <<
    458     number_of_zones << G4endl;
     468         << " proton binding energy " << binding_energies[0]
     469         << " neutron binding energy " << binding_energies[1] << G4endl
     470         << " Nuclei radius " << nuclei_radius << " number of zones "
     471         << number_of_zones << G4endl;
    459472
    460473  for (G4int i = 0; i < number_of_zones; i++)
    461 
    462474    G4cout << " zone " << i+1 << " radius " << zone_radii[i] << G4endl
    463475           << " protons: density " << getDensity(1,i) << " PF " <<
     
    480492G4InuclElementaryParticle
    481493G4NucleiModel::generateNucleon(G4int type, G4int zone) const {
    482   if (verboseLevel > 3) {
     494  if (verboseLevel > 1) {
    483495    G4cout << " >>> G4NucleiModel::generateNucleon" << G4endl;
    484496  }
     
    492504G4NucleiModel::generateQuasiDeutron(G4int type1, G4int type2,
    493505                                    G4int zone) const {
    494 
    495   if (verboseLevel > 3) {
     506  if (verboseLevel > 1) {
    496507    G4cout << " >>> G4NucleiModel::generateQuasiDeutron" << G4endl;
    497508  }
     
    518529void
    519530G4NucleiModel::generateInteractionPartners(G4CascadParticle& cparticle) {
    520   if (verboseLevel > 3) {
     531  if (verboseLevel > 1) {
    521532    G4cout << " >>> G4NucleiModel::generateInteractionPartners" << G4endl;
    522533  }
    523534
    524   const G4double pi4by3 = 4.1887903; // 4 Pi / 3
     535  const G4double pi4by3 = 4.1887903; // 4 Pi / 3        FIXME!
    525536  const G4double small = 1.0e-10;
    526537  const G4double huge_num = 50.0;
     
    556567    r_in = zone_radii[zone - 1];
    557568    r_out = zone_radii[zone];
    558   }; 
     569  } 
    559570
    560571  G4double path = cparticle.getPathToTheNextZone(r_in, r_out);
    561572
    562   if (verboseLevel > 2){
     573  if (verboseLevel > 2) {
    563574    G4cout << " r_in " << r_in << " r_out " << r_out << " path " << path << G4endl;
    564575  }
    565576
    566   if (path < -small) { // something wrong
     577  if (path < -small) {                  // something wrong
     578    G4cerr << " generateInteractionPartners-> negative path length" << G4endl;
    567579    return;
    568 
    569   } else if (std::fabs(path) < small) { // just on the boundary
    570     path = 0.0;
    571 
    572     G4InuclElementaryParticle particle; // Dummy -- no type or momentum
    573     thePartners.push_back(partner(particle, path));
    574 
    575   } else { // normal case 
    576     G4LorentzConvertor dummy_convertor;
    577     dummy_convertor.setBullet(pmom, pmass);
    578  
    579     for (G4int ip = 1; ip < 3; ip++) {
    580       G4InuclElementaryParticle particle = generateNucleon(ip, zone);
    581       dummy_convertor.setTarget(particle.getMomentum(), particle.getMass());
     580  }
     581
     582  if (std::fabs(path) < small) {        // just on the boundary
     583    if (verboseLevel > 3)
     584      G4cout << " generateInteractionPartners-> zero path" << G4endl;
     585
     586    thePartners.push_back(partner());   // Dummy list terminator with zero path
     587    return;
     588  }
     589
     590  G4LorentzConvertor dummy_convertor;
     591  dummy_convertor.setBullet(pmom, pmass);
     592
     593  for (G4int ip = 1; ip < 3; ip++) {
     594    // Only process nucleons which remain active in target
     595    if (ip==1 && protonNumberCurrent < 1) continue;
     596    if (ip==2 && neutronNumberCurrent < 1) continue;
     597
     598    // All nucleons are assumed to be at rest when colliding
     599    G4InuclElementaryParticle particle = generateNucleon(ip, zone);
     600    dummy_convertor.setTarget(particle.getMomentum(), particle.getMass());
     601    G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
     602   
     603    G4double csec = totalCrossSection(ekin, ptype * ip);
     604   
     605    if(verboseLevel > 2) {
     606      G4cout << " ip " << ip << " ekin " << ekin << " csec " << csec << G4endl;
     607    }
     608   
     609    G4double dens = nucleon_densities[ip - 1][zone];
     610    G4double rat = getRatio(ip);
     611    G4double pw = -path * dens * csec * rat;
     612   
     613    if (pw < -huge_num) pw = -huge_num;
     614    pw = 1.0 - std::exp(pw);
     615   
     616    if (verboseLevel > 2) {
     617      G4cout << " pw " << pw << " rat " << rat << G4endl;
     618    }
     619   
     620    G4double spath = path;
     621   
     622    if (inuclRndm() < pw) {
     623      spath = -1.0 / dens / csec / rat * std::log(1.0 - pw * inuclRndm());
     624      if (cparticle.young(young_cut, spath)) spath = path;
     625     
     626      if (verboseLevel > 2) {
     627        G4cout << " ip " << ip << " spath " << spath << G4endl;
     628      }
     629    }
     630
     631    if (spath < path) {
     632      if (verboseLevel > 3) {
     633        G4cout << " adding partner[" << thePartners.size() << "]: ";
     634        particle.printParticle();
     635      }
     636      thePartners.push_back(partner(particle, spath));
     637    }
     638  } 
     639 
     640  if (verboseLevel > 2) {
     641    G4cout << " after nucleons " << thePartners.size() << " path " << path << G4endl;
     642  }
     643 
     644  if (cparticle.getParticle().pion()) { // absorption possible
     645    if (verboseLevel > 2) {
     646      G4cout << " trying quasi-deuterons with bullet: ";
     647      cparticle.getParticle().printParticle();
     648    }
     649
     650    // Initialize buffers for quasi-deuteron results
     651    qdeutrons.clear();
     652    acsecs.clear();
     653
     654    G4double tot_abs_csec = 0.0;
     655    G4double abs_sec;
     656    G4double vol = zone_radii[zone]*zone_radii[zone]*zone_radii[zone];
     657   
     658    if (zone > 0) vol -= zone_radii[zone-1]*zone_radii[zone-1]*zone_radii[zone-1];
     659    vol *= pi4by3;
     660   
     661    G4double rat  = getRatio(1);
     662    G4double rat1 = getRatio(2);
     663
     664    // FIXME:  Shouldn't be creating zero-cross-section states!
     665
     666    // Proton-proton state interacts with pi-, pi0 only
     667    G4InuclElementaryParticle ppd = generateQuasiDeutron(1, 1, zone);
     668   
     669    if (protonNumberCurrent < 2 || !(ptype == pi0 || ptype == pim)) {
     670      abs_sec = 0.0;
     671    } else {
     672      dummy_convertor.setTarget(ppd.getMomentum(), ppd.getMass());
     673     
    582674      G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
    583 
    584       // Total cross section converted from mb to fm**2
    585       G4double csec = totalCrossSection(ekin, ptype * ip);
    586 
    587       if(verboseLevel > 2){
    588         G4cout << " ip " << ip << " ekin " << ekin << " csec " << csec << G4endl;
     675     
     676      if (verboseLevel > 2) {
     677        G4cout << " ptype=" << ptype << " using pp target" << G4endl;
     678        ppd.printParticle();
    589679      }
    590 
    591       G4double dens = nucleon_densities[ip - 1][zone];
    592       G4double rat = getRatio(ip);
    593       G4double pw = -path * dens * csec * rat;
    594 
    595       if (pw < -huge_num) pw = -huge_num;
    596       pw = 1.0 - std::exp(pw);
    597 
    598       if (verboseLevel > 2){
    599         G4cout << " pw " << pw << " rat " << rat << G4endl;
    600       }
    601 
    602       G4double spath = path;
    603 
    604       if (inuclRndm() < pw) {
    605         spath = -1.0 / dens / csec / rat * std::log(1.0 - pw * inuclRndm());
    606         if (cparticle.young(young_cut, spath)) spath = path;
    607 
    608         if (verboseLevel > 2){
    609           G4cout << " ip " << ip << " spath " << spath << G4endl;
    610         }
    611 
    612       };
    613       if (spath < path) thePartners.push_back(partner(particle, spath));
    614     }; 
    615 
    616     if (verboseLevel > 2){
    617       G4cout << " after nucleons " << thePartners.size() << " path " << path << G4endl;
    618     }
    619 
    620     if (cparticle.getParticle().pion()) { // absorption possible
    621       if (verboseLevel > 2) {
    622         G4cout << " trying quasi-deuterons with bullet: ";
    623         cparticle.getParticle().printParticle();
    624       }
    625 
    626       std::vector<G4InuclElementaryParticle> qdeutrons(3);
    627       std::vector<G4double> acsecs(3);
    628 
    629       G4double tot_abs_csec = 0.0;
    630       G4double abs_sec;
    631       G4double vol = zone_radii[zone]*zone_radii[zone]*zone_radii[zone];
    632 
    633       if (zone > 0) vol -= zone_radii[zone-1]*zone_radii[zone-1]*zone_radii[zone-1];
    634       vol *= pi4by3;
    635 
    636       G4double rat  = getRatio(1);
    637       G4double rat1 = getRatio(2);
    638 
    639       G4InuclElementaryParticle ppd = generateQuasiDeutron(1, 1, zone);
    640 
    641       if (ptype == 7 || ptype == 5) {
    642         dummy_convertor.setTarget(ppd.getMomentum(), ppd.getMass());
    643 
    644         G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
    645 
    646         if (verboseLevel > 2) {
    647           G4cout << " ptype=" << ptype << " using pp target" << G4endl;
    648           ppd.printParticle();
    649         }
    650 
    651         abs_sec = absorptionCrossSection(ekin, ptype);
    652         abs_sec *= nucleon_densities[0][zone] * nucleon_densities[0][zone]*
    653           rat * rat * vol;
    654 
    655       } else {
    656         abs_sec = 0.0;
    657       };
    658 
    659       // abs_sec = 0.0;
    660       tot_abs_csec += abs_sec;
    661       acsecs.push_back(abs_sec);
    662       qdeutrons.push_back(ppd);
    663 
    664       G4InuclElementaryParticle npd = generateQuasiDeutron(1, 2, zone);
    665 
     680     
     681      abs_sec = absorptionCrossSection(ekin, ptype);
     682      abs_sec *= nucleon_densities[0][zone] * nucleon_densities[0][zone]*
     683        rat * rat * vol;
     684    }
     685   
     686    tot_abs_csec += abs_sec;
     687    acsecs.push_back(abs_sec);
     688    qdeutrons.push_back(ppd);
     689   
     690    // Proton-neutron state interacts with any pion type
     691    G4InuclElementaryParticle npd = generateQuasiDeutron(1, 2, zone);
     692
     693    if (protonNumberCurrent < 1 || neutronNumberCurrent < 1) {
     694      abs_sec = 0.0;
     695    } else {
    666696      dummy_convertor.setTarget(npd.getMomentum(), npd.getMass());
    667 
     697     
    668698      G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
    669 
     699     
    670700      if (verboseLevel > 2) {
    671701        G4cout << " using np target" << G4endl;
    672702        npd.printParticle();
    673703      }
    674 
     704     
    675705      abs_sec = absorptionCrossSection(ekin, ptype);
    676706      abs_sec *= pn_spec * nucleon_densities[0][zone] * nucleon_densities[1][zone] *
    677         rat * rat1 * vol;
    678       tot_abs_csec += abs_sec;
    679       acsecs.push_back(abs_sec);
    680       qdeutrons.push_back(npd);
    681 
    682       G4InuclElementaryParticle nnd = generateQuasiDeutron(2, 2, zone);
    683 
    684       if (ptype == 7 || ptype == 3) {
    685         dummy_convertor.setTarget(nnd.getMomentum(), nnd.getMass());
    686 
    687         G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
    688 
    689         if (verboseLevel > 2) {
    690           G4cout << " ptype=" << ptype << " using nn target" << G4endl;
    691           nnd.printParticle();
     707        rat * rat1 * vol;
     708    }
     709
     710    tot_abs_csec += abs_sec;
     711    acsecs.push_back(abs_sec);
     712    qdeutrons.push_back(npd);
     713
     714    // Neutron-neutron state interacts with pi+, pi0 only
     715    G4InuclElementaryParticle nnd = generateQuasiDeutron(2, 2, zone);
     716   
     717    if (neutronNumberCurrent < 2 || !(ptype == pi0 || ptype == pip)) {
     718      abs_sec = 0.0;
     719    } else {
     720      dummy_convertor.setTarget(nnd.getMomentum(), nnd.getMass());
     721     
     722      G4double ekin = dummy_convertor.getKinEnergyInTheTRS();
     723     
     724      if (verboseLevel > 2) {
     725        G4cout << " ptype=" << ptype << " using nn target" << G4endl;
     726        nnd.printParticle();
     727      }
     728     
     729      abs_sec = absorptionCrossSection(ekin, ptype);
     730      abs_sec *= nucleon_densities[1][zone] * nucleon_densities[1][zone] *
     731        rat1 * rat1 * vol;
     732    }
     733
     734    tot_abs_csec += abs_sec;
     735    acsecs.push_back(abs_sec);
     736    qdeutrons.push_back(nnd);
     737
     738    // Select quasideuteron interaction from non-zero cross-section choices
     739    if (verboseLevel > 2){
     740      G4cout << " rod1 " << acsecs[0] << " rod2 " << acsecs[1] 
     741             << " rod3 " << acsecs[2] << G4endl;
     742    }
     743   
     744    if (tot_abs_csec > small) {
     745      G4double pw = -path * tot_abs_csec;
     746     
     747      if (pw < -huge_num) pw = -huge_num;
     748      pw = 1.0 - std::exp(pw);
     749     
     750      if (verboseLevel > 2){
     751        G4cout << " pw " << pw << G4endl;
     752      }
     753     
     754      G4double apath = path;
     755     
     756      if (inuclRndm() < pw)
     757        apath = -1.0 / tot_abs_csec * std::log(1.0 - pw * inuclRndm());
     758     
     759      if (cparticle.young(young_cut, apath)) apath = path; 
     760     
     761      if(verboseLevel > 2){
     762        G4cout << " apath " << apath << " path " << path << G4endl;
     763      }
     764     
     765      if (apath < path) {       // choose the qdeutron
     766        G4double sl = inuclRndm() * tot_abs_csec;
     767        G4double as = 0.0;
     768       
     769        for (G4int i = 0; i < 3; i++) {
     770          as += acsecs[i];
     771          if (sl < as) {
     772            if (verboseLevel > 2) G4cout << " deut type " << i << G4endl;
     773            thePartners.push_back(partner(qdeutrons[i], apath));
     774            break;
     775          }
    692776        }
    693 
    694         abs_sec = absorptionCrossSection(ekin, ptype);
    695         abs_sec *= nucleon_densities[1][zone] * nucleon_densities[1][zone] *
    696           rat1 * rat1 * vol;
    697 
    698       } else {
    699         abs_sec = 0.0;
    700       };
    701 
    702       // abs_sec = 0.0;
    703       tot_abs_csec += abs_sec;
    704       acsecs.push_back(abs_sec);
    705       qdeutrons.push_back(nnd);
    706 
    707       if (verboseLevel > 2){
    708         G4cout << " rod1 " << acsecs[0] << " rod2 " << acsecs[1] 
    709                << " rod3 " << acsecs[2] << G4endl;
    710       }
    711 
    712       if (tot_abs_csec > small) {
    713      
    714         G4double pw = -path * tot_abs_csec;
    715 
    716         if (pw < -huge_num) pw = -huge_num;
    717         pw = 1.0 - std::exp(pw);
    718 
    719         if (verboseLevel > 2){
    720           G4cout << " pw " << pw << G4endl;
    721         }
    722 
    723         G4double apath = path;
    724 
    725         if (inuclRndm() < pw)
    726           apath = -1.0 / tot_abs_csec * std::log(1.0 - pw * inuclRndm());
    727 
    728         if (cparticle.young(young_cut, apath)) apath = path; 
    729 
    730         if(verboseLevel > 2){
    731           G4cout << " apath " << apath << " path " << path << G4endl;
    732         }
    733 
    734         if (apath < path) { // chose the qdeutron
    735 
    736           G4double sl = inuclRndm() * tot_abs_csec;
    737           G4double as = 0.0;
    738 
    739           for (G4int i = 0; i < 3; i++) {
    740             as += acsecs[i];
    741 
    742             if (sl < as) {
    743 
    744               if (verboseLevel > 2){
    745                 G4cout << " deut type " << i << G4endl;
    746               }
    747 
    748               thePartners.push_back(partner(qdeutrons[i], apath));
    749 
    750               break;
    751             };
    752           };
    753         };   
    754       };
    755     }; 
    756 
    757     if(verboseLevel > 2){
    758       G4cout << " after deutrons " << thePartners.size() << G4endl;
    759     }
    760  
    761     if (thePartners.size() > 1) {               // Sort list by path length
    762       std::sort(thePartners.begin(), thePartners.end(), sortPartners);
    763     }
    764 
    765     G4InuclElementaryParticle particle;         // Dummy for end of list
    766     thePartners.push_back(partner(particle, path));
    767   }
    768  
    769   return;
     777      }   
     778    }
     779  } 
     780 
     781  if (verboseLevel > 2) {
     782    G4cout << " after deuterons " << thePartners.size() << " partners"
     783           << G4endl;
     784  }
     785 
     786  if (thePartners.size() > 1) {         // Sort list by path length
     787    std::sort(thePartners.begin(), thePartners.end(), sortPartners);
     788  }
     789 
     790  G4InuclElementaryParticle particle;           // Total path at end of list
     791  thePartners.push_back(partner(particle, path));
    770792}
    771793
     
    774796G4NucleiModel::generateParticleFate(G4CascadParticle& cparticle,
    775797                                    G4ElementaryParticleCollider* theElementaryParticleCollider) {
    776   if (verboseLevel > 3)
     798  if (verboseLevel > 1)
    777799    G4cout << " >>> G4NucleiModel::generateParticleFate" << G4endl;
    778800
     801  if (verboseLevel > 2) {
     802    G4cout << " cparticle: ";
     803    cparticle.print();
     804  }
     805
     806  // Create four-vector checking
     807#ifdef G4CASCADE_CHECK_ECONS
     808  G4CascadeCheckBalance balance(0.005, 0.01, "G4NucleiModel");  // Second arg is in GeV
     809  balance.setVerboseLevel(verboseLevel);
     810#endif
     811
    779812  outgoing_cparticles.clear();          // Clear return buffer for this event
    780 
    781813  generateInteractionPartners(cparticle);       // Fills "thePartners" data
    782814
    783815  if (thePartners.empty()) { // smth. is wrong -> needs special treatment
    784     G4cout << " generateParticleFate-> can not be here " << G4endl;
     816    G4cerr << " generateParticleFate-> got empty interaction-partners list "
     817           << G4endl;
    785818    return outgoing_cparticles;
    786819  }
    787820
    788   G4int npart = thePartners.size();
    789 
    790   if (npart == 1) { // cparticle is on the next zone entry
    791     // need to go here if particle outside nucleus ?
    792     //
     821  G4int npart = thePartners.size();     // Last item is a total-path placeholder
     822
     823  if (npart == 1) {             // cparticle is on the next zone entry
    793824    cparticle.propagateAlongThePath(thePartners[0].second);
    794825    cparticle.incrementCurrentPath(thePartners[0].second);
     
    796827    outgoing_cparticles.push_back(cparticle);
    797828   
    798     if (verboseLevel > 2){
     829    if (verboseLevel > 2) {
    799830      G4cout << " next zone " << G4endl;
    800831      cparticle.print();
    801832    }
    802    
    803   } else { // there are possible interactions
    804    
     833  } else {                      // there are possible interactions
     834    if (verboseLevel > 1)
     835      G4cout << " processing " << npart-1 << " possible interactions" << G4endl;
     836
    805837    G4ThreeVector old_position = cparticle.getPosition();
    806    
    807     G4InuclElementaryParticle bullet = cparticle.getParticle();
    808    
     838    G4InuclElementaryParticle& bullet = cparticle.getParticle();
    809839    G4bool no_interaction = true;
    810    
    811840    G4int zone = cparticle.getCurrentZone();
    812841   
    813     G4CollisionOutput output;
    814 
    815     for (G4int i = 0; i < npart - 1; i++) {
     842    for (G4int i=0; i<npart-1; i++) {   // Last item is a total-path placeholder
    816843      if (i > 0) cparticle.updatePosition(old_position);
    817844     
    818       G4InuclElementaryParticle target = thePartners[i].first;
    819      
    820       if (verboseLevel > 2){
    821         if (target.quasi_deutron())
    822           G4cout << " try absorption: target " << target.type() << " bullet " <<
    823             bullet.type() << G4endl;
     845      G4InuclElementaryParticle& target = thePartners[i].first;
     846
     847      if (verboseLevel > 3) {
     848        if (target.quasi_deutron()) G4cout << " try absorption: ";
     849        G4cout << " target " << target.type() << " bullet " << bullet.type()
     850              << G4endl;
    824851      }
    825852
    826       output.reset();
    827       theElementaryParticleCollider->collide(&bullet, &target, output);
    828      
    829       if (verboseLevel > 2) output.printCollisionOutput();
     853      EPCoutput.reset();
     854      theElementaryParticleCollider->collide(&bullet, &target, EPCoutput);
     855     
     856      if (verboseLevel > 2) {
     857        EPCoutput.printCollisionOutput();
     858#ifdef G4CASCADE_CHECK_ECONS
     859        balance.collide(&bullet, &target, EPCoutput);
     860        balance.okay();         // Do checks, but ignore result
     861#endif
     862      }
    830863
    831864      // Don't need to copy list, as "output" isn't changed again below
    832865      const std::vector<G4InuclElementaryParticle>& outgoing_particles =
    833         output.getOutgoingParticles();
    834      
    835       if (passFermi(outgoing_particles, zone)) { // interaction
    836         cparticle.propagateAlongThePath(thePartners[i].second);
    837         G4ThreeVector new_position = cparticle.getPosition();
    838        
    839         for (G4int ip = 0; ip < G4int(outgoing_particles.size()); ip++) {
    840           G4CascadParticle temp(outgoing_particles[ip], new_position, zone, 0.0, 0);
    841           outgoing_cparticles.push_back(temp);
    842         }
    843        
    844         no_interaction = false;
    845         current_nucl1 = 0;
    846         current_nucl2 = 0;
    847 #ifdef CHC_CHECK
     866        EPCoutput.getOutgoingParticles();
     867     
     868      if (!passFermi(outgoing_particles, zone)) continue; // Interaction fails
     869
     870      // Successful interaction, add results to output list
     871      cparticle.propagateAlongThePath(thePartners[i].second);
     872      G4ThreeVector new_position = cparticle.getPosition();
     873
     874      if (verboseLevel > 2)
     875        G4cout << " adding " << outgoing_particles.size()
     876               << " output particles" << G4endl;
     877     
     878      for (G4int ip = 0; ip < G4int(outgoing_particles.size()); ip++) {
     879        G4CascadParticle temp(outgoing_particles[ip], new_position, zone, 0.0, 0);
     880        outgoing_cparticles.push_back(temp);
     881      }
     882     
     883      no_interaction = false;
     884      current_nucl1 = 0;
     885      current_nucl2 = 0;
     886     
     887#ifdef G4CASCADE_DEBUG_CHARGE
     888      {
    848889        G4double out_charge = 0.0;
    849890       
     
    851892          out_charge += outgoing_particles[ip].getCharge();
    852893       
    853         G4cout << " multiplicity " << outgoing_particles.size() <<
    854           " bul type " << bullet.type() << " targ type " << target.type() <<
    855           G4endl << " initial charge " << bullet.getCharge() + target.getCharge()
     894        G4cout << " multiplicity " << outgoing_particles.size()
     895               << " bul type " << bullet.type()
     896               << " targ type " << target.type()
     897               << "\n initial charge "
     898               << bullet.getCharge() + target.getCharge()
    856899               << " out charge " << out_charge << G4endl; 
     900      }
    857901#endif
    858        
    859         if (verboseLevel > 2){
    860           G4cout << " partner type " << target.type() << G4endl;
    861         }
    862        
    863         if (target.nucleon()) {
    864           current_nucl1 = target.type();
    865          
    866         } else {
    867           if (verboseLevel > 2) G4cout << " good absorption " << G4endl;
    868          
    869           current_nucl1 = (target.type() - 100) / 10;
    870           current_nucl2 = target.type() - 100 - 10 * current_nucl1;
    871         }   
    872        
    873         if (current_nucl1 == 1) {
    874           protonNumberCurrent -= 1.0;
    875          
    876         } else {
    877           neutronNumberCurrent -= 1.0;
    878         };
    879        
    880         if (current_nucl2 == 1) {
    881           protonNumberCurrent -= 1.0;
    882          
    883         } else if(current_nucl2 == 2) {
    884           neutronNumberCurrent -= 1.0;
    885         };
    886        
    887         break;
    888       };
    889     }  // loop over partners
    890    
    891     if (no_interaction) { // still no interactions
     902     
     903      if (verboseLevel > 2)
     904        G4cout << " partner type " << target.type() << G4endl;
     905     
     906      if (target.nucleon()) {
     907        current_nucl1 = target.type();
     908      } else {
     909        if (verboseLevel > 2) G4cout << " good absorption " << G4endl;
     910        current_nucl1 = (target.type() - 100) / 10;
     911        current_nucl2 = target.type() - 100 - 10 * current_nucl1;
     912      }   
     913     
     914      if (current_nucl1 == 1) {
     915        if (verboseLevel > 3) G4cout << " decrement proton count" << G4endl;
     916        protonNumberCurrent--;
     917      } else {
     918        if (verboseLevel > 3) G4cout << " decrement neutron count" << G4endl;
     919        neutronNumberCurrent--;
     920      }
     921     
     922      if (current_nucl2 == 1) {
     923        if (verboseLevel > 3) G4cout << " decrement proton count" << G4endl;
     924        protonNumberCurrent--;
     925      } else if (current_nucl2 == 2) {
     926        if (verboseLevel > 3) G4cout << " decrement neutron count" << G4endl;
     927        neutronNumberCurrent--;
     928      }
     929     
     930      break;
     931    }           // loop over partners
     932   
     933    if (no_interaction) {               // still no interactions
     934      if (verboseLevel > 1) G4cout << " no interaction " << G4endl;
     935
     936      // For conservation checking (below), get particle before updating
     937      static G4InuclElementaryParticle prescatCP;       // Avoid memory churn
     938      prescatCP = cparticle.getParticle();
     939
     940      // Last "partner" is just a total-path placeholder
    892941      cparticle.updatePosition(old_position);
    893       cparticle.propagateAlongThePath(thePartners[npart - 1].second);
    894       cparticle.incrementCurrentPath(thePartners[npart - 1].second);
     942      cparticle.propagateAlongThePath(thePartners[npart-1].second);
     943      cparticle.incrementCurrentPath(thePartners[npart-1].second);
    895944      boundaryTransition(cparticle);
    896945      outgoing_cparticles.push_back(cparticle);
    897     };
    898   };
     946
     947      // Check conservation for simple scattering (ignore target nucleus!)
     948#ifdef G4CASCADE_CHECK_ECONS
     949      if (verboseLevel > 2) {
     950        balance.collide(&prescatCP, 0, outgoing_cparticles);
     951        balance.okay();         // Report violations, but don't act on them
     952      }
     953#endif
     954    }
     955  }     // if (npart == 1) [else]
    899956
    900957  return outgoing_cparticles;
     
    903960G4bool G4NucleiModel::passFermi(const std::vector<G4InuclElementaryParticle>& particles,
    904961                                G4int zone) {
     962  if (verboseLevel > 1) {
     963    G4cout << " >>> G4NucleiModel::passFermi" << G4endl;
     964  }
     965
     966  // Only check Fermi momenta for nucleons
     967  for (G4int i = 0; i < G4int(particles.size()); i++) {
     968    if (!particles[i].nucleon()) continue;
     969
     970    G4int type   = particles[i].type();
     971    G4double mom = particles[i].getMomModule();
     972    G4double pf  = fermi_momenta[type-1][zone];
     973
     974    if (verboseLevel > 2)
     975      G4cout << " type " << type << " p " << mom << " pf " << pf << G4endl;
     976   
     977    if (mom < pf) {
     978        if (verboseLevel > 2) G4cout << " rejected by Fermi" << G4endl;
     979        return false;
     980    }
     981  }
     982  return true;
     983}
     984
     985void G4NucleiModel::boundaryTransition(G4CascadParticle& cparticle) {
     986  if (verboseLevel > 1) {
     987    G4cout << " >>> G4NucleiModel::boundaryTransition" << G4endl;
     988  }
     989
     990  G4int zone = cparticle.getCurrentZone();
     991
     992  if (cparticle.movingInsideNuclei() && zone == 0) {
     993    G4cerr << " boundaryTransition-> in zone 0 " << G4endl;
     994    return;
     995  }
     996
     997  G4LorentzVector mom = cparticle.getMomentum();
     998  G4ThreeVector pos = cparticle.getPosition();
     999 
     1000  G4int type = cparticle.getParticle().type();
     1001 
     1002  G4double pr = pos.dot(mom.vect());
     1003  G4double r = pos.mag();
     1004 
     1005  pr /= r;
     1006 
     1007  G4int next_zone = cparticle.movingInsideNuclei() ? zone - 1 : zone + 1;
     1008 
     1009  G4double dv = getPotential(type,zone) - getPotential(type, next_zone);
     1010  //    G4cout << "Potentials for type " << type << " = "
     1011  //           << getPotential(type,zone) << " , "
     1012  //       << getPotential(type,next_zone) << G4endl;
     1013 
     1014  G4double qv = dv * dv - 2.0 * dv * mom.e() + pr * pr;
     1015 
     1016  G4double p1r;
     1017 
    9051018  if (verboseLevel > 3) {
    906     G4cout << " >>> G4NucleiModel::passFermi" << G4endl;
    907   }
    908 
    909   for (G4int i = 0; i < G4int(particles.size()); i++) {
    910 
    911     if (particles[i].nucleon()) {
    912 
    913       if (verboseLevel > 2){
    914         G4cout << " type " << particles[i].type() << " p " << particles[i].getMomModule()
    915                << " pf " << fermi_momenta[particles[i].type() - 1][zone] << G4endl;
    916       }
    917 
    918       if (particles[i].getMomModule() < fermi_momenta[particles[i].type() - 1][zone]) {
    919 
    920         if (verboseLevel > 2) {
    921           G4cout << " rejected by fermi: type " << particles[i].type() <<
    922             " p " << particles[i].getMomModule() << G4endl;
    923         }
    924 
    925         return false;
    926       };
    927     };
    928   };
    929   return true;
    930 }
    931 
    932 void G4NucleiModel::boundaryTransition(G4CascadParticle& cparticle) {
    933 
     1019    G4cout << " type " << type << " zone " << zone << " next " << next_zone
     1020           << " qv " << qv << " dv " << dv << G4endl;
     1021  }
     1022
     1023  if (qv <= 0.0) {      // reflection
     1024    if (verboseLevel > 3) G4cout << " reflects off boundary" << G4endl;
     1025    p1r = -pr;
     1026    cparticle.incrementReflectionCounter();
     1027  } else {              // transition
     1028    if (verboseLevel > 3) G4cout << " passes thru boundary" << G4endl;
     1029    p1r = std::sqrt(qv);
     1030    if(pr < 0.0) p1r = -p1r;
     1031    cparticle.updateZone(next_zone);
     1032    cparticle.resetReflection();
     1033  }
     1034 
     1035  G4double prr = (p1r - pr) / r; 
     1036 
    9341037  if (verboseLevel > 3) {
    935     G4cout << " >>> G4NucleiModel::boundaryTransition" << G4endl;
    936   }
    937 
    938   G4int zone = cparticle.getCurrentZone();
    939 
    940   if (cparticle.movingInsideNuclei() && zone == 0) {
    941     G4cout << " boundaryTransition-> in zone 0 " << G4endl;
    942 
    943   } else {
    944     G4LorentzVector mom = cparticle.getMomentum();
    945     G4ThreeVector pos = cparticle.getPosition();
    946 
    947     G4int type = cparticle.getParticle().type();
    948 
    949     G4double pr = pos.dot(mom.vect());
    950     G4double r = pos.mag();
    951 
    952     pr /= r;
    953 
    954     G4int next_zone = cparticle.movingInsideNuclei() ? zone - 1 : zone + 1;
    955 
    956     G4double dv = getPotential(type,zone) - getPotential(type, next_zone);
    957     //    G4cout << "Potentials for type " << type << " = "
    958     //           << getPotential(type,zone) << " , "
    959     //     << getPotential(type,next_zone) << G4endl;
    960 
    961     G4double qv = dv * dv - 2.0 * dv * mom.e() + pr * pr;
    962 
    963     G4double p1r;
    964 
    965     if (verboseLevel > 2){
    966       G4cout << " type " << type << " zone " << zone
    967              << " next " << next_zone
    968              << " qv " << qv << " dv " << dv << G4endl;
    969     }
    970 
    971     if(qv <= 0.0) { // reflection
    972       p1r = -pr;
    973       cparticle.incrementReflectionCounter();
    974 
    975     } else { // transition
    976       p1r = std::sqrt(qv);
    977       if(pr < 0.0) p1r = -p1r;
    978       cparticle.updateZone(next_zone);
    979       cparticle.resetReflection();
    980     };
    981  
    982     G4double prr = (p1r - pr) / r; 
    983 
    984     mom.setVect(mom.vect() + pos*prr);
    985     cparticle.updateParticleMomentum(mom);
    986   };
     1038    G4cout << " prr " << prr << " delta px " << prr*pos.x() << " py "
     1039           << prr*pos.y()  << " pz " << prr*pos.z() << " mag "
     1040           << std::fabs(prr*r) << G4endl;
     1041  }
     1042
     1043  mom.setVect(mom.vect() + pos*prr);
     1044  cparticle.updateParticleMomentum(mom);
    9871045}
    9881046
    9891047G4bool G4NucleiModel::worthToPropagate(const G4CascadParticle& cparticle) const {
    990 
    991   if (verboseLevel > 3) {
     1048  if (verboseLevel > 1) {
    9921049    G4cout << " >>> G4NucleiModel::worthToPropagate" << G4endl;
    9931050  }
     
    10101067             << worth << G4endl;
    10111068    }
    1012   };
     1069  }
    10131070
    10141071  return worth;
    10151072}
    10161073
     1074
    10171075G4double G4NucleiModel::getRatio(G4int ip) const {
    1018 
    1019   if (verboseLevel > 3) {
     1076  if (verboseLevel > 1) {
    10201077    G4cout << " >>> G4NucleiModel::getRatio" << G4endl;
    10211078  }
    10221079
    1023   G4double rat;
    1024   //  G4double ratm;
    1025 
    1026   // Calculate number of protons and neutrons in local region
    1027   //  G4double Athird = G4cbrt(A);
    1028   //  G4double Nneut = Athird*(A-Z)/A;
    1029   //  G4double Nprot = Athird*Z/A;
    1030 
    1031   // Reduce number of
    10321080  if (ip == 1) {
     1081    if (verboseLevel > 2) {
     1082      G4cout << " current " << protonNumberCurrent << " inp " << protonNumber
     1083             << G4endl;
     1084    }
     1085    return G4double(protonNumberCurrent)/G4double(protonNumber);
     1086  }
     1087
     1088  if (ip == 2) {
    10331089    if (verboseLevel > 2){
    1034       G4cout << " current " << protonNumberCurrent << " inp " << protonNumber << G4endl;
    1035     }
    1036 
    1037     rat = protonNumberCurrent/protonNumber;
    1038 
    1039     // Calculate ratio modified for local region
    1040     //    G4double deltaP = protonNumber - protonNumberCurrent;
    1041     //    G4cout << " deltaP = " << deltaP << G4endl;
    1042     //    ratm = std::max(0.0, (Nprot - deltaP)/Nprot);
    1043 
    1044   } else {
    1045     if (verboseLevel > 2){
    1046       G4cout << " current " << neutronNumberCurrent << " inp " << neutronNumber << G4endl;
    1047     }
    1048 
    1049     rat = neutronNumberCurrent/neutronNumber;
    1050 
    1051     // Calculate ratio modified for local region
    1052     //    G4double deltaN = neutronNumber - neutronNumberCurrent;
    1053     //   G4cout << " deltaN = " << deltaN << G4endl;
    1054     //    ratm = std::max(0.0, (Nneut - deltaN)/Nneut);
    1055   }
    1056 
    1057   //  G4cout << " get ratio: ratm =  " << ratm << G4endl;
    1058   return rat;
    1059   //  return ratm;
    1060 }
    1061 
    1062 G4CascadParticle G4NucleiModel::initializeCascad(G4InuclElementaryParticle* particle) {
    1063 
    1064   if (verboseLevel > 3) {
    1065     G4cout << " >>> G4NucleiModel::initializeCascad(G4InuclElementaryParticle* particle)" << G4endl;
     1090      G4cout << " current " << neutronNumberCurrent << " inp " << neutronNumber
     1091             << G4endl;
     1092    }
     1093    return G4double(neutronNumberCurrent)/G4double(neutronNumber);
     1094  }
     1095
     1096  return 0.;
     1097}
     1098
     1099G4CascadParticle
     1100G4NucleiModel::initializeCascad(G4InuclElementaryParticle* particle) {
     1101  if (verboseLevel > 1) {
     1102    G4cout << " >>> G4NucleiModel::initializeCascad(particle)" << G4endl;
    10661103  }
    10671104
    10681105  const G4double large = 1000.0;
    10691106
    1070   G4double s1 = std::sqrt(inuclRndm());
    1071   G4double phi = randomPHI();
    1072   G4double rz = nuclei_radius * s1;
    1073 
    1074   G4ThreeVector pos(rz*std::cos(phi), rz*std::sin(phi),
    1075                     -nuclei_radius*std::sqrt(1.0 - s1*s1));
    1076  
     1107  // FIXME:  Previous version generated random sin(theta), then used -cos(theta)
     1108  //         Using generateWithRandomAngles changes result!
     1109  // G4ThreeVector pos = generateWithRandomAngles(nuclei_radius).vect();
     1110  G4double costh = std::sqrt(1.0 - inuclRndm());
     1111  G4ThreeVector pos = generateWithFixedTheta(-costh, nuclei_radius);
     1112
    10771113  G4CascadParticle cpart(*particle, pos, number_of_zones, large, 0);
    10781114
     
    10851121                                     G4InuclNuclei* target,
    10861122                                     modelLists& output) {
    1087 
    1088   if (verboseLevel > 3) {
    1089     G4cout << " >>> G4NucleiModel::initializeCascad(G4InuclNuclei* bullet, G4InuclNuclei* target)" << G4endl;
     1123  if (verboseLevel) {
     1124    G4cout << " >>> G4NucleiModel::initializeCascad(bullet,target,output)"
     1125          << G4endl;
    10901126  }
    10911127
     
    11101146
    11111147  // first decide whether it will be cascad or compound final nuclei
    1112   G4double ab = bullet->getA();
    1113   G4double zb = bullet->getZ();
    1114   G4double at = target->getA();
    1115   G4double zt = target->getZ();
     1148  G4int ab = bullet->getA();
     1149  G4int zb = bullet->getZ();
     1150  G4int at = target->getA();
     1151  G4int zt = target->getZ();
    11161152
    11171153  G4double massb = bullet->getMass();   // For creating LorentzVectors below
     
    11191155  if (ab < max_a_for_cascad) {
    11201156
    1121     G4double benb = 0.001 * G4NucleiProperties::GetBindingEnergy(G4lrint(ab), G4lrint(zb)) / ab;
    1122     G4double bent = 0.001 * G4NucleiProperties::GetBindingEnergy(G4lrint(at), G4lrint(zt)) / at;
     1157    G4double benb = 0.001 * bindingEnergy(ab,zb) / G4double(ab);
     1158    G4double bent = 0.001 * bindingEnergy(at,zt) / G4double(at);
    11231159    G4double ben = benb < bent ? bent : benb;
    11241160
     
    11281164      while (casparticles.size() == 0 && itryg < itry_max) {     
    11291165        itryg++;
    1130 
    1131         if(itryg > 0) particles.clear();
     1166        particles.clear();
    11321167     
    11331168        //    nucleons coordinates and momenta in nuclei rest frame
    1134         std::vector<G4ThreeVector> coordinates;
    1135         std::vector<G4LorentzVector> momentums;
     1169        coordinates.clear();
     1170        momentums.clear();
    11361171     
    1137         if (ab < 3.0) { // deutron, simplest case
     1172        if (ab < 3) { // deuteron, simplest case
    11381173          G4double r = 2.214 - 3.4208 * std::log(1.0 - 0.981 * inuclRndm());
    1139           G4double s = 2.0 * inuclRndm() - 1.0;
    1140           G4double r1 = r * std::sqrt(1.0 - s * s);
    1141           G4double phi = randomPHI();
    1142 
    1143           G4ThreeVector coord1(r1*std::cos(phi), r1*std::sin(phi), r*s);   
     1174          G4ThreeVector coord1 = generateWithRandomAngles(r).vect();
    11441175          coordinates.push_back(coord1);
    1145 
    1146           coord1 *= -1.;
    1147           coordinates.push_back(coord1);
     1176          coordinates.push_back(-coord1);
    11481177
    11491178          G4double p = 0.0;
     
    11571186            if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023e-4 * inuclRndm() &&
    11581187               p * r > 312.0) bad = false;
    1159           };
     1188          }
    11601189
    11611190          if (itry == itry_max)
     
    11761205          momentums.push_back(-mom);
    11771206        } else {
    1178           G4int ia = int(ab + 0.5);
    1179 
    11801207          G4ThreeVector coord1;
    11811208
     
    11841211          G4int itry = 0;
    11851212       
    1186           if (ab < 4.0) { // a == 3
     1213          if (ab == 3) {
    11871214            while (badco && itry < itry_max) {
    11881215              if (itry > 0) coordinates.clear();
     
    12101237                    }
    12111238                    break;
    1212                   };
    1213                 };
     1239                  }
     1240                }
    12141241
    12151242                if (itry1 == itry_max) { // bad case
     
    12171244                  coordinates.push_back(coord1);
    12181245                  break;
    1219                 };
    1220               };
     1246                }
     1247              }
    12211248
    12221249              coord1 = -coordinates[0] - coordinates[1];
     
    12411268
    12421269                    break;
    1243                   };     
    1244                 };
     1270                  }     
     1271                }
    12451272
    12461273                if (large_dist) break;
    1247               };
     1274              }
    12481275
    12491276              if(!large_dist) badco = false;
    12501277
    1251             };
     1278            }
    12521279
    12531280          } else { // a >= 4
     
    12641291              G4int i(0);
    12651292           
    1266               for (i = 0; i < ia-1; i++) {
     1293              for (i = 0; i < ab-1; i++) {
    12671294                G4int itry1 = 0;
    12681295                G4double s, u;
     
    12831310
    12841311                    break;
    1285                   };
    1286                 };
     1312                  }
     1313                }
    12871314
    12881315                if (itry1 == itry_max) { // bad case
     
    12901317                  coordinates.push_back(coord1);
    12911318                  break;
    1292                 };
    1293               };
     1319                }
     1320              }
    12941321
    12951322              coord1 *= 0.0;    // Cheap way to reset
    1296               for(G4int j = 0; j < ia -1; j++) coord1 -= coordinates[j];
     1323              for(G4int j = 0; j < ab -1; j++) coord1 -= coordinates[j];
    12971324
    12981325              coordinates.push_back(coord1);   
     
    13041331              G4bool large_dist = false;
    13051332
    1306               for (i = 0; i < ia-1; i++) {
    1307                 for (G4int j = i+1; j < ia; j++) {
     1333              for (i = 0; i < ab-1; i++) {
     1334                for (G4int j = i+1; j < ab; j++) {
    13081335             
    13091336                  G4double r2 = (coordinates[i]-coordinates[j]).mag2();
     
    13171344
    13181345                    break;
    1319                   };     
    1320                 };
     1346                  }     
     1347                }
    13211348
    13221349                if (large_dist) break;
    1323               };
     1350              }
    13241351
    13251352              if (!large_dist) badco = false;
    1326             };
    1327           };
     1353            }
     1354          }
    13281355
    13291356          if(badco) {
     
    13391366            G4LorentzVector mom;
    13401367            //G4bool badp = True;
    1341             G4int i(0);
    1342 
    1343             for (i = 0; i < ia - 1; i++) {
     1368
     1369            for (G4int i = 0; i < ab - 1; i++) {
    13441370              G4int itry = 0;
    13451371
     
    13551381
    13561382                  break;
    1357                 };
    1358               };
     1383                }
     1384              }
    13591385
    13601386              if(itry == itry_max) {
     
    13651391                particles.clear();
    13661392                return;
    1367               };
    1368 
    1369             };
     1393              }
     1394
     1395            }
    13701396            // last momentum
    13711397
    13721398            mom *= 0.;          // Cheap way to reset
    1373             for(G4int j=0; j< ia-1; j++) mom -= momentums[j];
     1399            mom.setE(bullet->getEnergy()+target->getEnergy());
     1400
     1401            for(G4int j=0; j< ab-1; j++) mom -= momentums[j];
    13741402
    13751403            momentums.push_back(mom);
    1376           };
     1404          }
    13771405        }
    13781406 
     
    13851413
    13861414          if(rp > rb) rb = rp;
    1387         };
     1415        }
    13881416
    13891417        // nuclei i.p. as a whole
     
    13961424        for (i = 0; i < G4int(coordinates.size()); i++) {
    13971425          coordinates[i] += global_pos;
    1398         }; 
     1426        } 
    13991427
    14001428        // all nucleons at rest
    1401         std::vector<G4InuclElementaryParticle> raw_particles;
    1402         G4int ia = G4int(ab + 0.5);
    1403         G4int iz = G4int(zb + 0.5);
    1404 
    1405         for (G4int ipa = 0; ipa < ia; ipa++) {
    1406           G4int knd = ipa < iz ? 1 : 2;
     1429        raw_particles.clear();
     1430
     1431        for (G4int ipa = 0; ipa < ab; ipa++) {
     1432          G4int knd = ipa < zb ? 1 : 2;
    14071433          raw_particles.push_back(G4InuclElementaryParticle(momentums[ipa], knd));
    1408         };
     1434        }
    14091435     
    14101436        G4InuclElementaryParticle dummy(small_ekin, 1);
    1411         G4LorentzConvertor toTheBulletRestFrame;
    1412         toTheBulletRestFrame.setBullet(dummy.getMomentum(), dummy.getMass());
    1413         toTheBulletRestFrame.setTarget(bullet->getMomentum(),bullet->getMass());
     1437        G4LorentzConvertor toTheBulletRestFrame(&dummy, bullet);
    14141438        toTheBulletRestFrame.toTheTargetRestFrame();
    14151439
     
    14181442        for (ipart = raw_particles.begin(); ipart != raw_particles.end(); ipart++) {
    14191443          ipart->setMomentum(toTheBulletRestFrame.backToTheLab(ipart->getMomentum()));
    1420         };
     1444        }
    14211445
    14221446        // fill cascad particles and outgoing particles
     
    14371461              if(t1 > 0.0) {
    14381462                if(coordinates[ip].z() + mom.z() * t1 / pmod <= 0.0) tr = t1;
    1439               };
     1463              }
    14401464
    14411465              if(tr < 0.0 && t2 > 0.0) {
    14421466
    14431467                if(coordinates[ip].z() + mom.z() * t2 / pmod <= 0.0) tr = t2;
    1444               };
     1468              }
    14451469
    14461470            } else {
     
    14481472
    14491473                if(coordinates[ip].z() + mom.z() * t2 / pmod <= 0.0) tr = t2;
    1450               };
     1474              }
    14511475
    14521476              if(tr < 0.0 && t1 > 0.0) {
    14531477                if(coordinates[ip].z() + mom.z() * t1 / pmod <= 0.0) tr = t1;
    1454               };
    1455             };
    1456 
    1457           };
     1478              }
     1479            }
     1480
     1481          }
    14581482
    14591483          if(tr >= 0.0) { // cascad particle
    1460             coordinates[ip] += mom*tr / pmod;
     1484            coordinates[ip] += mom.vect()*tr / pmod;
    14611485            casparticles.push_back(G4CascadParticle(raw_particles[ip],
    14621486                                                    coordinates[ip],
     
    14651489          } else {
    14661490            particles.push_back(raw_particles[ip]);
    1467           };
    1468         };
    1469       };   
     1491          }
     1492        }
     1493      }   
    14701494
    14711495      if(casparticles.size() == 0) {
     
    14741498        G4cout << " can not generate proper distribution for " << itry_max
    14751499               << " steps " << G4endl;
    1476       };   
    1477     };
    1478   };
     1500      }   
     1501    }
     1502  }
    14791503
    14801504  if(verboseLevel > 2){
     
    15091533  } else if (ke < 1.0) {
    15101534    csec = 3.6735 * (1.0-ke)*(1.0-ke);     
    1511   };
     1535  }
    15121536
    15131537  if (csec < 0.0) csec = 0.0;
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4PionNucSampler.cc

    r1337 r1340  
    2525//
    2626// $Id: G4PionNucSampler.cc,v 1.2 2010/06/25 09:44:58 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100512  M. Kelsey -- Replaces (old, untemplated) G4FinalStateSampler
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4RegionModel.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: G4RegionModel.cc,v 1.17 2010/06/25 09:45:04 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: G4RegionModel.cc,v 1.18 2010/10/19 19:49:12 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100319  M. Kelsey -- Eliminate unnecessary use of std::pow()
     30// 20101019  M. Kelsey -- CoVerity report: unitialized constructor
    3031
    3132#include "G4RegionModel.hh"
     
    3839const G4double G4RegionModel::BE = 7;
    3940
    40 G4RegionModel::G4RegionModel(const G4int numberOfLayers, const G4int A, const G4int Z)
     41G4RegionModel::G4RegionModel(const G4int numberOfLayers,
     42                             const G4int A, const G4int Z)
     43  : massNumber(A), protonNumber(Z)
    4144{
    4245  //count the radiuses, densities and fermi momenta with A and Z
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4UnboundPN.cc

    r1337 r1340  
    2525//
    2626// $Id: G4UnboundPN.cc,v 1.5 2010/06/25 09:45:06 gunter Exp $
    27 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// GEANT4 tag $Name: hadr-casc-V09-03-85 $
    2828//
    2929// ------------------------------------------------------------
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4VCascadeCollider.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4VCascadeCollider.cc,v 1.4 2010/07/14 15:41:13 mkelsey Exp $
     26// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2527//
    26 // $Id: G4VCascadeCollider.cc,v 1.1.2.1 2010/06/25 09:45:08 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     28// 20100615  M. Kelsey -- Split constructor to have verbose separately
     29// 20100623  M. Kelsey -- Use old bindingEnergy() wrapper (now returns
     30//              G4NucleiProperties::GetBindingEnergy()).
     31// 20100714  M. Kelsey -- Move concrete functions to G4CascadeColliderBase
    2832
    2933#include "G4VCascadeCollider.hh"
    30 #include "G4HadTmpUtil.hh"
    31 #include "G4InteractionCase.hh"
    32 #include "G4InuclElementaryParticle.hh"
    33 #include "G4InuclNuclei.hh"
    34 #include "G4InuclSpecialFunctions.hh"
    35 #include "G4NucleiProperties.hh"
    3634#include "G4ios.hh"
    37 
    38 using namespace G4InuclSpecialFunctions;
    3935
    4036
     
    4339G4VCascadeCollider::G4VCascadeCollider(const char* name, G4int verbose)
    4440  : theName(name), verboseLevel(verbose) {
    45   if (verbose > 3) G4cout << " >>> " << theName << " ctor " << G4endl;
     41  if (verboseLevel) G4cout << " >>> " << theName << " ctor " << G4endl;
    4642}
    47 
    48 
    49 // Both bullet and target must be hadrons or leptons for this to work
    50 
    51 G4bool G4VCascadeCollider::useEPCollider(G4InuclParticle* bullet,
    52                                          G4InuclParticle* target) const {
    53   return (dynamic_cast<G4InuclElementaryParticle*>(bullet) &&
    54           dynamic_cast<G4InuclElementaryParticle*>(target));
    55 }
    56 
    57 
    58 // Decide wether nuclear fragment is candidate for G4BigBanger
    59 
    60 G4bool G4VCascadeCollider::explosion(G4InuclNuclei* target) const {
    61   if (verboseLevel > 3) {
    62     G4cout << " >>> " << theName << "::explosion" << G4endl;
    63   }
    64 
    65   const G4double a_cut = 20.0;
    66   const G4double be_cut = 3.0;
    67 
    68   G4double a = target->getA();
    69   G4double z = target->getZ();
    70   G4double eexs = target->getExitationEnergy();
    71 
    72   // Only small fragments with high excitations can explode
    73   G4bool explo = ((a <= a_cut) &&
    74                   (eexs >= be_cut * G4NucleiProperties::GetBindingEnergy(G4lrint(a), G4lrint(z)))
    75                   );
    76 
    77   return explo;
    78 }
    79 
    80 
    81 // Decide whether bullet-target interaction is candidate for cascade
    82 
    83 G4bool
    84 G4VCascadeCollider::inelasticInteractionPossible(G4InuclParticle* bullet,
    85                                                  G4InuclParticle* target,
    86                                                  G4double ekin) const {
    87   if (verboseLevel > 3) {
    88     G4cout << " >>> " << theName << "::inelasticInteractionPossible" << G4endl;
    89   }
    90 
    91   // If hadron-hadron collision, defer to ElementaryParticleCollider
    92   if (useEPCollider(bullet, target)) return true;
    93 
    94   // See which one of the two (or both) is a nucleus, get properties
    95   // FIXME:  Should set a = baryon() for both, but that's not in base
    96   G4InuclNuclei* nuclei_bullet = dynamic_cast<G4InuclNuclei*>(bullet);
    97   G4double ab = nuclei_bullet ? nuclei_bullet->getA() : 1;      // FIXME
    98   G4double zb = nuclei_bullet ? nuclei_bullet->getZ() : bullet->getCharge();
    99  
    100   G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target);
    101   G4double at = nuclei_target ? nuclei_target->getA() : 1;      // FIXME
    102   G4double zt = nuclei_target ? nuclei_target->getZ() : target->getCharge();
    103  
    104   // VCOL (Coulomb barrier) used for testing if elastic collision necessary
    105   const G4double coeff = 0.001 * 1.2;
    106 
    107   G4double VCOL = coeff * zt * zb / (G4cbrt(at) + G4cbrt(ab));
    108  
    109   G4bool possible = true;       // Force inelastic; should be (ekin >= VCOL)
    110 
    111   if (verboseLevel > 3) {
    112     G4cout << " VCOL: " << VCOL << " ekin: " << ekin << " inelastic possible: "
    113            << possible << G4endl;
    114   }
    115 
    116   return possible;
    117 }
  • trunk/source/processes/hadronic/models/cascade/cascade/src/G4WatcherGun.cc

    r1337 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: G4WatcherGun.cc,v 1.15 2010/10/22 20:41:05 mkelsey Exp $
     26// GEANT4 tag: $Name: hadr-casc-V09-03-85 $
    2527//
    26 // $Id: G4WatcherGun.cc,v 1.13.2.1 2010/06/25 09:45:10 gunter Exp $
    27 // GEANT4 tag: $Name: geant4-09-04-beta-01 $
     28// To include numerous high-Z watchers (e.g., for proton-lead collisions)
     29// set the preprocessor flag G4CASCADE_WATCHER_HIGHZ
    2830//
    2931// 20100407  M. Kelsey -- Replace std::vector<>::resize(0) with ::clear(),
    3032//              and create vectors pre-sized to maximum needed.
    31 
    32 //#define PB
     33//
    3334
    3435#include "G4WatcherGun.hh"
     
    6263  cs.push_back(217.4);
    6364  errs.push_back(1.22);
    64   watchers.push_back(G4NuclWatcher(0.0, as, cs, errs, false, false));
     65  watchers.push_back(G4NuclWatcher(0, as, cs, errs, false, false));
    6566
    6667  // Z = 1
     
    8081  cs.push_back(338.6);
    8182  errs.push_back(3.1);
    82   watchers.push_back(G4NuclWatcher(1.0, as, cs, errs, false, false));
     83  watchers.push_back(G4NuclWatcher(1, as, cs, errs, false, false));
    8384
    8485  // Z = 1
     
    9293  cs.push_back(338.6);
    9394  errs.push_back(3.1);
    94   watchers.push_back(G4NuclWatcher(1.0, as, cs, errs, false, true));
     95  watchers.push_back(G4NuclWatcher(1, as, cs, errs, false, true));
    9596 
    9697  // Z = -1
     
    101102  cs.push_back(198.3);
    102103  errs.push_back(1.0);
    103   watchers.push_back(G4NuclWatcher(-1.0, as, cs, errs, false, false));
     104  watchers.push_back(G4NuclWatcher(-1, as, cs, errs, false, false));
    104105
    105106  // Z = 2
     
    113114  cs.push_back(781.0);
    114115  errs.push_back(5.0);
    115   watchers.push_back(G4NuclWatcher(2.0, as, cs, errs, false, true));
    116 
    117 #ifdef PB
     116  watchers.push_back(G4NuclWatcher(2, as, cs, errs, false, true));
     117
     118#ifdef G4CASCADE_WATCHER_HIGHZ
    118119  // Z = 22
    119120  // watchers for pb208 + 1 GeV p
     
    139140  cs.push_back(0.06);
    140141  errs.push_back(0.023);
    141   watchers.push_back(G4NuclWatcher(22.0, as, cs, errs, false, true));
     142  watchers.push_back(G4NuclWatcher(22, as, cs, errs, false, true));
    142143
    143144  // Z = 23
     
    166167  cs.push_back(0.05);
    167168  errs.push_back(0.012);
    168   watchers.push_back(G4NuclWatcher(23.0, as, cs, errs, false, true));
     169  watchers.push_back(G4NuclWatcher(23, as, cs, errs, false, true));
    169170
    170171  // Z = 24
     
    193194  cs.push_back(0.092);
    194195  errs.push_back(0.011);
    195   watchers.push_back(G4NuclWatcher(24.0, as, cs, errs, true, true));
     196  watchers.push_back(G4NuclWatcher(24, as, cs, errs, true, true));
    196197
    197198  // Z = 25
     
    223224  cs.push_back(0.051);
    224225  errs.push_back(0.015);
    225   watchers.push_back(G4NuclWatcher(25.0, as, cs, errs, false, true));
     226  watchers.push_back(G4NuclWatcher(25, as, cs, errs, false, true));
    226227
    227228  // Z = 26
     
    253254  cs.push_back(0.09);
    254255  errs.push_back(0.014);
    255   watchers.push_back(G4NuclWatcher(26.0, as, cs, errs, false, true));
     256  watchers.push_back(G4NuclWatcher(26, as, cs, errs, false, true));
    256257
    257258  // Z = 27
     
    286287  cs.push_back(0.108);
    287288  errs.push_back(0.046);
    288   watchers.push_back(G4NuclWatcher(27.0, as, cs, errs, false, true));
     289  watchers.push_back(G4NuclWatcher(27, as, cs, errs, false, true));
    289290
    290291  // Z = 28
     
    322323  cs.push_back(0.054);
    323324  errs.push_back(0.036);
    324   watchers.push_back(G4NuclWatcher(28.0, as, cs, errs, true, true));
     325  watchers.push_back(G4NuclWatcher(28, as, cs, errs, true, true));
    325326
    326327  // Z = 29
     
    361362  cs.push_back(0.041);
    362363  errs.push_back(0.024);
    363   watchers.push_back(G4NuclWatcher(29.0, as, cs, errs, false, true));
     364  watchers.push_back(G4NuclWatcher(29, as, cs, errs, false, true));
    364365
    365366  // Z = 30
     
    397398  cs.push_back(0.082);
    398399  errs.push_back(0.034);
    399   watchers.push_back(G4NuclWatcher(30.0, as, cs, errs, false, true));
     400  watchers.push_back(G4NuclWatcher(30, as, cs, errs, false, true));
    400401
    401402  // Z = 31
     
    436437  cs.push_back(0.061);
    437438  errs.push_back(0.014);
    438   watchers.push_back(G4NuclWatcher(31.0, as, cs, errs, true, true));
     439  watchers.push_back(G4NuclWatcher(31, as, cs, errs, true, true));
    439440
    440441  // Z = 32
     
    478479  cs.push_back(0.04);
    479480  errs.push_back(0.018);
    480   watchers.push_back(G4NuclWatcher(32.0, as, cs, errs, false, true));
     481  watchers.push_back(G4NuclWatcher(32, as, cs, errs, false, true));
    481482
    482483  // Z = 33
     
    520521  cs.push_back(0.023);
    521522  errs.push_back(0.01);
    522   watchers.push_back(G4NuclWatcher(33.0, as, cs, errs, false, true));
     523  watchers.push_back(G4NuclWatcher(33, as, cs, errs, false, true));
    523524
    524525  // Z = 34
     
    562563  cs.push_back(0.045);
    563564  errs.push_back(0.012);
    564   watchers.push_back(G4NuclWatcher(34.0, as, cs, errs, false, true));
     565  watchers.push_back(G4NuclWatcher(34, as, cs, errs, false, true));
    565566
    566567  // Z = 35
     
    607608  cs.push_back(0.033);
    608609  errs.push_back(0.02);
    609   watchers.push_back(G4NuclWatcher(35.0, as, cs, errs, false, true));
     610  watchers.push_back(G4NuclWatcher(35, as, cs, errs, false, true));
    610611
    611612  // spallation part
     
    656657  cs.push_back(0.023);
    657658  errs.push_back(0.016);
    658   watchers.push_back(G4NuclWatcher(61.0, as, cs, errs, true, true));
     659  watchers.push_back(G4NuclWatcher(61, as, cs, errs, true, true));
    659660
    660661  // Z = 69
     
    716717  cs.push_back(0.014);
    717718  errs.push_back(0.01);
    718   watchers.push_back(G4NuclWatcher(69.0, as, cs, errs, true, true));
     719  watchers.push_back(G4NuclWatcher(69, as, cs, errs, true, true));
    719720
    720721  // Z = 73
     
    791792  cs.push_back(0.016);
    792793  errs.push_back(0.009);
    793   watchers.push_back(G4NuclWatcher(73.0, as, cs, errs, true, true));
     794  watchers.push_back(G4NuclWatcher(73, as, cs, errs, true, true));
    794795
    795796  // Z = 77
     
    878879  cs.push_back(0.037);
    879880  errs.push_back(0.019);
    880   watchers.push_back(G4NuclWatcher(77.0, as, cs, errs, true, true));
     881  watchers.push_back(G4NuclWatcher(77, as, cs, errs, true, true));
    881882
    882883  // Z = 81
     
    956957  cs.push_back(17.525);
    957958  errs.push_back(0.526);
    958   watchers.push_back(G4NuclWatcher(81.0, as, cs, errs, true, true));
     959  watchers.push_back(G4NuclWatcher(81, as, cs, errs, true, true));
    959960
    960961  // Z = 82
     
    10251026  cs.push_back(63.653);
    10261027  errs.push_back(9.573);
    1027   watchers.push_back(G4NuclWatcher(82.0, as, cs, errs, true, true));
     1028  watchers.push_back(G4NuclWatcher(82, as, cs, errs, true, true));
    10281029
    10291030#else
     
    10881089  cs.push_back(0.003);
    10891090  errs.push_back(0.001);
    1090   watchers.push_back(G4NuclWatcher(80.0, as, cs, errs, true, true));
     1091  watchers.push_back(G4NuclWatcher(80, as, cs, errs, true, true));
    10911092
    10921093  // Z = 77
     
    11631164  cs.push_back(3.54);
    11641165  errs.push_back(0.45);
    1165   watchers.push_back(G4NuclWatcher(77.0, as, cs, errs, true, true));
     1166  watchers.push_back(G4NuclWatcher(77, as, cs, errs, true, true));
    11661167
    11671168  // Z = 73
     
    12321233  cs.push_back(0.01);
    12331234  errs.push_back(0.008);
    1234   watchers.push_back(G4NuclWatcher(73.0, as, cs, errs, true, true));
     1235  watchers.push_back(G4NuclWatcher(73, as, cs, errs, true, true));
    12351236
    12361237  // Z = 61
     
    12741275  cs.push_back(0.02);
    12751276  errs.push_back(0.003);
    1276   watchers.push_back(G4NuclWatcher(61.0, as, cs, errs, true, true));
     1277  watchers.push_back(G4NuclWatcher(61, as, cs, errs, true, true));
    12771278
    12781279  // Z = 79
     
    13431344  cs.push_back(0.36);
    13441345  errs.push_back(0.05);
    1345   watchers.push_back(G4NuclWatcher(79.0, as, cs, errs, true, true));
     1346  watchers.push_back(G4NuclWatcher(79, as, cs, errs, true, true));
    13461347
    13471348  // Z = 78
     
    14151416  cs.push_back(5.49);
    14161417  errs.push_back(0.7);
    1417   watchers.push_back(G4NuclWatcher(78.0, as, cs, errs, true, true));
     1418  watchers.push_back(G4NuclWatcher(78, as, cs, errs, true, true));
    14181419
    14191420  // Z = 72
     
    14751476  cs.push_back(0.14);
    14761477  errs.push_back(0.02);
    1477   watchers.push_back(G4NuclWatcher(72.0, as, cs, errs, true, true));
     1478  watchers.push_back(G4NuclWatcher(72, as, cs, errs, true, true));
    14781479
    14791480  // Z = 66
     
    15141515  cs.push_back(0.55);
    15151516  errs.push_back(0.1);
    1516   watchers.push_back(G4NuclWatcher(66.0, as, cs, errs, true, true));
     1517  watchers.push_back(G4NuclWatcher(66, as, cs, errs, true, true));
    15171518
    15181519  // Z = 65
     
    15511552  errs.push_back(0.1);
    15521553
    1553   watchers.push_back(G4NuclWatcher(65.0, as, cs, errs, true, true));
     1554  watchers.push_back(G4NuclWatcher(65, as, cs, errs, true, true));
    15541555#endif 
    15551556
  • trunk/source/processes/hadronic/models/cascade/cascade/src/bindingEnergy.cc

    r819 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: bindingEnergy.cc,v 1.10 2010/09/14 17:51:36 mkelsey Exp $
    2526//
     27// 20100622 M. Kelsey -- Replace all functionally with call-through to
     28//              G4NucleiProperties.  Check for valid A/Z and return zero
     29//              without warning message.
     30// 20100914 M. Kelsey -- Migrate to integer A and Z
     31
    2632#include "G4InuclSpecialFunctions.hh"
     33#include "G4NucleiProperties.hh"
    2734
    28 G4double G4InuclSpecialFunctions::bindingEnergy(G4double A, G4double Z) {
    29   G4int verboseLevel = 2;
    3035
    31   if (verboseLevel > 3) {
    32     G4cout << " >>> G4InuclSpecialFunctions::bindingEnergy" << G4endl;
    33   }
     36G4double G4InuclSpecialFunctions::bindingEnergy(G4int A, G4int Z) {
     37  // NOTE:  Test condition copied from G4NucleiProperties.cc; not encapsulated
     38  if (A < 1 || Z < 0 || Z > A) return 0.;
    3439
    35   // calculates the nuclei binding energy using Kummel or exact or asymptotic
    36   // high temperature
    37   G4double DM;
    38   G4double AN = A - Z;
    39 
    40   if (AN < 0.1 || Z < 0.1) {
    41     DM = 0.0;
    42 
    43   } else {
    44 
    45     if (A <= 256.0) {
    46 
    47       if (AN >= 20. && Z >= 20) {
    48 
    49         if (Z < 1.7 * AN && Z > 0.3 * AN) { // standard
    50           DM = bindingEnergyKummel(A, Z);
    51 
    52         } else { // bad case
    53           DM = bindingEnergyAsymptotic(A, Z);
    54         };
    55 
    56       } else {
    57 
    58         if (A > 60.0 || Z > 21) { // bad case
    59           DM = bindingEnergyAsymptotic(A, Z);
    60 
    61         } else { // exact case
    62           DM = bindingEnergyExact(A, Z);
    63         };
    64       };
    65 
    66     } else {
    67       DM = bindingEnergyAsymptotic(A, Z);
    68     };
    69   }; 
    70 
    71   // G4cout << " A " << A << " Z " << Z << " DM " << DM << G4endl;
    72 
    73   return DM;
     40  return G4NucleiProperties::GetBindingEnergy(A, Z);
    7441}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/bindingEnergyAsymptotic.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: bindingEnergyAsymptotic.cc,v 1.12 2010/06/25 09:45:12 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: bindingEnergyAsymptotic.cc,v 1.13 2010/09/14 17:51:36 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100202  M. Kelsey -- Eliminate unnecessary use of std::pow()
     30// 20100914  M. Kelsey -- Migrate to integer A and Z; discard unused verbose
    3031
    3132#include "G4InuclSpecialFunctions.hh"
    3233
    33 G4double G4InuclSpecialFunctions::bindingEnergyAsymptotic(G4double A,
    34                                                           G4double Z) {
    35   G4int verboseLevel = 2;
    36 
    37   if (verboseLevel > 3) {
    38     G4cout << " >>> G4InuclSpecialFunctions::bindingEnergyAsymptotic" << G4endl;
    39   }
    40 
     34G4double G4InuclSpecialFunctions::bindingEnergyAsymptotic(G4int A, G4int Z) {
    4135  // calculates the nuclei binding energy
    4236  // using smooth liquid high energy formula 
    43   G4double X = (1.0 - 2.0 * Z / A) * (1.0 - 2.0 * Z / A);
     37  G4double X = (1.0 - 2.0*Z/A); X *= X;
    4438  G4double X1 = G4cbrt(A);
    4539  G4double X2 = X1 * X1;
    4640  G4double X3 = 1.0 / X1;
    4741  G4double X4 = 1.0 / X2;
     42  G4double X5 = (1.0 - 0.62025 * X4); X5 *= X5;
     43
    4844  G4double DM = 17.035 * (1.0 - 1.846 * X) * A -
    49     25.8357 * (1.0 - 1.712 * X) * X2 *
    50     ((1.0  -0.62025 * X4) * (1.0 - 0.62025 * X4)) -
    51     0.779 * Z * (Z - 1.0) * X3 *
     45    25.8357 * (1.0 - 1.712 * X) * X2 * X5 -
     46    0.779 * Z * (Z - 1) * X3 *
    5247    (1.0 - 1.5849 * X4 + 1.2273 / A + 1.5772 * X4 * X4) +
    5348    0.4328 * G4cbrt(Z*Z*Z*Z) * X3 *
  • trunk/source/processes/hadronic/models/cascade/cascade/src/nucleiLevelDensity.cc

    r819 r1340  
    2323// * acceptance of all terms of the Geant4 Software license.          *
    2424// ********************************************************************
     25// $Id: nucleiLevelDensity.cc,v 1.8 2010/09/14 17:51:36 mkelsey Exp $
    2526//
     27// 20100914  M. Kelsey -- Migrate to integer A and Z; simplify code
     28
    2629#include "G4InuclSpecialFunctions.hh"
    2730
    28 G4double G4InuclSpecialFunctions::nucleiLevelDensity(G4double a) {
    29   G4int verboseLevel = 2;
    3031
    31   if (verboseLevel > 3) {
    32     G4cout << " >>> G4InuclSpecialFunctions::nucleiLevelDensity" << G4endl;
    33   }
    34 
     32G4double G4InuclSpecialFunctions::nucleiLevelDensity(G4int a) {
    3533  const G4double NLD[226] = {
    3634    // 20 - 29
     
    8179    29.87, 30.25, 30.5, 29.8, 29.17, 28.67};
    8280
    83   G4int ia = G4int(a + 0.1) - 20;
    84 
    85   if (ia > 0) {
    86     return NLD[ia];
    87 
    88   } else {
    89     return 0.1 * a;
    90   };
     81  return (a>=20) ? NLD[a-20] : 0.1*a;
    9182}
  • trunk/source/processes/hadronic/models/cascade/cascade/src/paraMaker.cc

    r1337 r1340  
    2424// ********************************************************************
    2525//
    26 // $Id: paraMaker.cc,v 1.18 2010/06/25 09:45:16 gunter Exp $
    27 // Geant4 tag: $Name: geant4-09-04-beta-01 $
     26// $Id: paraMaker.cc,v 1.19 2010/09/14 17:51:36 mkelsey Exp $
     27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
    2828//
    2929// 20100412  M. Kelsey -- Modify paraMaker[Truncated] to take buffer as argument
     
    3131// 20100517  M. Kelsey -- Use G4CascadeInterpolator, which handles boundaries
    3232// 20100601  M. Kelsey -- Bug fix from Gunter Folger; resize(6,0.), not clear()
     33// 20100914  M. Kelsey -- Migrate to integer A and Z
    3334
    3435#include "G4InuclSpecialFunctions.hh"
Note: See TracChangeset for help on using the changeset viewer.