Skip to content

Commit 7ac832a

Browse files
committed
TL: implemented Nusselt computation
1 parent 28a41f4 commit 7ac832a

File tree

1 file changed

+95
-40
lines changed
  • pySDC/playgrounds/dedalus/problems

1 file changed

+95
-40
lines changed

pySDC/playgrounds/dedalus/problems/rbc.py

Lines changed: 95 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ def log(msg):
330330
cls.log(" -- done !")
331331
except:
332332
log('Exception raised, triggering end of main loop.')
333+
if MPI_SIZE > 1:
334+
COMM_WORLD.Abort()
333335
raise
334336
finally:
335337
solver.log_stats()
@@ -433,6 +435,11 @@ def __init__(self, folder):
433435
else:
434436
raise NotImplementedError(f"{dim = }")
435437

438+
with open(f"{self.folder}/00_infoSimu.txt", "r") as f:
439+
lines = f.readlines()
440+
self.Ra = float(lines[0].split(" : ")[-1])
441+
self.Pr = float(lines[1].split(" : ")[-1])
442+
436443
def __del__(self):
437444
try:
438445
self.file.close()
@@ -554,17 +561,49 @@ def readFields(self, name, start=0, stop=None, step=1):
554561

555562
def getTimeSeries(self, which=["ke"], batchSize=None):
556563

564+
565+
if which == "all":
566+
which = ["ke", "NuV", "NuT", "NuB"]
567+
else:
568+
which = list(which)
569+
557570
series = {name: [] for name in which}
558571
avgAxes = 1 if self.dim==2 else (1, 2)
559572

560-
Iz = LagrangeApproximation(self.z).getIntegrationMatrix([(0, 1)])
573+
approx = LagrangeApproximation(self.z)
574+
mIz = approx.getIntegrationMatrix([(0, 1)])
575+
if set(which).intersection(["NuV", "NuT", "NuB"]):
576+
mDz = approx.getDerivativeMatrix()
577+
if "NuB" in which:
578+
mDzB = approx.getInterpolationMatrix([0]) @ mDz
579+
if "NuT" in which:
580+
mDzT = approx.getInterpolationMatrix([1]) @ mDz
561581

562582
for r in self.BatchRanges(self.nFields, maxSize=batchSize):
563583

584+
u = self.readFields("velocity", r.start, r.stop, r.step)
585+
w = u[:, -1]
586+
587+
if set(which).intersection(["NuV", "NuT", "NuB"]):
588+
b = self.readFields("buoyancy", r.start, r.stop, r.step)
589+
590+
if "NuV" in which:
591+
coeff = (self.Ra*self.Pr)**0.5
592+
integ = w*b*coeff - (mDz @ b[..., None])[..., 0]
593+
nuV = mIz @ integ.mean(axis=avgAxes)[..., None]
594+
series["NuV"].append(nuV.ravel())
595+
596+
if "NuT" in which:
597+
nuT = - mDzT @ b.mean(axis=avgAxes)[..., None]
598+
series["NuT"].append(nuT.ravel())
599+
600+
if "NuB" in which:
601+
nuB = - mDzB @ b.mean(axis=avgAxes)[..., None]
602+
series["NuB"].append(nuB.ravel())
603+
564604
if "ke" in which:
565-
u = self.readFields("velocity", r.start, r.stop, r.step)
566605
u **= 2
567-
ke = Iz @ u.sum(axis=1).mean(axis=avgAxes)[..., None]
606+
ke = mIz @ u.sum(axis=1).mean(axis=avgAxes)[..., None]
568607
series["ke"].append(ke.ravel())
569608

570609
for key, val in series.items():
@@ -666,8 +705,7 @@ def addSamples(current, new, nNew):
666705
return profiles
667706

668707

669-
def getBoundaryLayers(self,
670-
which=["uRMS", "bRMS"], profiles=None,
708+
def getBoundaryLayers(self, which=["uRMS", "bRMS"], profiles=None,
671709
start=0, stop=None, step=1, batchSize=None):
672710

673711
if which == "all":
@@ -724,8 +762,10 @@ def getSpectrum(self, which=["uv", "uh"], zVal="all",
724762
field = u[:, :-1]
725763
if name == "b":
726764
field = self.readFields("buoyancy", r.start, r.stop, r.step)[:, None, ...]
727-
avgDir = 2 if self.dim == 2 else (2, 3)
728-
field -= field.mean(axis=avgDir)[:, :, None, None]
765+
if self.dim == 3:
766+
field -= field.mean(axis=(2, 3))[:, :, None, None, :]
767+
else:
768+
field -= field.mean(axis=2)[:, :, None, :]
729769
# field.shape = (nT,nVar,nX[,nY],nZ)
730770

731771
if zVal != "all":
@@ -744,6 +784,9 @@ def getSpectrum(self, which=["uv", "uh"], zVal="all",
744784
# scaling
745785
s /= self.nX**2
746786

787+
# ignore last frequency (zero amplitude)
788+
s = s[:, :-1]
789+
747790
# 3D case
748791
elif self.dim == 3:
749792

@@ -850,45 +893,38 @@ def toVTR(self, idxFormat="{:06d}"):
850893
if __name__ == "__main__":
851894
import matplotlib.pyplot as plt
852895

853-
aspectRatio = 4 # Lx = Ly = A*Lz
854-
meshRatio = 0.5 # Nx/Lx = Ny/Ly = M*Nz/Lz
855-
resFactor = 1 # Nz = R*32
856-
Rayleigh = 1e6
857-
858-
# dirName = f"run_3D_A{aspectRatio}_M{meshRatio}_R{resFactor}_Ra{Rayleigh:.1e}"
859-
# dirName = dirName.replace("e+0", "e").replace("e+", "e")
860-
861-
# initFile = OutputFiles("run_3D_A4_M0.5_R1_Ra1e5")
862-
863-
# problem = RBCProblem3D.runSimulation(
864-
# dirName, 100, 1e-2/4, logEvery=20, dtWrite=1.0,
865-
# Rayleigh=Rayleigh,
866-
# aspectRatio=aspectRatio, meshRatio=meshRatio, resFactor=resFactor)
867-
896+
# dirName = "run_3D_A4_M0.5_R1_Ra1e6"
868897
dirName = "run_3D_A4_M0.5_R1_Ra1e6"
869-
dirName = "run_3D_A4_M1_R1"
870-
# dirName = "run_M4_R2"
898+
# dirName = "run_M4_R1"
899+
# dirName = "test_M4_R2"
871900
OutputFiles.VERBOSE = True
872901
output = OutputFiles(dirName)
873902

874-
if False:
875-
series = output.getTimeSeries()
903+
if True:
904+
series = output.getTimeSeries(which=["NuV", "NuT", "NuB"])
876905

877906
plt.figure("series")
878-
plt.plot(output.times, series["ke"], label="ke")
907+
for name, values in series.items():
908+
plt.plot(output.times, values, label=name)
879909
plt.legend()
880910

881-
if False:
882-
profiles = output.getProfiles(which="all", batchSize=None)
911+
start = 40
912+
913+
if True:
914+
which = ["bRMS"]
883915

884-
deltas = output.getBoundaryLayers(which="all", profiles=profiles)
916+
917+
Nu = series["NuV"][start:].mean()
918+
919+
profiles = output.getProfiles(
920+
which, start=start, batchSize=None)
921+
deltas = output.getBoundaryLayers(
922+
which, start=start, profiles=profiles)
885923

886924
for name, p in profiles.items():
887925
if "Mean" in name:
888926
plt.figure("Mean profiles")
889927
plt.plot(p, output.z, label=name)
890-
if name in deltas:
891-
plt.hlines(deltas[name], p.min(), p.max(), linestyles="--", colors="black")
892928
if "RMS" in name:
893929
plt.figure("RMS profiles")
894930
plt.plot(p, output.z, label=name)
@@ -901,12 +937,31 @@ def toVTR(self, idxFormat="{:06d}"):
901937
plt.xlabel("profile")
902938
plt.ylabel("z coord")
903939

904-
spectrum = output.getSpectrum(
905-
which=["b"], zVal="all", start=30, stop=None, batchSize=25)
906-
kappa = output.kappa
940+
zLog = np.logspace(np.log10(1/(100*Nu)), np.log(0.5), num=200)
941+
approx = LagrangeApproximation(output.z)
942+
mPz = approx.getInterpolationMatrix(zLog)
907943

908-
plt.figure("spectrum")
909-
for name, vals in spectrum.items():
910-
plt.loglog(kappa, vals, label=name)
911-
plt.loglog(kappa, kappa**(-5/3), '--k')
912-
plt.legend()
944+
bMean = (profiles["bMean"] + (1-profiles["bMean"][-1::-1]))/2
945+
bMean = mPz @ bMean
946+
947+
bRMS = (profiles["bRMS"] + profiles["bRMS"][-1::-1])/2
948+
bRMS = mPz @ bRMS
949+
950+
plt.figure("mean-log")
951+
plt.semilogx(zLog*Nu, bMean, label=dirName)
952+
plt.legend()
953+
954+
plt.figure("rms-log")
955+
plt.semilogx(zLog*Nu, bRMS, label=dirName)
956+
plt.legend()
957+
958+
if True:
959+
spectrum = output.getSpectrum(
960+
which=["b"], zVal="all", start=start, batchSize=None)
961+
kappa = output.kappa
962+
963+
plt.figure("spectrum")
964+
for name, vals in spectrum.items():
965+
plt.loglog(kappa[1:], vals[1:], label=name)
966+
plt.loglog(kappa[1:], kappa[1:]**(-5/3), '--k')
967+
plt.legend()

0 commit comments

Comments
 (0)