Skip to content

Commit 79b88a5

Browse files
committed
cleaner implementation of theta derivative
easier handling of 3-D/2-D helper arrays, like th2D, rr2D, th3D, rr3D
1 parent 2b8284c commit 79b88a5

4 files changed

Lines changed: 229 additions & 358 deletions

File tree

python/magic/checkpoint.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -745,14 +745,9 @@ def graph2rst(self, gr, filename='checkpoint_ave.from_chk'):
745745
# Calculate the toroidal potential using wr
746746
self.ztor = np.zeros_like(self.wpol)
747747

748-
th3D = np.zeros_like(gr.vr)
749-
rr3D = np.zeros_like(th3D)
750-
for i in range(self.n_theta_max):
751-
th3D[:, i, :] = gr.colatitude[i]
752-
for i in range(self.n_r_max):
753-
rr3D[:, :, i] = self.radius[i]
754-
s3D = rr3D*np.sin(th3D)
755-
omr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.vphi, order=4) -
748+
th3D = gr.colatitude[None, :, None]
749+
s3D = self.radius[None, None, :]*np.sin(gr.colatitude[None, :, None])
750+
omr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.vphi, colat=gr.colatitude, order=4) -
756751
phideravg(gr.vtheta, minc=self.minc))
757752

758753
for i in range(self.n_r_max):
@@ -790,7 +785,7 @@ def graph2rst(self, gr, filename='checkpoint_ave.from_chk'):
790785
self.radius[i]**2
791786

792787
self.btor = np.zeros_like(self.ztor)
793-
jr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.Bphi, order=4) -
788+
jr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.Bphi, colat=gr.colatitude, order=4) -
794789
phideravg(gr.Btheta, minc=self.minc))
795790

796791
for i in range(self.n_r_max):
@@ -819,16 +814,12 @@ def graph2rst(self, gr, filename='checkpoint_ave.from_chk'):
819814
# Calculate the toroidal potential using jr
820815
self.btor_ic = np.zeros_like(self.bpol_ic)
821816

822-
th3D = np.zeros_like(gr.Br_ic)
823-
rr3D = np.zeros_like(th3D)
824-
for i in range(self.n_theta_max):
825-
th3D[:, i, :] = gr.colatitude[i]
826-
for i in range(self.n_r_ic_max-1):
827-
rr3D[:, :, i] = self.radius_ic[i]
828-
rr3D[:, :, -1] = 1e-4
829-
s3D = rr3D*np.sin(th3D)
817+
th3D = gr.colatitude[None, :, None]
818+
s3D = self.radius_ic[None, None, :]*np.sin(gr.colatitude[None, :, None])
819+
s3D[:, :, -1] = 1e-4
830820
jr_ic = np.zeros_like(th3D)
831-
jr_ic = 1./s3D*(thetaderavg(np.sin(th3D)*gr.Bphi_ic, order=4) -
821+
jr_ic = 1./s3D*(thetaderavg(np.sin(th3D)*gr.Bphi_ic,
822+
colat=gr.colatitude, order=4) -
832823
phideravg(gr.Btheta_ic, minc=self.minc))
833824

834825
for i in range(self.n_r_ic_max):

python/magic/graph2vtk.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,10 @@ def __init__(self, gr, filename='out', scals=['vr', 'emag', 'tfluct'],
367367
gr.Btheta[..., ::-1]**2+\
368368
gr.Bphi[..., ::-1]**2)
369369
elif index == 3 or index == 7: # z-vorticity
370-
th3D = np.zeros_like(gr.vphi)
371-
rr3D = np.zeros_like(th3D)
372-
for i in range(gr.ntheta):
373-
th3D[:, i, :] = gr.colatitude[i]
374-
for i in range(gr.nr):
375-
rr3D[:, :, i] = gr.radius[i]
370+
th3D = gr.colatitude[None, :, None]
371+
rr3D = gr.radius[None, None, :]
376372
s3D = rr3D * np.sin(th3D)
377-
dtheta = thetaderavg(gr.vphi*s3D)
373+
dtheta = thetaderavg(gr.vphi*s3D, colat=gr.colatitude)
378374
dr = rderavg(gr.vphi*s3D, gr.radius)
379375
vs = gr.vr * np.sin(th3D) + gr.vtheta * np.cos(th3D) # 'vs'
380376
ds = np.sin(th3D)*dr + np.cos(th3D)/rr3D*dtheta
@@ -408,15 +404,11 @@ def __init__(self, gr, filename='out', scals=['vr', 'emag', 'tfluct'],
408404
self.scals[k, ...] = self.scals[k, ...]-\
409405
self.scals[k, ...].mean(axis=0)
410406
elif index == 8: # r-vorticity
411-
th3D = np.zeros_like(gr.vphi)
412-
rr3D = np.zeros_like(th3D)
413-
for i in range(gr.ntheta):
414-
th3D[:, i, :] = gr.colatitude[i]
415-
for i in range(gr.nr):
416-
rr3D[:, :, i] = gr.radius[i]
407+
th3D = gr.radius[None, None, :]
408+
rr3D = gr.colatitude[None, :, None]
417409
s3D = rr3D * np.sin(th3D)
418-
vortr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.vphi)-\
419-
phideravg(gr.vtheta, gr.minc))
410+
vortr = 1./s3D*(thetaderavg(np.sin(th3D)*gr.vphi, colat=gr.colatitude)-\
411+
phideravg(gr.vtheta, gr.minc))
420412
if deminc:
421413
self.scals[k, :, :, 0:gr.nr] = symmetrize(vortr[..., ::-1],
422414
gr.minc)

python/magic/libmagic.py

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ def rderavg(data, rad, exclude=False):
874874

875875
return der
876876

877-
def thetaderavg(data, order=4):
877+
def thetaderavg(data, colat=None, order=4):
878878
"""
879879
Theta-derivative of an input array (finite differences)
880880
@@ -883,42 +883,53 @@ def thetaderavg(data, order=4):
883883
884884
:param data: input array
885885
:type data: numpy.ndarray
886+
:param colat: colatitudes (when not specified a regular grid is assumed)
887+
:type colat: numpy.ndarray
886888
:param order: order of the finite-difference scheme (possible values are 2 or 4)
887889
:type order: int
888890
:returns: the theta-derivative of the input array
889891
:rtype: numpy.ndarray
890892
"""
893+
if colat is None:
894+
if len(data.shape) == 3:
895+
ntheta = data.shape[1]
896+
elif len(data.shape) == 2:
897+
ntheta = data.shape[0]
898+
th = np.linspace(0., np.pi, ntheta)
899+
else:
900+
th = colat
901+
891902
if len(data.shape) == 3: # 3-D
892-
ntheta = data.shape[1]
893-
dtheta = np.pi/(ntheta-1.)
894903
if order == 2:
895-
der = (np.roll(data, -1, axis=1)-np.roll(data, 1, axis=1))/(2.*dtheta)
896-
der[:, 0, :] = (data[:, 1, :]-data[:, 0, :])/dtheta
897-
der[:, -1, :] = (data[:, -1, :]-data[:, -2, :])/dtheta
904+
der = (np.roll(data,-1,axis=1)-np.roll(data,1,axis=1)) / \
905+
(np.roll(th[None, :, None],-1)-np.roll(th[None, :, None],1))
906+
der[:, 0, :] = (data[:, 1, :]-data[:, 0, :])/(th[1]-th[0])
907+
der[:, -1, :] = (data[:, -1, :]-data[:, -2, :])/(th[-1]-th[-2])
898908
elif order == 4:
899-
der = ( -np.roll(data,-2,axis=1) \
900-
+8.*np.roll(data,-1,axis=1) \
901-
-8.*np.roll(data, 1,axis=1) \
902-
+np.roll(data, 2,axis=1) )/(12.*dtheta)
903-
der[:, 1, :] = (data[:, 2, :]-data[:, 0, :])/(2.*dtheta)
904-
der[:, -2, :] = (data[:, -1, :]-data[:, -3, :])/(2.*dtheta)
905-
der[:, 0, :] = (data[:, 1, :]-data[:, 0, :])/dtheta
906-
der[:, -1, :] = (data[:, -1, :]-data[:, -2, :])/dtheta
909+
der = (-np.roll(data,-2,axis=1)+8.*np.roll(data,-1,axis=1) \
910+
-8.*np.roll(data, 1,axis=1)+np.roll(data, 2,axis=1)) / \
911+
(-np.roll(th[None, :, None],-2)+8*np.roll(th[None, :, None],-1) \
912+
-8*np.roll(th[None, :, None],1)+np.roll(th[None, :, None],2))
913+
der[:, 1, :] = (data[:, 2, :]-data[:, 0, :])/(th[2]-th[0])
914+
der[:, -2, :] = (data[:, -1, :]-data[:, -3, :])/(th[-1]-th[-3])
915+
der[:, 0, :] = (data[:, 1, :]-data[:, 0, :])/(th[1]-th[0])
916+
der[:, -1, :] = (data[:, -1, :]-data[:, -2, :])/(th[-1]-th[-2])
907917

908918
elif len(data.shape) == 2: #2-D
909-
ntheta = data.shape[0]
910-
dtheta = np.pi/(ntheta-1.)
911919
if order == 2:
912-
der = (np.roll(data, -1, axis=0)-np.roll(data, 1, axis=0))/(2.*dtheta)
913-
der[0, :] = (data[1, :]-data[0, :])/dtheta
914-
der[-1, :] = (data[-1, :]-data[-2, :])/dtheta
920+
der = (np.roll(data,-1,axis=0)-np.roll(data,1,axis=0)) / \
921+
(np.roll(th[:, None],-1)-np.roll(th[:, None],1))
922+
der[0, :] = (data[1, :]-data[0, :])/(th[1]-th[0])
923+
der[-1, :] = (data[-1, :]-data[-2, :])/(th[-1]-th[-2])
915924
elif order == 4:
916925
der = (-np.roll(data,-2,axis=0)+8.*np.roll(data,-1,axis=0)-\
917-
8.*np.roll(data,1,axis=0)+np.roll(data,2,axis=0))/(12.*dtheta)
918-
der[1, :] = (data[2, :]-data[0, :])/(2.*dtheta)
919-
der[-2, :] = (data[-1, :]-data[-3, :])/(2.*dtheta)
920-
der[0, :] = (data[1, :]-data[0, :])/dtheta
921-
der[-1, :] = (data[-1, :]-data[-2, :])/dtheta
926+
8.*np.roll(data,1,axis=0)+np.roll(data,2,axis=0)) / \
927+
(-np.roll(th[:, None],-2)+8*np.roll(th[:, None],-1)-\
928+
8.*np.roll(th[:, None],1)+np.roll(th[:, None],2))
929+
der[1, :] = (data[2, :]-data[0, :])/(th[2]-th[0])
930+
der[-2, :] = (data[-1, :]-data[-3, :])/(th[-1]-th[-3])
931+
der[0, :] = (data[1, :]-data[0, :])/(th[1]-th[0])
932+
der[-1, :] = (data[-1, :]-data[-2, :])/(th[-1]-th[-2])
922933

923934
return der
924935

@@ -953,15 +964,11 @@ def zderavg(data, rad, colat=None, exclude=False):
953964
th = np.linspace(0., np.pi, ntheta)
954965

955966
if len(data.shape) == 3: # 3-D
956-
thmD = np.zeros_like(data)
957-
for i in range(ntheta):
958-
thmD[:,i,:] = th[i]
967+
thmD = th[None, :, None]
959968
elif len(data.shape) == 2: # 2-D
960-
thmD = np.zeros((ntheta, nr), np.float64)
961-
for i in range(ntheta):
962-
thmD[i, :] = th[i]
969+
thmD = th[None, :]
963970

964-
dtheta = thetaderavg(data)
971+
dtheta = thetaderavg(data, colat=colat)
965972
dr = rderavg(data, rad, exclude)
966973
dz = np.cos(thmD)*dr - np.sin(thmD)/rad*dtheta
967974

@@ -997,15 +1004,11 @@ def sderavg(data, rad, colat=None, exclude=False):
9971004
th = np.linspace(0., np.pi, ntheta)
9981005

9991006
if len(data.shape) == 3: # 3-D
1000-
thmD = np.zeros_like(data)
1001-
for i in range(ntheta):
1002-
thmD[:,i,:] = th[i]
1007+
thmD = th[None, :, None]
10031008
elif len(data.shape) == 2: # 2-D
1004-
thmD = np.zeros((ntheta, nr), np.float64)
1005-
for i in range(ntheta):
1006-
thmD[i, :] = th[i]
1009+
thmD = th[None, :]
10071010

1008-
dtheta = thetaderavg(data)
1011+
dtheta = thetaderavg(data, colat=colat)
10091012
dr = rderavg(data, rad, exclude)
10101013
ds = np.sin(thmD)*dr + np.cos(thmD)/rad*dtheta
10111014

0 commit comments

Comments
 (0)