source: trunk/source/materials/src/G4MaterialPropertyVector.cc @ 850

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

geant4.8.2 beta

File size: 11.3 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// $Id: G4MaterialPropertyVector.cc,v 1.16 2008/06/05 23:38:51 gum Exp $
28// GEANT4 tag $Name: HEAD $
29//
30//
31////////////////////////////////////////////////////////////////////////
32// G4MaterialPropertyVector Class Implementation
33////////////////////////////////////////////////////////////////////////
34//
35// File:        G4MaterialPropertyVector.cc
36// Version:     1.0
37// Created:     1996-02-08
38// Author:      Juliet Armstrong
39// Updated:     1997-03-25 by Peter Gumplinger
40//              > cosmetics (only)
41// mail:        gum@triumf.ca
42//
43////////////////////////////////////////////////////////////////////////
44
45#include "G4MaterialPropertyVector.hh"
46
47/////////////////////////
48// Class Implementation 
49/////////////////////////
50
51        //////////////
52        // Operators
53        //////////////
54
55// ++ operator
56// -----------
57//
58G4bool G4MaterialPropertyVector::operator ++()
59{
60        CurrentEntry++;
61        if (CurrentEntry < NumEntries) {
62                return true;
63        }
64        else {
65                return false; 
66        }
67}
68
69// = operator
70// ----------
71//
72G4MaterialPropertyVector&
73G4MaterialPropertyVector::operator =(const G4MaterialPropertyVector& right)
74{
75        if (this == &right) return *this;
76       
77        // clear the vector of current contents
78
79        MPV.clear();
80
81        // create an actual copy (instead of the shallow copy that the
82        // assignment operator defaults to for G4RWTPtrSortedVector)
83
84        NumEntries = 0;
85        CurrentEntry = -1;
86
87        for (G4int i = 0 ; i < right.NumEntries; i++) {
88                G4MPVEntry *newElement = new G4MPVEntry(right.GetEntry(i));
89                MPV.push_back(newElement);
90                NumEntries++;
91        }
92
93        return *this;
94}
95
96        /////////////////
97        // Constructors
98        /////////////////
99
100G4MaterialPropertyVector::G4MaterialPropertyVector(G4double *PhotonEnergies,
101                                                   G4double *PropertyValues,
102                                                   G4int     NumElements)
103{
104        NumEntries = 0;
105        CurrentEntry = -1;
106
107        // create a vector filling it with the values
108        // from PhotonEnergies[] and PropertyValues[]
109
110        for(G4int i = 0; i < NumElements; i++) {
111                AddElement(PhotonEnergies[i], PropertyValues[i]);
112        }
113}
114
115G4MaterialPropertyVector::G4MaterialPropertyVector
116                          (const G4MaterialPropertyVector &right)
117{
118        // create an actual copy (instead of the shallow copy that the
119        // assignment operator defaults to for G4RWTPtrSortedVector)
120
121        NumEntries = 0;
122        CurrentEntry = -1;
123
124        for (G4int i = 0 ; i < right.NumEntries; i++) {
125                G4MPVEntry *newElement = new G4MPVEntry(right.GetEntry(i));
126                MPV.push_back(newElement);
127                NumEntries++;
128        }
129}
130
131        ////////////////
132        // Destructors
133        ////////////////
134
135G4MaterialPropertyVector::~G4MaterialPropertyVector()
136{
137        MPV.clear();
138}
139
140        ////////////
141        // Methods
142        ////////////
143void G4MaterialPropertyVector::AddElement(G4double aPhotonEnergy,
144                                          G4double aPropertyValue) 
145{
146        G4MPVEntry *newElement;
147       
148        newElement = new G4MPVEntry(aPhotonEnergy, aPropertyValue);
149        MPV.push_back(newElement);
150        std::sort(MPV.begin(), MPV.end(), MPVEntry_less());
151        NumEntries++; 
152}
153
154void G4MaterialPropertyVector::RemoveElement(G4double aPhotonEnergy)
155{
156        G4MPVEntry *newElement;
157        G4MPVEntry *success=0;
158
159        newElement = new G4MPVEntry(aPhotonEnergy, DBL_MAX);
160
161        std::vector<G4MPVEntry*>::iterator i;
162        for (i = MPV.begin(); i != MPV.end(); i++)
163          if (**i == *newElement) {success = *i; break;}
164        //      success = MPV.remove(newElement);
165
166        if(success == 0)
167        {
168        G4Exception("G4MaterialPropertyVector::RemoveElement==>"
169                                               "element not found");
170        return;
171        }
172        else
173        {
174          MPV.erase(i); // remove done here.
175        }
176
177        NumEntries--;
178}
179
180G4double
181G4MaterialPropertyVector::GetProperty(G4double aPhotonEnergy) const
182{
183        G4MPVEntry *target, *temp; 
184        G4int left, right;
185        G4double ratio1, ratio2, pmright, pmleft, InterpolatedValue;
186 
187        /////////////////////////
188        // Establish table range
189        /////////////////////////
190
191        G4double PMmin   = MPV.front()->GetPhotonEnergy(); 
192        G4double minProp = MPV.front()->GetProperty(); 
193        G4double PMmax   = MPV.back() ->GetPhotonEnergy();
194        G4double maxProp = MPV.back() ->GetProperty();
195
196        ///////////////////////////////////////////
197        // Does value fall outside range of table?
198        ///////////////////////////////////////////
199
200        if (aPhotonEnergy < PMmin) 
201        {
202                G4cout << "\nWarning: G4MaterialPropertyVector::GetProperty";
203                G4cout << "\n==> attempt to Retrieve Property below range" 
204                << G4endl;
205                return minProp; 
206        } 
207
208        if (aPhotonEnergy > PMmax)
209        {
210                G4cout << "\nWarning: G4MaterialPropertyVector::GetProperty";
211                G4cout << "\n==> attempt to Retrieve Property above range" 
212                << G4endl;
213                return maxProp;
214        } 
215       
216        target = new G4MPVEntry(aPhotonEnergy, 0.0);
217
218        temp = 0;
219        //temp = MPV.find(target);
220        std::vector<G4MPVEntry*>::const_iterator i;
221        for (i = MPV.begin(); i != MPV.end(); i++)
222          if (**i == *target) {temp = *i; break;}
223        if (temp != 0) {
224
225                ////////////////////////
226                // Return actual value
227                ////////////////////////
228
229                G4double retval = temp->GetProperty();
230                delete target;
231                return retval;
232        }
233        else {
234                //////////////////////////////
235                // Return interpolated value
236                //////////////////////////////
237
238                GetAdjacentBins(aPhotonEnergy, &left, &right);
239
240                pmleft = MPV[left]->GetPhotonEnergy();
241                pmright = MPV[right]->GetPhotonEnergy();
242                ratio1 = (aPhotonEnergy-pmleft)/(pmright-pmleft);
243                ratio2 = 1 - ratio1;
244                InterpolatedValue = MPV[left]->GetProperty()*ratio2 + 
245                                    MPV[right]->GetProperty()*ratio1;
246               
247                delete target;
248                return InterpolatedValue;
249        }       
250}
251
252G4double G4MaterialPropertyVector::GetProperty() const
253{
254//      For use with G4MaterialPropertyVector iterator
255
256        if(CurrentEntry == -1 || CurrentEntry >= NumEntries) {
257                G4Exception("G4MaterialPropertyVector::GetProperty ==>"
258                "Iterator attempted to Retrieve Property out of range");
259                return DBL_MAX;
260        }
261        else { 
262                return MPV[CurrentEntry]->GetProperty();
263        }
264}
265
266G4double G4MaterialPropertyVector::GetPhotonEnergy() const
267{
268//      For use with G4MaterialPropertyVector iterator
269
270        if(CurrentEntry == -1 || CurrentEntry >= NumEntries) {
271                G4Exception("G4MaterialPropertyVector::GetPhotonEnergy ==>"
272                "Iterator attempted to Retrieve Photon Energy out of range");
273                return DBL_MAX;
274        }
275        else { 
276                return MPV[CurrentEntry]->GetPhotonEnergy();
277        }
278}
279
280G4double
281G4MaterialPropertyVector::GetPhotonEnergy(G4double aProperty) const
282{
283//                              ***NB***
284// Assumes that the property is an increasing function of photon energy (e.g.
285// refraction index)
286//                              ***NB***
287//
288// Returns the photon energy corresponding to the property value passed in.
289// If several photon energy values correspond to the value passed in, the
290// function returns the first photon energy in the vector that corresponds
291// to that value.
292
293        G4int left, right, mid;
294        G4double ratio1, ratio2, pright, pleft, InterpolatedValue;
295
296        //////////////////////////
297        // Establish Table range
298        //////////////////////////
299
300        G4double PropMin = MPV.front()->GetProperty();
301        G4double PMmin   = MPV.front()->GetPhotonEnergy();
302        G4double PropMax = MPV.back() ->GetProperty();
303        G4double PMmax   = MPV.back() ->GetPhotonEnergy();
304
305        ///////////////////////////////////////////
306        // Does value fall outside range of table?
307        ///////////////////////////////////////////
308
309        if (aProperty < PropMin) 
310        {
311          G4cout << "\nWarning: G4MaterialPropertyVector::GetPhotonEnergy";
312          G4cout << "\n==> attempt to Retrieve Photon Energy out of range" 
313               << G4endl; 
314          return PMmin;
315        }
316
317        if (aProperty > PropMax) {
318          G4cout << "\nWarning: G4MaterialPropertyVector::GetPhotonEnergy";
319          G4cout << "\n==> attempt to Retrieve Photon Energy out of range" 
320               << G4endl;
321          return PMmax;
322        }
323
324        //////////////////////////////
325        // Return interpolated value
326        //////////////////////////////
327
328        left = 0;
329        right = MPV.size(); // was .entries()
330
331        // find values in bins on either side of aProperty
332       
333        do {
334                mid = (left + right)/2;
335                if (MPV[mid]->GetProperty() == aProperty) { 
336
337                        // Get first photon energy value in vector that
338                        // corresponds to property value 
339
340                        while (mid-1 >= 0 && 
341                               MPV[mid-1]->GetProperty() == aProperty) {
342                                  mid--;
343                        }
344
345                        InterpolatedValue = MPV[mid]->GetPhotonEnergy();
346                        goto end_GetPhotonEnergy;       
347                }
348                if (MPV[mid]->GetProperty() < aProperty)
349                        left = mid;
350                else
351                        right = mid;
352
353        } while ((right - left) > 1);
354
355        pleft = MPV[left]->GetProperty();
356        pright = MPV[right]->GetProperty();
357        ratio1 = (aProperty - pleft) / (pright - pleft);
358        ratio2 = 1 - ratio1;
359        InterpolatedValue = MPV[left]->GetPhotonEnergy()*ratio2 +
360                            MPV[right]->GetPhotonEnergy()*ratio1;
361
362end_GetPhotonEnergy:
363
364        return InterpolatedValue;
365}
366
367void G4MaterialPropertyVector::ResetIterator()
368{
369        CurrentEntry = -1;
370} 
371
372void G4MaterialPropertyVector::DumpVector()
373{
374        if (MPV.empty())  {
375                G4cerr << "nothing to dump" << G4endl;
376                G4Exception("G4MaterialPropertyVector::DumpVector ==>"
377                            "Nothing to dump!  Vector is empty");
378        }
379
380        for (G4int i = 0; i < NumEntries; i++) {
381                G4cout << "MPV["<< i << "]: ";
382                MPV[i]->DumpEntry();
383        }
384        G4cout << " Done DumpVector of " << NumEntries << " entries " << G4endl;
385
386} 
387
388G4MPVEntry G4MaterialPropertyVector::GetEntry(G4int i) const
389{
390        return *MPV[i];
391}
392
393void 
394G4MaterialPropertyVector::GetAdjacentBins(G4double aPhotonEnergy,
395                                          G4int *left,
396                                          G4int *right) const
397{
398        G4int mid;
399
400        *left = 0;
401        *right = (MPV.size() - 1); // was .entries()
402
403        // find values in bins on either side of aPhotonEnergy
404
405        do {
406                mid = (*left + *right)/2;
407
408                if (MPV[mid]->GetPhotonEnergy() < aPhotonEnergy) 
409                {
410                        *left = mid;
411                }
412                else
413                {
414                        *right = mid;
415                }
416        } while ((*right - *left) > 1);
417}
Note: See TracBrowser for help on using the repository browser.