Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
008d320
-Add 10 magnetic lines traced around torus, input and dR_sep input po…
JorgeAMorales Oct 30, 2019
bc05e04
-Add test script for doctest
JorgeAMorales Oct 8, 2019
eaeb4f0
-Remove blank spaces
JorgeAMorales Oct 30, 2019
68bc5cb
-Modifications of tofuplot for magfieldlines
JorgeAMorales Oct 30, 2019
3c1a662
-Add init variable as input, initial point for manual magnetic field …
JorgeAMorales Oct 31, 2019
7eacddb
Merge remote-tracking branch 'origin/devel' into br/add_more_field_lines
lasofivec Nov 4, 2019
3d0fb11
[br/add_more_field_lines] Introduced xaxis reversal on field line tra…
Nov 6, 2019
de5dc6b
[Issue235] Reversed xaxis operational: solves the perpection issue bu…
Nov 6, 2019
d1c9e63
-Correction of hard coded correction for C3b campaign not valid in C4…
JorgeAMorales Nov 6, 2019
1c655fd
Merge branch 'devel' into br/add_more_field_lines
lasofivec Nov 6, 2019
bb8a2dc
-Avoid to change the sys path if test files are loaded from python co…
JorgeAMorales Nov 6, 2019
8a9544f
-Add separatrix plot and make other magnetic lines transparent when p…
JorgeAMorales Nov 6, 2019
a191896
-Respect of pep8
JorgeAMorales Nov 6, 2019
2192577
-Respect of pep8 2
JorgeAMorales Nov 6, 2019
2ab46fa
-Respect of pep8 3
JorgeAMorales Nov 6, 2019
94ac9a1
-Respect of pep8 4
JorgeAMorales Nov 6, 2019
08661c4
-Add strike points plot
JorgeAMorales Nov 7, 2019
6429203
-Changes on help of tofuplot.py
JorgeAMorales Nov 7, 2019
107f827
-Add Poincare plot and option to make the field line tracing without …
JorgeAMorales Nov 8, 2019
6b30f99
-Increased field line length
JorgeAMorales Nov 8, 2019
86e41d9
Merge branch 'devel' into br/add_more_field_lines
Nov 19, 2019
a7c7ef7
[br/add_more_field_lines] PEP8 Compliance
Nov 20, 2019
f837259
[br/add_more_field_lines] PEP8 Compliance 2
Nov 20, 2019
d739927
[br/add_more_field_lines] pop temporary path from sys.path in test_ma…
Nov 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 13 additions & 29 deletions tofu/geom/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3074,37 +3074,21 @@ def _get_phithetaproj_dist(

return dist, indStruct

def plot_phithetaproj_dist(
self,
refpt=None,
ntheta=None,
nphi=None,
theta=None,
phi=None,
cmap=None,
ax=None,
fs=None,
tit=None,
wintit=None,
draw=None,
):
dist, indStruct = self._get_phithetaproj_dist(
refpt=refpt, ntheta=ntheta, nphi=nphi, theta=theta, phi=phi
)
return _plot.Config_phithetaproj_dist(
self,
refpt,
dist,
indStruct,
cmap=cmap,
ax=ax,
fs=fs,
tit=tit,
wintit=wintit,
draw=draw,
)
def plot_phithetaproj_dist(self, refpt=None, ntheta=None, nphi=None,
theta=None, phi=None, cmap=None, invertx=None,
ax=None, fs=None, tit=None, wintit=None,
draw=None):
dist, indStruct = self._get_phithetaproj_dist(refpt=refpt,
ntheta=ntheta, nphi=nphi,
theta=theta, phi=phi)
return _plot.Config_phithetaproj_dist(self, refpt, dist, indStruct,
cmap=cmap, ax=ax, fs=fs,
tit=tit, wintit=wintit,
invertx=invertx, draw=draw)


def isInside(self, pts, In="(X,Y,Z)", log="any"):

""" Return a 2D array of bool

Equivalent to applying isInside to each Struct
Expand Down
6 changes: 5 additions & 1 deletion tofu/geom/_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,13 +692,15 @@ def Plot_Impact_3DPoly(T, Leg="", ax=None, Ang=_def.TorPAng,

def Config_phithetaproj_dist(config, refpt, dist, indStruct,
distonly=False,
cmap=None, vmin=None, vmax=None,
cmap=None, vmin=None, vmax=None, invertx=None,
ax=None, fs=None, cbck=(0.8,0.8,0.8,0.8),
tit=None, wintit=None, legend=None, draw=None):
if cmap is None:
cmap = 'touch'
lS = config.lStruct
indsu = np.unique(indStruct)
if invertx is None:
invertx = True

# set extent
ratio = refpt[0] / np.nanmin(dist)
Expand Down Expand Up @@ -745,6 +747,8 @@ def Config_phithetaproj_dist(config, refpt, dist, indStruct,
# labels.append( '%s_%s'%(lS[ii].Id.Cls, lS[ii].Id.Name) )
# dax['cross'][0].legend(handles, labels, frameon=False,
# bbox_to_anchor=(1.01,1.), loc=2, borderaxespad=0.)
if invertx is True:
dax['dist'][0].invert_xaxis()

if draw:
fig.canvas.draw()
Expand Down
6 changes: 3 additions & 3 deletions tofu/mag/equimap.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
import imas_west
except ImportError as err:
pass
# print(err)
print(err)
try:
import pywed as pw
except ImportError as err:
pass
# print(err)
print(err)

# Project modules
try:
import mag_ripple as mr
except ImportError as err:
pass
# print(err)
print(err)

__all__ = ['get']

Expand Down
136 changes: 111 additions & 25 deletions tofu/mag/magFieldLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def __init__(self, shot, run=0, occ=0, user='imas_public', machine='west'):
bounds_error=False)

def trace_mline(self, init_state, time, direction='FWD', \
length_line=None, stp=None):
length_line=None, stp=None, ripple=True):
'''
Traces the field line given a starting point.
Integration step defined by stp and maximum length of the field line
Expand All @@ -174,6 +174,7 @@ def trace_mline(self, init_state, time, direction='FWD', \
- time : array of times requested (list or numpy array)
- direction : direction of integration 'FWD' forward or 'REV' reverse
(string)
- ripple : take into account magnetic ripple or not (boolean)

output:
returns a dictionary containing:
Expand Down Expand Up @@ -209,7 +210,8 @@ def trace_mline(self, init_state, time, direction='FWD', \

# !!!!!!!!!!!!!!!!!!!!!
# HARD CODED CORRECTION
bt_intp_t *= -1
if (np.nanmean(bt_intp_t) > 0):
bt_intp_t *= -1
# !!!!!!!!!!!!!!!!!!!!!

# Interpolate current
Expand All @@ -236,7 +238,7 @@ def trace_mline(self, init_state, time, direction='FWD', \

for jj in range(init_state.shape[1]):
out_prime = self.integrate_solve_ivp(init_state[:, jj], \
direction, s, ds)
direction, s, ds, ripple)
out_prime['init_point'] = init_state[:, jj]
out_prime['time'] = self.ar_time[ii]
# Return list of dict
Expand All @@ -246,7 +248,7 @@ def trace_mline(self, init_state, time, direction='FWD', \

return outMagLine

def integrate_solve_ivp(self, init_state, direction, s, ds):
def integrate_solve_ivp(self, init_state, direction, s, ds, ripple=True):
'''
Integration step defined by stp and maximum length of the field line
defined by s.
Expand All @@ -258,6 +260,7 @@ def integrate_solve_ivp(self, init_state, direction, s, ds):
(string)
- s : field line maximum length
- ds : vector of steps
- ripple : boolean, take into account magnetic ripple or not

output:
returns a dictionary containing:
Expand All @@ -268,14 +271,26 @@ def integrate_solve_ivp(self, init_state, direction, s, ds):
- y : y coordinate (np.array)
- cp : collision point with the wall (list)
'''
if (direction=='FWD'):
sol = spode.solve_ivp(self.mfld3dcylfwd, [0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
elif (direction=='REV'):
sol = spode.solve_ivp(self.mfld3dcylrev, [0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
if (ripple):
if direction == 'FWD':
sol = spode.solve_ivp(self.mfld3dcylfwd, [0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
elif direction == 'REV':
sol = spode.solve_ivp(self.mfld3dcylrev, [0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
else:
if direction == 'FWD':
sol = spode.solve_ivp(self.mfld3dcylfwd_no_ripple,
[0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
elif direction == 'REV':
sol = spode.solve_ivp(self.mfld3dcylrev_no_ripple,
[0, s], init_state,
method='RK23', t_eval=ds,
events=self.hit_wall_circ)
sgf = sol.t
rgf = sol.y[0]
pgf = sol.y[1]
Expand Down Expand Up @@ -321,9 +336,43 @@ def mfld3dcylrev(self, s, state):
'''
R, P, Z = state
Br, Bt, Bz = self.b_field_interp(R, P, Z)
#Br=self.fBp_r(R,Z)[0]+self.fBt_r(P,self.ftheta(R,Z),R)
#Bt=self.fBt_t(P,self.ftheta(R,Z),R)
#Bz=self.fBp_z(R,Z)[0]
# Br=self.fBp_r(R,Z)[0]+self.fBt_r(P,self.ftheta(R,Z),R)
# Bt=self.fBt_t(P,self.ftheta(R,Z),R)
# Bz=self.fBp_z(R,Z)[0]
B = np.sqrt(Br*Br + Bz*Bz + Bt*Bt)
d_R = -Br/B
d_P = -Bt/B*1/R
d_Z = -Bz/B
return [d_R, d_P, d_Z]

def mfld3dcylfwd_no_ripple(self, s, state):
'''
Returns the right end side of the field line system of equations in
cyclindrical (R, Phi, Z) coord.
This is the case for forward integration.
'''
R, P, Z = state
Br, Bt, Bz = self.b_field_interp_no_ripple(R, P, Z)
# Br=self.fBp_r(R,Z)[0]+self.fBt_r(P,self.ftheta(R,Z),R)
# Bt=self.fBt_t(P,self.ftheta(R,Z),R)
# Bz=self.fBp_z(R,Z)[0]
B = np.sqrt(Br*Br + Bz*Bz + Bt*Bt)
d_R = Br/B
d_P = Bt/B*1/R
d_Z = Bz/B
return [d_R, d_P, d_Z]

def mfld3dcylrev_no_ripple(self, s, state):
'''
Returns the right end side of the field line system of equations in
cyclindrical (R, Phi, Z) coord.
This is the case for backward integration.
'''
R, P, Z = state
Br, Bt, Bz = self.b_field_interp_no_ripple(R, P, Z)
# Br=self.fBp_r(R,Z)[0]+self.fBt_r(P,self.ftheta(R,Z),R)
# Bt=self.fBt_t(P,self.ftheta(R,Z),R)
# Bz=self.fBp_z(R,Z)[0]
B = np.sqrt(Br*Br + Bz*Bz + Bt*Bt)
d_R = -Br/B
d_P = -Bt/B*1/R
Expand All @@ -340,14 +389,17 @@ def hit_wall_circ(self, s, state):
mat file
'''
R, P, Z = state
#if np.abs(Z)<=0.5 and R>3.01 and np.deg2rad(89.5)<=P<=np.deg2rad(90.5):
# return 0
#if np.abs(Z)<=0.5 and R>3.01 and np.deg2rad(179.5)<=P<=np.deg2rad(180.5):
# print('Got 2')
# return 0
#elif np.abs(Z)<=0.5 and R>3.01 and np.deg2rad(269.5)<=P<=np.deg2rad(270.5):
# print('Got 3')
# return 0
# if (np.abs(Z) <= 0.5 and R > 3.01
# and np.deg2rad(89.5) <= P <= np.deg2rad(90.5)):
# return 0
# if (np.abs(Z) <= 0.5 and R > 3.01
# and np.deg2rad(179.5) <= P <= np.deg2rad(180.5)):
# print('Got 2')
# return 0
# elif (np.abs(Z) <= 0.5 and R > 3.01
# and np.deg2rad(269.5) <= P <= np.deg2rad(270.5)):
# print('Got 3')
# return 0
if self.wall_ck==False:
Rc=2.460
Zc=0.0
Expand All @@ -362,10 +414,9 @@ def hit_wall_circ(self, s, state):

hit_wall_circ.terminal=True

def b_field_interp(self, R, Phi, Z, no_ripple=False):
def b_field_interp(self, R, Phi, Z):
''' Linear interpolation of B vector components at R, Phi, Z positions
'''

interp_points = np.vstack((R, Z)).transpose()

br_intp = self.br_lin_intp.__call__(interp_points)
Expand All @@ -384,6 +435,17 @@ def b_field_interp(self, R, Phi, Z, no_ripple=False):

return br_intp[0], bt_intp[0], bz_intp[0]

def b_field_interp_no_ripple(self, R, Phi, Z):
''' Linear interpolation of B vector components at R, Phi, Z positions
'''
interp_points = np.vstack((R, Z)).transpose()

br_intp = self.br_lin_intp.__call__(interp_points)
bt_intp = self.bt_lin_intp.__call__(interp_points)
bz_intp = self.bz_lin_intp.__call__(interp_points)

return br_intp[0], bt_intp[0], bz_intp[0]

def plot_trace(self, trace):
'''
Plots a summary of the magnetic field line trace.
Expand Down Expand Up @@ -511,3 +573,27 @@ def plot_trace_3D(self, trace):
ax.set_xlabel('x [m]'); ax.set_ylabel('y [m]'); ax.set_zlabel('z [m]')
plt.title('Magnetic field line trace')
plt.show()

def plot_poincare(self, trace_plt, tor_angle=0):
'''
Plots Poincare plot at given toroidal angle

input:
- trace_plt : the magneticl field line data for several points
one single time (dictionary)
'''

fig, ax = plt.subplots()

for ii in range(len(trace_plt)):
loc_cross = trace_plt[ii]['p'] % (tor_angle + 2*np.pi)
mask_cross = np.r_[False, loc_cross[1:]
< loc_cross[:-1]] & np.r_[loc_cross[:-1]
< loc_cross[1:],
False]
ax.plot(trace_plt[ii]['r'][mask_cross],
trace_plt[ii]['z'][mask_cross], 'o', markersize=3)

ax.set_aspect('equal')
ax.set_xlabel('R [m]')
ax.set_ylabel('Z [m]')
17 changes: 17 additions & 0 deletions tofu/mag/mag_ripple/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,20 @@
'''
Magnetic ripple
'''

import warnings
import traceback

try:
try:
from tofu.mag.mag_ripple import *
except Exception:
from .mag_ripple import *
del warnings, traceback
except Exception as err:
msg = str(traceback.format_exc())
msg += "\n\n => the optional sub-package is not usable\n"
warnings.warn(msg)
del msg, err

__all__ = ['mag_ripple']
Loading