@@ -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}"):
850893if __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