Skip to content

Commit 6106b4f

Browse files
committed
TL: added function to check DNS with spectrum
1 parent 7ac832a commit 6106b4f

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

pySDC/playgrounds/dedalus/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ problems/run_*
55

66
scripts/*.sh
77
scripts/run_*
8+
scripts/init_*

pySDC/playgrounds/dedalus/problems/rbc.py

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -889,28 +889,101 @@ def toVTR(self, idxFormat="{:06d}"):
889889
u = self.readFieldAt(i)
890890
writeToVTR(template.format(i), u, coords, varNames)
891891

892+
def checkDNS(spectrum:np.ndarray, kappa:np.ndarray, sRatio:int=4, nThrow:int=0):
893+
r"""
894+
Check for a well-resolved DNS, by looking at an energy spectrum
895+
:math:`s(\kappa)` and doing a quadratic regression in log space
896+
on its tail :
897+
898+
.. math::
899+
\log(s_{tail}) \simeq
900+
a\log(\kappa_{tail})^2 + b\log(\kappa_{tail}) + c
901+
902+
where :math:`(\kappa_{tail},s_{tail})` is continuous subset of the
903+
mapping :math:`(\kappa,s)` for large values of :math:`\kappa`
904+
(i.e spectrum tail).
905+
If the quadratic regression produces a convex polynomial
906+
(i.e :math:`a > 0`) then the simulation is considered as under-resolved
907+
(no DNS).
908+
Per default, the tail is built considering the
909+
**last quarter of the spectrum**.
910+
911+
Parameters
912+
----------
913+
spectrum : np.ndarray
914+
Vector of the spectrum values :math:`s(\kappa)`.
915+
kappa : np.ndarray
916+
Vector of the wavenumber values :math:`\kappa`.
917+
sRatio : int, optional
918+
Spectrum ratio used to define the tail: if the spectrum has
919+
N values, then the tail is defined with the last N/sRatio values.
920+
The default is 4.
921+
nThrow : int, optional
922+
Number of higher kappa extremity spectrum values to not consider
923+
when defining the tail. The default is 1.
924+
925+
Returns
926+
-------
927+
results : dict
928+
Dictionnary containing the results, with keys :
929+
930+
- `DNS` : boolean indicating if the simulation is well resolved
931+
- `coeffs` : the :math:`a,b,c` regression coefficients, stored in a tuple
932+
- `kTail` : the :math:`\kappa_{tail}` values used for the regression
933+
- `sTail` : the :math:`s_{tail}` values used for the regression
934+
935+
"""
936+
spectrum = np.asarray(spectrum)
937+
kappa = np.asarray(kappa)
938+
assert spectrum.ndim == 1, "spectrum must be a 1D vector"
939+
assert kappa.shape == spectrum.shape, "kappa and spectrum must have the same shape"
940+
941+
nValues = kappa.size//sRatio
942+
sl = slice(-nValues-nThrow, -nThrow if nThrow else None)
943+
944+
kTail = kappa[sl]
945+
sTail = spectrum[sl]
946+
947+
y = np.log(sTail)
948+
x = np.log(kTail)
949+
950+
def fun(coeffs):
951+
a, b, c = coeffs
952+
return np.linalg.norm(y - a*x**2 - b*x - c)
953+
954+
res = sco.minimize(fun, [0, 0, 0])
955+
a, b, c = res.x
956+
957+
results = {
958+
"DNS": not a > 0,
959+
"coeffs": (a, b, c),
960+
"kTail": kTail,
961+
"sTail": sTail,
962+
}
963+
964+
return results
892965

893966
if __name__ == "__main__":
894967
import matplotlib.pyplot as plt
895968

896969
# dirName = "run_3D_A4_M0.5_R1_Ra1e6"
897-
dirName = "run_3D_A4_M0.5_R1_Ra1e6"
898-
# dirName = "run_M4_R1"
970+
dirName = "run_3D_A4_M1_R1_Ra1e6"
971+
# dirName = "run_M4_R2"
899972
# dirName = "test_M4_R2"
900973
OutputFiles.VERBOSE = True
901974
output = OutputFiles(dirName)
902975

903-
if True:
976+
if False:
904977
series = output.getTimeSeries(which=["NuV", "NuT", "NuB"])
905978

906979
plt.figure("series")
907980
for name, values in series.items():
908981
plt.plot(output.times, values, label=name)
909982
plt.legend()
910983

911-
start = 40
984+
start = 60
912985

913-
if True:
986+
if False:
914987
which = ["bRMS"]
915988

916989

@@ -957,11 +1030,20 @@ def toVTR(self, idxFormat="{:06d}"):
9571030

9581031
if True:
9591032
spectrum = output.getSpectrum(
960-
which=["b"], zVal="all", start=start, batchSize=None)
1033+
which=["uh"], zVal="all", start=start, batchSize=None)
9611034
kappa = output.kappa
9621035

1036+
check = checkDNS(spectrum["uh"], kappa)
1037+
print(f"DNS : {check['DNS']}")
1038+
a, b, c = check["coeffs"]
1039+
kTail = check["kTail"]
1040+
sTail = check["sTail"]
1041+
9631042
plt.figure("spectrum")
9641043
for name, vals in spectrum.items():
9651044
plt.loglog(kappa[1:], vals[1:], label=name)
1045+
plt.loglog(kTail, sTail, '.', c="black")
1046+
kTL = np.log(kTail)
1047+
plt.loglog(kTail, np.exp(a*kTL**2 + b*kTL + c), c="gray")
9661048
plt.loglog(kappa[1:], kappa[1:]**(-5/3), '--k')
9671049
plt.legend()

0 commit comments

Comments
 (0)