Skip to content

Commit 4f7fb84

Browse files
Version 1.1.0 - tallies, var. dec./opt., pre-samp. pts, sph. inc.
- Refactoring of flux capabilities to be easier on users and developers. - New features of variance deconvolution (ClementsJQSRT2024) and optimization for mean quantities (OlsonANS2018)--these required enabling multiple histories per sample in 3D and multiple samples per partition for statistical estimates. - New feature of pre-sampled points on a grid with grid lookups for 1D CoPS. - Refactoring and new features for spherical inclusion geometry to enable faster realization generation and material lookups.
1 parent 2292dd9 commit 4f7fb84

30 files changed

+1760
-1537
lines changed

Core/1D/MonteCarloParticleSolverpy.py

Lines changed: 89 additions & 152 deletions
Large diffs are not rendered by default.

Core/1D/OneDSlabpy.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ def populateMarkovRealization(self,totxs=None,lam=None,s=None,scatxs=None,NaryTy
184184
b0 = [0]*self.nummats; b0.append(1)
185185
b=np.transpose(np.array(b0))
186186
self.chordfreq = list( np.linalg.solve(np.transpose(A).dot(A), np.transpose(A).dot(b)) )
187-
#########print('self.chordfreq:',self.chordfreq)
188187
self.prob = []
189188
for i in range(0,self.nummats):
190189
self.prob.append( self.chordfreq[i]*self.lam[i] / np.dot(self.chordfreq,self.lam) )
@@ -203,8 +202,6 @@ def populateMarkovRealization(self,totxs=None,lam=None,s=None,scatxs=None,NaryTy
203202
else:
204203
while True: #sample next material either by abundance or with equal probability
205204
local_probs = self.NaryType[curmat]
206-
# local_probs[curmat] = 0.0 #give probability of zero to current material
207-
# local_probs = np.divide( local_probs, np.sum(local_probs) ) #normalize probabilities
208205
curmat = int( self.Rng.choice( self.nummats, p=local_probs ) ) #select material from any but current
209206

210207
self.mattype.append(curmat)
@@ -222,7 +219,8 @@ def populateMarkovRealization(self,totxs=None,lam=None,s=None,scatxs=None,NaryTy
222219
# \param[in] lam list of average material chord lengths
223220
# \param[in] s float, the length of the slab
224221
# \param scatxs list, optional, list of scattering cross section values, if specified, absorption cross sections and scattering ratios will also be computed and stored as attributes
225-
def populateMarkovRealizationPseudo(self,totxs=None,lam=None,s=None,scatxs=None):
222+
def populateMarkovRealizationPseudo(self,totxs=None,lam=None,s=None,scatxs=None,NaryType='volume-fraction'):
223+
assert NaryType=='volume-fraction' #the pseudo-interface approach is only a valid approach for 'volume-fraction'-type Markovian mixing; for other types of Markovian mixing, use the chord-based sampler
226224
assert isinstance(totxs,list)
227225
self.nummats = len(totxs)
228226
for i in range(0,self.nummats): assert isinstance(totxs[i],float) and totxs[i]>=0.0

Core/1D/SpecialMonteCarloDriverspy.py

Lines changed: 267 additions & 157 deletions
Large diffs are not rendered by default.

Core/3D/Geometry_Basepy.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from Particlepy import Particle
66
from ClassToolspy import ClassTools
77
import numpy as np
8-
import matplotlib.pyplot as plt
98

109
## \brief Multi-D base geometry class - useless by itself, but other multi-D geometry classes inherit from it
1110
# \author Aaron Olson, [email protected], [email protected]
@@ -40,9 +39,9 @@ def defineGeometryBoundaries(self,xbounds=None,ybounds=None,zbounds=None):
4039
self.ybounds = ybounds
4140
self.zbounds = zbounds
4241

43-
self.Volume = self.zbounds[1]-zbounds[0]
44-
if self.Part.numDims>=2: self.Volume *= (self.xbounds[1]-xbounds[0])
45-
if self.Part.numDims==3: self.Volume *= (self.ybounds[1]-ybounds[0])
42+
self.Volume = self.zbounds[1]-self.zbounds[0]
43+
if self.Part.numDims>=2: self.Volume *= (self.xbounds[1]-self.xbounds[0])
44+
if self.Part.numDims==3: self.Volume *= (self.ybounds[1]-self.ybounds[0])
4645

4746

4847
## \brief Define boundary conditions
@@ -188,20 +187,21 @@ def _generateRandomPoint(self):
188187

189188

190189

190+
## \brief Initialize geometry parameters at start of each history
191+
# \returns nothing
192+
def _initializeHistoryGeometryMemory(self):
193+
assert 1==0
191194

192-
193-
195+
## \brief Initialize geometry parameters at start of each sample
196+
# \returns nothing
197+
def _initializeSampleGeometryMemory(self):
198+
assert 1==0
194199

195200
## \brief Define mixing parameters (correlation length and material probabilities)
196201
# To be provided by non-base class
197202
def defineMixingParams(self,laminf=None,prob=None):
198203
assert 1==0
199204

200-
## \brief Initializes list of material types and coordinate of location, initializes xyz boundary locations
201-
# To be provided by non-base class
202-
def initializeGeometryMemory(self):
203-
assert 1==0
204-
205205
## \brief Samples a new point according to the selected rules
206206
# To be provided by non-base class
207207
def samplePoint(self):

Core/3D/Geometry_BoxPoissonpy.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#!usr/bin/env python
22
from Geometry_Basepy import Geometry_Base
33
import numpy as np
4-
import scipy.spatial
54
import bisect as bisect
6-
import collections
75
try:
86
import pandas as pd
97
except:
@@ -23,11 +21,27 @@ def __init__(self):
2321
self.flshowplot = False; self.flsaveplot = False
2422
self.kdtrees = False
2523
self.GeomType = 'BoxPoisson'
24+
self.abundanceModel = 'ensemble'
2625

2726
def __str__(self):
2827
return str(self.__dict__)
2928

3029

30+
## \brief Some geometries will need to overwrite this method definition, others won't.
31+
#
32+
# \returns nothing
33+
def _initializeHistoryGeometryMemory(self):
34+
pass
35+
36+
## \brief Initializes list of material types and coordinate of location, initializes xyz boundary locations
37+
#
38+
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists, but convert to arrays using np.asarray(l) if needed to use array format
39+
#
40+
# \returns initializes self.MatInds and self.xBoundaries, self.yBoundaries, self.zBoundaries
41+
def _initializeSampleGeometryMemory(self):
42+
self._sampleNumberOfHyperplanes()
43+
self._sampleHyperplaneLocations()
44+
3145
## \brief Defines mixing parameters (correlation length and material probabilities)
3246
# Note: laminf and rhoB notation and formula following LarmierJQSRT2017 different mixing types paper
3347
#
@@ -45,16 +59,6 @@ def defineMixingParams(self,laminf=None,prob=None):
4559
self.rhoB = 2.0 / 3.0 / self.laminf
4660

4761

48-
## \brief Initializes list of material types and coordinate of location, initializes xyz boundary locations
49-
#
50-
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists, but convert to arrays using np.asarray(l) if needed to use array format
51-
#
52-
# \returns initializes self.MatInds and self.xBoundaries, self.yBoundaries, self.zBoundaries
53-
def initializeGeometryMemory(self):
54-
self._sampleNumberOfHyperplanes()
55-
self._sampleHyperplaneLocations()
56-
57-
5862
## \brief compute number of pseudo-interfaces
5963
#
6064
# \computes number of pseudo-interfaces in x, y, and z direction for defined geometry

Core/3D/Geometry_CLSpy.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import sys
33
from Geometry_Basepy import Geometry_Base
44
sys.path.append('/../../Classes/Tools')
5-
from RandomNumberspy import RandomNumbers
6-
from Particlepy import Particle
75
from ClassToolspy import ClassTools
86
from MarkovianInputspy import MarkovianInputs
97
import numpy as np
@@ -18,10 +16,22 @@ class Geometry_CLS(Geometry_Base,ClassTools,MarkovianInputs):
1816
def __init__(self):
1917
super(Geometry_CLS,self).__init__()
2018
self.GeomType = 'CLS'
19+
self.abundanceModel = 'ensemble'
2120

2221
def __str__(self):
2322
return str(self.__dict__)
2423

24+
## \brief Some geometries will need to overwrite this method definition, others won't.
25+
#
26+
# \returns nothing
27+
def _initializeHistoryGeometryMemory(self):
28+
pass
29+
30+
## \brief Some geometries will need to overwrite this method definition, others won't.
31+
#
32+
# \returns nothing
33+
def _initializeSampleGeometryMemory(self):
34+
pass
2535

2636
## \brief Defines mixing parameters (chord lengths and probabilities)
2737
#
@@ -52,12 +62,6 @@ def defineCLSGeometryType(self,CLSAlg="CLS",fl1DEmulation=False):
5262
assert isinstance(fl1DEmulation,bool)
5363
self.fl1DEmulation = fl1DEmulation
5464

55-
## \brief Initializes geometry memory; CLS doesn't have any so only initialize if LRP
56-
def initializeGeometryMemory(self):
57-
if self.CLSAlg == "LRP":
58-
self.dip = 0.0
59-
self.dim = 0.0
60-
6165
## \brief Samples material index at start of particle transport based on volume fractions
6266
#
6367
# \returns updates material index and point attributes

Core/3D/Geometry_CoPSpy.py

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import sys
33
from Geometry_Basepy import Geometry_Base
44
sys.path.append('/../../Classes/Tools')
5-
from RandomNumberspy import RandomNumbers
6-
from Particlepy import Particle
75
from ClassToolspy import ClassTools
86
from MarkovianInputspy import MarkovianInputs
97
import numpy as np
@@ -23,10 +21,30 @@ def __init__(self):
2321
self.flshowplot = False; self.flsaveplot = False
2422
self.flCollectPoints = False
2523
self.GeomType = 'CoPS'
24+
self.abundanceModel = 'ensemble'
2625

2726
def __str__(self):
2827
return str(self.__dict__)
2928

29+
## \brief Initializes short-term points and material indices for CoPS (starts history)--erases memory
30+
#
31+
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists,
32+
# but convert to arrays using np.asarray(l) if needed to use array format
33+
#
34+
# \returns initializes self.RecentPoints and self.RecentMatInds
35+
def _initializeHistoryGeometryMemory(self):
36+
self.RecentPoints = []
37+
self.RecentMatInds = []
38+
39+
## \brief Initializes long-term memory points and material indices for CoPS (starts cohort)--erases memory
40+
#
41+
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists,
42+
# but convert to arrays using np.asarray(l) if needed to use array format
43+
#
44+
# \returns initializes self.LongTermPoints and self.LongTermMatInds
45+
def _initializeSampleGeometryMemory(self):
46+
self.LongTermPoints = []
47+
self.LongTermMatInds = []
3048

3149
## \brief Defines mixing parameters (chord lengths and probabilities)
3250
#
@@ -41,20 +59,6 @@ def defineMixingParams(self,lam=None):
4159
# Solve and store material probabilities and correlation length
4260
self.solveNaryMarkovianParamsBasedOnChordLengths(self.lam)
4361

44-
## \brief Initializes points and material indices--erases any memory
45-
#
46-
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists,
47-
# but convert to arrays using np.asarray(l) if needed to use array format
48-
# "LongTerm" refers to storage of point location and material index until the end of a cohort
49-
# "Recent" refers to storage of the N most recent points not committed to long term memory
50-
#
51-
# \returns initializes self.LongTermPoints, self.LongTermMatInds, self.RecentPoints, and self.RecentMatInds
52-
def initializeGeometryMemory(self):
53-
self.LongTermPoints = []
54-
self.LongTermMatInds = []
55-
self.RecentPoints = []
56-
self.RecentMatInds = []
57-
5862
## \brief Samples material index of new point, and stores or forgets new point, according to selected rules
5963
#
6064
# Calls other method to solve conditional probabilities of material index at new point based on previously
@@ -464,25 +468,4 @@ def selectWhetherPrintPoints(self,flCollectPoints=False,pointsNpyFileName='CoPSP
464468
self.flCollectPoints = flCollectPoints
465469
if self.flCollectPoints:
466470
assert isinstance(pointsNpyFileName,str)
467-
self.pointsNpyFileName = pointsNpyFileName
468-
469-
## \brief Collect CoPS output points and store in accumulating list
470-
#
471-
# \param[in] ipart int, Particle number (same as realization number so far)
472-
# \returns creates or contributes to master list of points self.OldPointData
473-
def appendNewPointsToCollection(self,ipart):
474-
if len(self.LongTermMatInds)>0:
475-
#Create array of particle number, combine particle number, material indices, and x, y, z coordinates into one array
476-
NewPointData = np.concatenate( ( np.stack( (np.full(len(self.LongTermMatInds),ipart), np.array(self.LongTermMatInds)), axis=-1 ) , np.array(self.LongTermPoints) ) , axis=1)
477-
#Add to master list of points defined in all realizations (or create that list)
478-
if hasattr(self,'OldPointData'): self.OldPointData = np.concatenate( (self.OldPointData,NewPointData), axis=0)
479-
else : self.OldPointData = NewPointData
480-
481-
482-
## \brief If flag set to collect points, print collected points to npy file
483-
#
484-
# \returns prints data to file
485-
def printCollectedPointsToNumpyFile(self):
486-
if self.flCollectPoints: np.save( self.pointsNpyFileName , self.OldPointData )
487-
488-
471+
self.pointsNpyFileName = pointsNpyFileName

Core/3D/Geometry_Markovianpy.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,26 @@ def __init__(self):
1919
super(Geometry_Markovian,self).__init__()
2020
self.flshowplot = False; self.flsaveplot = False
2121
self.GeomType = 'Markovian'
22+
self.abundanceModel = 'ensemble'
2223

2324
def __str__(self):
2425
return str(self.__dict__)
25-
26+
27+
## \brief Some geometries will need to overwrite this method definition, others won't.
28+
#
29+
# \returns nothing
30+
def _initializeHistoryGeometryMemory(self):
31+
pass
32+
33+
## \brief Initializes list of material types and coordinate of location, initializes xyz boundary locations
34+
#
35+
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists, but convert to arrays using np.asarray(l) if needed to use array format
36+
#
37+
# \returns initializes self.MatInds and self.xBoundaries, self.yBoundaries, self.zBoundaries
38+
def _initializeSampleGeometryMemory(self):
39+
self._sampleNumberOfHyperplanes()
40+
self._sampleHyperplaneLocations()
41+
2642
## \brief Defines mixing parameters (correlation length and material probabilities)
2743
# Note: laminf and rhoP notation following LarmierJQSRT2017 different mixing types paper
2844
#
@@ -40,15 +56,6 @@ def defineMixingParams(self,laminf=None,prob=None):
4056
self.rhoP = 1.0 / self.laminf
4157

4258

43-
## \brief Initializes list of material types and coordinate of location, initializes xyz boundary locations
44-
#
45-
# Note: Numpy arrays don't start blank and concatenate, where lists do, therefore plan to use lists, but convert to arrays using np.asarray(l) if needed to use array format
46-
#
47-
# \returns initializes self.MatInds and self.xBoundaries, self.yBoundaries, self.zBoundaries
48-
def initializeGeometryMemory(self):
49-
self._sampleNumberOfHyperplanes()
50-
self._sampleHyperplaneLocations()
51-
5259
## \brief compute average number of hyper-planes
5360
#
5461
# \computes average number of hyper-planes used to sample number of planes (Poisson)

0 commit comments

Comments
 (0)