Skip to content

Commit 606872f

Browse files
committed
TL: update from office computer
1 parent b937be0 commit 606872f

File tree

1 file changed

+164
-76
lines changed
  • pySDC/playgrounds/dedalus/problems

1 file changed

+164
-76
lines changed

pySDC/playgrounds/dedalus/problems/rbc.py

Lines changed: 164 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ def printSpaceDistr(self):
376376
MPI.COMM_WORLD.Barrier()
377377

378378

379+
380+
379381
class OutputFiles():
380382
"""
381383
Utility class used to load and post-process solution
@@ -389,7 +391,7 @@ def __init__(self, folder):
389391
assert len(fileNames) == 1, "cannot read fields splitted in several files"
390392
self.fileName = fileNames[0]
391393

392-
self._file = None # temporary buffer to store the HDF5 file
394+
self.file = h5py.File(self.fileName, mode='r')
393395

394396
vData0 = self.file['tasks']['velocity']
395397
self.x = np.array(vData0.dims[2]["x"])
@@ -403,15 +405,9 @@ def __init__(self, folder):
403405
else:
404406
raise NotImplementedError(f"{dim = }")
405407

406-
@property
407-
def file(self):
408-
if self.file is None:
409-
self._file = h5py.File(self.fileName, mode='r')
410-
return self._file
411-
412408
def __del__(self):
413409
try:
414-
self._file.close()
410+
self.file.close()
415411
except:
416412
pass
417413

@@ -459,15 +455,7 @@ def bData(self):
459455
def pData(self):
460456
return self.file['tasks']['pressure']
461457

462-
@property
463-
def times(self):
464-
return np.array(self.vData.dims[0]["sim_time"])
465-
466-
@property
467-
def nFields(self):
468-
return len(self.times)
469-
470-
def readFields(self, iField):
458+
def readFieldAt(self, iField):
471459
data = self.file["tasks"]
472460
fields = [
473461
data["velocity"][iField, 0],
@@ -481,7 +469,53 @@ def readFields(self, iField):
481469
]
482470
return np.array(fields)
483471

484-
def readField(self, name, iBeg=0, iEnd=None, step=1, verbose=False):
472+
@property
473+
def times(self):
474+
return np.array(self.vData.dims[0]["sim_time"])
475+
476+
@property
477+
def nFields(self):
478+
return len(self.times)
479+
480+
481+
class BatchRanges():
482+
483+
def __init__(self, *args, maxSize=None, start=0, step=1):
484+
assert len(args) < 5
485+
try:
486+
start, stop, step, maxSize = args
487+
except:
488+
try:
489+
start, stop, step = args
490+
except:
491+
try:
492+
start, stop = args
493+
except:
494+
stop, = args
495+
self.range = range(start, stop, step)
496+
self.maxSize = stop if not maxSize else maxSize
497+
498+
@property
499+
def start(self):
500+
return self.range.start
501+
502+
@property
503+
def stop(self):
504+
return self.range.stop
505+
506+
@property
507+
def step(self):
508+
return self.range.step
509+
510+
def __len__(self):
511+
return len(self.range)
512+
513+
def __iter__(self):
514+
for i in range(self.start, self.stop, self.step*self.maxSize):
515+
yield range(i, min(i+self.maxSize*self.step, self.stop), self.step)
516+
517+
518+
def readFields(self, name, start=0, stop=None, step=1, verbose=False):
485519
if verbose: print(f"Reading {name} from hdf5 file {self.fileName}")
486520
if name == "velocity":
487521
fData = self.vData
@@ -491,60 +525,101 @@ def readField(self, name, iBeg=0, iEnd=None, step=1, verbose=False):
491525
fData = self.pData
492526
else:
493527
raise ValueError(f"cannot read {name} from file")
494-
shape = fData.shape
495-
if iEnd is None:
496-
iEnd = shape[0]
497-
rData = range(iBeg, iEnd, step)
498-
data = np.empty((len(rData), *shape[1:]), dtype=float)
499-
for i, iData in enumerate(rData):
500-
if verbose: print(f" -- field {i+1}/{len(rData)}, idx={iData}")
501-
data[i] = fData[iData]
528+
if stop is None:
529+
stop = self.nFields
530+
if verbose: print(f" -- field[{start}:{stop}:{step}]")
531+
data = fData[start:stop:step]
502532
if verbose: print(" -- done !")
503533
return data
504534

505535

506-
def getMeanProfiles(self, buoyancy=False, bRMS=False, pressure=False,
507-
iBeg=0, iEnd=None, step=1, verbose=False):
508-
"""
509-
Args:
510-
iFile (int): file index
511-
buoyancy (bool, optional): return buoyancy profile. Defaults to False.
512-
pressure (bool, optional): return pressure profile. Defaults to False.
513-
514-
Returns:
515-
profilr (list): mean profiles of velocity, buoyancy and pressure
516-
"""
517-
profile = []
518-
axes = 1 if self.dim==2 else (1, 2)
519-
velocity = self.readField("velocity", iBeg, iEnd, step, verbose)
520-
521-
# Horizontal mean velocity amplitude
522-
uH = velocity[:, :self.dim-1]
523-
meanH = ((uH**2).sum(axis=1)**0.5).mean(axis=axes)
524-
profile.append(meanH)
525-
526-
# Vertical mean velocity
527-
uV = velocity[:, -1]
528-
meanV = np.mean(abs(uV), axis=axes)
529-
profile.append(meanV)
530-
531-
532-
533-
# uRMS = (ux**2 + uz**2).mean(axis=(0, 1))**0.5
534-
# bRMS = ((b - b.mean(axis=(0, 1)))**2).mean(axis=(0, 1))**0.5
535-
536-
if bRMS or buoyancy:
537-
b = self.readField("buoyancy", iBeg, iEnd, step, verbose)
538-
if buoyancy:
539-
profile.append(np.mean(b, axis=axes))
540-
if bRMS:
541-
diff = b - b.mean(axis=axes)[(slice(None), *[None]*(self.dim-1), slice(None))]
542-
rms = (diff**2).mean(axis=axes)**0.5
543-
profile.append(rms)
544-
if pressure:
545-
p = self.readField("pressure", iBeg, iEnd, step, verbose)
546-
profile.append(np.mean(p, axis=axes)) # (time_index, Nz)
547-
return profile
536+
def getProfiles(self, which=["uRMS", "bRMS"],
537+
start=0, stop=None, step=1, batchSize=None,
538+
verbose=False):
539+
avgAxes = (0, 1) if self.dim==2 else (0, 1, 2)
540+
formula = {
541+
"u" : "u.sum(axis=1)",
542+
"uv": "u[:, -1]",
543+
"uh": "u[:, :-1].sum(axis=1)",
544+
"b": "b",
545+
"p": "p"
546+
}
547+
if which == "all":
548+
which = [var+"Mean" for var in formula.keys()] \
549+
+ [var+"RMS" for var in formula.keys()]
550+
profiles = {name: np.zeros(self.nZ) for name in which}
551+
if stop is None:
552+
stop = self.nFields
553+
554+
nSamples = 0
555+
def addSamples(current, new, nNew):
556+
current *= nSamples
557+
new *= nNew
558+
current += new
559+
current /= (nSamples + nNew)
560+
561+
for r in self.BatchRanges(start, stop, step, batchSize):
562+
563+
bSize = len(r)
564+
565+
# Read required data
566+
if set(["uRMS", "uvRMS", "uhRMS",
567+
"uMean", "uvMean", "uhMean"]).intersection(which):
568+
u = self.readFields("velocity", r.start, r.stop, r.step, verbose)
569+
if set(["bRMS", "bMean"]).intersection(which):
570+
b = self.readFields("buoyancy", r.start, r.stop, r.step, verbose)
571+
if set(["pRMS", "pMean"]).intersection(which):
572+
p = self.readFields("pressure", r.start, r.stop, r.step, verbose)
573+
574+
# Mean profiles
575+
if "uMean" in which:
576+
uMean = u.sum(axis=1).mean(axis=avgAxes)
577+
addSamples(profiles["uMean"], uMean, bSize)
578+
if "uvMean" in which:
579+
uvMean = u[:, -1].mean(axis=avgAxes)
580+
addSamples(profiles["uvMean"], uvMean, bSize)
581+
if "uhMean" in which:
582+
uhMean = u[:, :-1].sum(axis=1).mean(axis=avgAxes)
583+
addSamples(profiles["uhMean"], uhMean, bSize)
584+
if "bMean" in which:
585+
bMean = b.mean(axis=avgAxes)
586+
addSamples(profiles["bMean"], bMean, bSize)
587+
if "pMean" in which:
588+
pMean = p.mean(axis=avgAxes)
589+
addSamples(profiles["pMean"], pMean, bSize)
590+
591+
# RMS profiles
592+
# -- inplace power 2 first
593+
try: u **= 2
594+
except: pass
595+
try: b **= 2
596+
except: pass
597+
try: p **= 2
598+
except: pass
599+
600+
if "uRMS" in which:
601+
uRMS = u.sum(axis=1).mean(axis=avgAxes)
602+
addSamples(profiles["uRMS"], uRMS, bSize)
603+
if "uvRMS" in which:
604+
uvRMS = u[:, -1].mean(axis=avgAxes)
605+
addSamples(profiles["uvRMS"], uvRMS, bSize)
606+
if "uhRMS" in which:
607+
uhRMS = u[:, :-1].sum(axis=1).mean(axis=avgAxes)
608+
addSamples(profiles["uhRMS"], uhRMS, bSize)
609+
if "bRMS" in which:
610+
bRMS = b.mean(axis=avgAxes)
611+
addSamples(profiles["bRMS"], bRMS, bSize)
612+
if "pRMS" in which:
613+
pRMS = p.mean(axis=avgAxes)
614+
addSamples(profiles["pRMS"], pRMS, bSize)
615+
616+
nSamples += bSize
617+
618+
for name, val in profiles.items():
619+
if "RMS" in name:
620+
val **= 0.5
621+
profiles["nSamples"] = nSamples
622+
return profiles
548623

549624

550625
def getLayersQuantities(self, iBeg=0, iEnd=None, step=1, verbose=False):
@@ -668,7 +743,7 @@ def computeMeanSpectrum(uValues, xGrid=None, zGrid=None, verbose=False):
668743
return energy_spectrum
669744

670745

671-
def getMeanSpectrum(self, iFile:int, iBeg=0, iEnd=None, step=1, verbose=False, batchSize=5):
746+
def getMeanSpectrum(self, iFile:int, iBeg=0, iEnd=None, step=1, batchSize=5, verbose=False):
672747
"""
673748
Mean spectrum from a given output file
674749
@@ -700,7 +775,7 @@ def getMeanSpectrum(self, iFile:int, iBeg=0, iEnd=None, step=1, verbose=False, b
700775
if verbose:
701776
print(f" -- computing for fields in range ({iBegSub},{iEndSub},{stepSub})")
702777
velocity = self.readField(iFile, "velocity", iBegSub, iEndSub, stepSub, verbose)
703-
spectra += computeMeanSpectrum(velocity, verbose=verbose, xGrid=self.x, zGrid=self.z)
778+
spectra += self.computeMeanSpectrum(velocity, verbose=verbose, xGrid=self.x, zGrid=self.z)
704779
return np.concatenate(spectra)
705780

706781

@@ -763,19 +838,32 @@ def toVTR(self, idxFormat="{:06d}"):
763838

764839

765840
if __name__ == "__main__":
766-
import scipy.optimize as sco
767-
768-
from pySDC.playgrounds.dedalus.problems.utils import OutputFiles
769-
# from qmat.lagrange import LagrangeApproximation
770841
import matplotlib.pyplot as plt
771842

772843
dirName = "run_3D_A4_R1_M1"
773844

774845
problem = RBCProblem3D.runSimulation(
775-
dirName, 100, 1e-2/2, logEvery=20, dtWrite=1.0,
846+
dirName, 100, 1e-2/4, logEvery=20, dtWrite=1.0,
776847
aspectRatio=4, resFactor=1, meshRatio=1)
777848

778-
# output = OutputFiles(dirName)
849+
output = OutputFiles(dirName)
850+
profiles = output.getProfiles(which="all", verbose=True, batchSize=25)
851+
852+
for name, p in profiles.items():
853+
if "Mean" in name:
854+
plt.figure("Mean profiles")
855+
plt.plot(p, output.z, label=name)
856+
if "RMS" in name:
857+
plt.figure("RMS profiles")
858+
plt.plot(p, output.z, label=name)
859+
860+
for pType in ["Mean", "RMS"]:
861+
plt.figure(f"{pType} profiles")
862+
plt.legend()
863+
plt.xlabel("profile")
864+
plt.ylabel("z coord")
865+
866+
779867
# approx = LagrangeApproximation(output.z)
780868

781869
# nThrow = 20

0 commit comments

Comments
 (0)