source: trunk/source/processes/hadronic/models/de_excitation/fermi_breakup/src/G4FermiSplitter.cc @ 1199

Last change on this file since 1199 was 819, checked in by garnier, 16 years ago

import all except CVS

File size: 5.8 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// Hadronic Process: Nuclear De-excitations
28// by V. Lara
29
30#include "G4FermiSplitter.hh"
31#include "G4FermiIntegerPartition.hh"
32#include "G4HadronicException.hh"
33#include <sstream>
34
35
36G4int G4FermiSplitter::Initialize(const G4int a, const G4int z, const G4int n)
37{
38  // Check argument correctness
39  if (a < 0 || z < 0 || n < 0) 
40    {
41      std::ostringstream errOs;
42      errOs << "G4FermiSplitter::Initialize() Error: Non valid arguments A = "
43            << a << " Z = " << z << " #fragments = " << n;
44      throw G4HadronicException(__FILE__, __LINE__, errOs.str());
45    }
46  if (z > a || n > a)
47    {
48      std::ostringstream errOs;
49      errOs << "G4FermiSplitter::Initialize() Error: Non physical arguments = "
50            << a << " Z = " << z << " #fragments = " << n;
51      throw G4HadronicException(__FILE__, __LINE__, errOs.str());
52    }
53  A = a;
54  Z = z;
55  K = n;
56  splits.clear();
57
58
59  // Form all possible partition by combination
60  // of A partitions and Z partitions (Z partitions include null parts)
61  G4FermiIntegerPartition PartitionA;
62  PartitionA.Initialize(A,K);
63  do // for each partition of A
64    {
65      G4FermiIntegerPartition PartitionZ;
66      PartitionZ.EnableNull();
67      PartitionZ.Initialize(Z,K);
68      std::vector<G4int> partA = PartitionA.GetPartition();
69      std::vector<G4int> multiplicities;
70      do  // for each partition of Z
71        {
72          std::vector<G4int> partZ = PartitionZ.GetPartition();
73          // Get multiplicities
74          // provided that for each a,z pair there could be several
75          // posibilities, we have to count them in order to create
76          // all possible combinations.
77          multiplicities.clear();
78          G4int num_rows = 1;
79          std::pair<G4int,G4int> az_pair;
80          for (G4int i = 0; i < K; i++)
81            {
82              az_pair = std::make_pair(partA[i],partZ[i]);
83              G4int m = theFragmentsPool->Count(az_pair);
84              if (m > 0)
85                {
86                  multiplicities.push_back(m);
87                  num_rows *= m;
88                }
89              else
90                {
91                  break;
92                }
93            }
94          // if size of multiplicities is equal to K, it
95          // means that all combinations a,z exist in the
96          // fragments pool
97          if (static_cast<G4int>(multiplicities.size()) == K)
98            {
99              std::vector<std::vector<const G4VFermiFragment*> > tsplits;
100              tsplits.clear();
101              tsplits.resize(num_rows);
102              G4int group_size = num_rows;
103              for (G4int i = 0; i < K; i++)
104                {
105                  az_pair = std::make_pair(partA[i],partZ[i]);
106                  group_size /= multiplicities[i];
107                  std::multimap<const std::pair<G4int,G4int>, const G4VFermiFragment*,
108                    std::less<const std::pair<G4int,G4int> > >::iterator pos;
109                  pos = theFragmentsPool->LowerBound(az_pair);
110                  for (G4int k = 0; k < num_rows/group_size; k++)
111                    {
112                      if (pos == theFragmentsPool->UpperBound(az_pair))
113                        {
114                          pos = theFragmentsPool->LowerBound(az_pair);
115                        }
116                      for (G4int l = 0; l < group_size; l++)
117                        {
118                          tsplits[k*group_size+l].push_back(pos->second);
119                        }
120                      pos++;
121                    }
122                }
123              // Remove wrong splits
124              for (std::vector<std::vector<const G4VFermiFragment*> >::iterator
125                     itsplits1 = tsplits.begin(); itsplits1 != tsplits.end(); itsplits1++)
126                {
127                  std::sort((itsplits1)->begin(), (itsplits1)->end(),
128                            std::greater<const G4VFermiFragment*>());
129                }
130              // add splits  (eliminating a few of them that are repeated)
131              std::vector<std::vector<const G4VFermiFragment*> >::iterator
132                itlastsplit =  tsplits.begin();
133              splits.push_back((*itlastsplit));
134              for (std::vector<std::vector<const G4VFermiFragment*> >::iterator
135                     itsplits2 = itlastsplit+1; itsplits2 != tsplits.end(); itsplits2++)
136                {
137                  if ( (*itsplits2) != (*itlastsplit)) splits.push_back((*itsplits2));
138                  itlastsplit++;
139                }
140            }
141        }
142      while (PartitionZ.Next());
143    } // partition of A
144  while (PartitionA.Next());
145
146  return splits.size();
147}
Note: See TracBrowser for help on using the repository browser.