Skip to content

Commit e1bb2c8

Browse files
authored
Handle Vcoils in plot_eddy
- Fixed bug when using linear solver with distribution specified on voltage coils - Correct units in `get_jtor_plasma()`
2 parents 872468c + 999ef95 commit e1bb2c8

4 files changed

Lines changed: 43 additions & 12 deletions

File tree

src/examples/TokaMaker/ITER/ITER_disruption_forces.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@
402402
"sim_time = [0.0]\n",
403403
"mygs.settings.pm=False\n",
404404
"mygs.update_settings()\n",
405-
"mygs.set_coil_currents()\n",
405+
"mygs.set_coil_currents({})\n",
406406
"for i in range(100):\n",
407407
" if i == 40:\n",
408408
" dt = CQ_time/5.0\n",

src/physics/grad_shaf.F90

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,12 +1806,14 @@ subroutine gs_wall_source(self,dpsi_dt,b)
18061806
CLASS(oft_vector), intent(inout) :: dpsi_dt !< \f$ \psi \f$ at start of step
18071807
CLASS(oft_vector), intent(inout) :: b !< Resulting source field
18081808
real(r8), pointer, dimension(:) :: btmp,btmp_coils
1809-
real(8) :: psitmp,goptmp(3,3),det,pt(3),v,ffp(3),t1,nturns
1809+
real(8) :: psitmp,goptmp(3,3),det,pt(3),v,ffp(3),t1,nturns,cond_norm
18101810
real(8), allocatable :: rhs_loc(:),cond_fac(:),rop(:),vcache(:),eta_reg(:),reg_source(:)
18111811
real(8), pointer :: psi_vals(:),coil_vals(:)
1812-
integer(4) :: j,m,l,k,kk,iCond
1812+
integer(4) :: j,m,l,k,kk,iCond,jc
18131813
integer(4), allocatable :: j_lag(:)
18141814
logical :: curved
1815+
CLASS(oft_scalar_bfem), POINTER :: lag_rep
1816+
lag_rep=>self%fe_rep
18151817
! t1=omp_get_wtime()
18161818
!---
18171819
NULLIFY(btmp,btmp_coils,psi_vals,coil_vals)
@@ -1839,7 +1841,7 @@ subroutine gs_wall_source(self,dpsi_dt,b)
18391841
END DO
18401842
END IF
18411843
!---
1842-
!$omp parallel private(rhs_loc,j_lag,curved,goptmp,v,m,det,pt,psitmp,l,rop,nturns)
1844+
!$omp parallel private(rhs_loc,j_lag,curved,goptmp,v,m,det,pt,psitmp,l,rop,nturns,cond_norm,jc)
18431845
allocate(rhs_loc(self%fe_rep%nce+self%ncoils))
18441846
allocate(rop(self%fe_rep%nce))
18451847
allocate(j_lag(self%fe_rep%nce))
@@ -1863,7 +1865,11 @@ subroutine gs_wall_source(self,dpsi_dt,b)
18631865
IF(self%Rcoils(l)<=0.d0)CYCLE
18641866
nturns = self%coil_nturns(self%fe_rep%mesh%reg(j),l)
18651867
IF(ABS(nturns)>1.d-8)THEN
1866-
rhs_loc(self%fe_rep%nce+l)=rhs_loc(self%fe_rep%nce+l)+mu0*2.d0*pi*psitmp*nturns*det
1868+
cond_norm=0.d0
1869+
do jc=1,lag_rep%nce ! Loop over degrees of freedom
1870+
cond_norm = cond_norm + self%dist_coil(j_lag(jc),l)*rop(jc)
1871+
end do
1872+
rhs_loc(self%fe_rep%nce+l)=rhs_loc(self%fe_rep%nce+l)+mu0*2.d0*pi*psitmp*nturns*cond_norm*det
18671873
END IF
18681874
END DO
18691875
IF(eta_reg(self%fe_rep%mesh%reg(j))<0.d0)CYCLE

src/physics/grad_shaf_td.F90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ subroutine apply_rhs(self,a,b)
482482
class(oft_vector), intent(inout) :: b !< Result of metric function
483483
integer(i4) :: i,m,jr,jc
484484
integer(i4), allocatable :: j(:)
485-
real(r8) :: vol,det,goptmp(3,3),elapsed_time,pt(3),eta_tmp,psi_tmp,eta_source,psi_lim,psi_max
485+
real(r8) :: vol,det,goptmp(3,3),elapsed_time,pt(3),eta_tmp,psi_tmp,eta_source,psi_lim,psi_max,cond_norm
486486
real(8) :: max_tmp,lim_tmp,vcont_val,nturns
487487
real(r8), allocatable :: rop(:),gop(:,:),lop(:,:),vals_loc(:),reg_source(:)
488488
real(r8), pointer, dimension(:) :: pol_vals,rhs_vals
@@ -528,7 +528,7 @@ subroutine apply_rhs(self,a,b)
528528
!------------------------------------------------------------------------------
529529
! Operator integration
530530
!------------------------------------------------------------------------------
531-
!$omp parallel private(j,vals_loc,rop,gop,det,curved,goptmp,m,vol,jr,jc,pt,eta_tmp,psi_tmp,eta_source,nturns)
531+
!$omp parallel private(j,vals_loc,rop,gop,det,curved,goptmp,m,vol,jr,jc,pt,eta_tmp,psi_tmp,eta_source,nturns,cond_norm)
532532
allocate(j(lag_rep%nce),vals_loc(lag_rep%nce+self%gs_eq%ncoils)) ! Local DOF and matrix indices
533533
allocate(rop(lag_rep%nce),gop(3,lag_rep%nce)) ! Reconstructed gradient operator
534534
!$omp do schedule(static,1)
@@ -561,11 +561,11 @@ subroutine apply_rhs(self,a,b)
561561
IF(self%gs_eq%Rcoils(jr)<=0.d0)CYCLE
562562
nturns = self%gs_eq%coil_nturns(mesh%reg(i),jr)
563563
IF(ABS(nturns)>1.d-8)THEN
564-
eta_source=0.d0
564+
cond_norm=0.d0
565565
do jc=1,lag_rep%nce ! Loop over degrees of freedom
566-
eta_source = eta_source + self%gs_eq%dist_coil(j(jc),jr)*rop(jc)
566+
cond_norm = cond_norm + self%gs_eq%dist_coil(j(jc),jr)*rop(jc)
567567
end do
568-
vals_loc(lag_rep%nce+jr)=vals_loc(lag_rep%nce+jr)+mu0*2.d0*pi*psi_tmp*nturns*eta_source*det
568+
vals_loc(lag_rep%nce+jr)=vals_loc(lag_rep%nce+jr)+mu0*2.d0*pi*psi_tmp*nturns*cond_norm*det
569569
END IF
570570
END DO
571571
end do
@@ -1438,4 +1438,4 @@ subroutine apply_wrap(self,a,b)
14381438
DEALLOCATE(tmp_vec)
14391439
DEBUG_STACK_POP
14401440
end subroutine apply_wrap
1441-
end module oft_gs_td
1441+
end module oft_gs_td

src/python/OpenFUSIONToolkit/TokaMaker/_core.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ def __init__(self,OFT_env):
108108
self.coil_sets = {}
109109
## Virtual coils, if present (currently only `'#VSC'`)
110110
self._virtual_coils = {'#VSC': {'id': -1 ,'facs': {}}}
111+
## Voltage coils dictionary. Currently only used for plotting on python side.
112+
self._vcoils = {}
111113
## Coil set names in order of id number
112114
self.coil_set_names = []
113115
## Distribution coils, only (currently) saved for plotting utility
@@ -182,6 +184,7 @@ def reset(self):
182184
self._cond_dict = {}
183185
self._vac_dict = {}
184186
self._coil_dict = {}
187+
self._vcoils = {}
185188
self.coil_sets = {}
186189
self._virtual_coils = {'#VSC': {'id': -1 ,'facs': {}}}
187190
self._F0 = 0.0
@@ -644,6 +647,8 @@ def set_vcoils(self,coil_resistivities):
644647
tokamaker_set_vcoil(self._tMaker_ptr,res_array,error_string)
645648
if error_string.value != b'':
646649
raise Exception(error_string.value)
650+
#Merge dicts and overwrite with new values where necessary. Only used for plotting.
651+
self._vcoils = self._vcoils | coil_resistivities
647652

648653
def init_psi(self, r0=-1.0, z0=0.0, a=0.0, kappa=0.0, delta=0.0, curr_source=None):
649654
r'''! Initialize \f$\psi\f$ using uniform current distributions
@@ -1098,7 +1103,7 @@ def get_jtor_plasma(self):
10981103
tokamaker_get_jtor(self._tMaker_ptr,curr,error_string)
10991104
if error_string.value != b'':
11001105
raise Exception(error_string.value)
1101-
return curr/mu0
1106+
return curr
11021107

11031108
def get_psi(self,normalized=True):
11041109
r'''! Get poloidal flux values on node points
@@ -1625,6 +1630,16 @@ def get_conductor_currents(self,psi,cell_centered=False):
16251630
if cell_centered:
16261631
mesh_currents[mask_tmp] = numpy.sum(curr[self.lc[mask_tmp,:]],axis=1)/3.0
16271632
mask = numpy.logical_or(mask,mask_tmp)
1633+
1634+
# Treat vcoils as conductors when looking at induced currents
1635+
for coil_name, coil_obj in self.coil_sets.items():
1636+
if coil_name in self._vcoils.keys():
1637+
for sub_coil in coil_obj["sub_coils"]:
1638+
mask_tmp = self.reg == sub_coil['reg_id']
1639+
if cell_centered:
1640+
mesh_currents[mask_tmp] = numpy.mean(curr[self.lc[mask_tmp]],axis=1)
1641+
mask = numpy.logical_or(mask,mask_tmp)
1642+
16281643
if cell_centered:
16291644
return mask, mesh_currents
16301645
else:
@@ -1663,6 +1678,16 @@ def get_conductor_source(self,dpsi_dt):
16631678
if cond_reg.get('noncontinuous',False):
16641679
mesh_currents[mask_tmp] -= (mesh_currents[mask_tmp]*area[mask_tmp]).sum()/area[mask_tmp].sum()
16651680
mask = numpy.logical_or(mask,mask_tmp)
1681+
1682+
# Treat vcoils as conductors when looking at induced currents
1683+
for coil_name, coil_obj in self.coil_sets.items():
1684+
if coil_name in self._vcoils.keys():
1685+
for sub_coil in coil_obj["sub_coils"]:
1686+
mask_tmp = self.reg == sub_coil['reg_id']
1687+
field_tmp = -dpsi_dt/self._vcoils[coil_name]
1688+
mesh_currents[mask_tmp] = numpy.mean(field_tmp[self.lc[mask_tmp]],axis=1)
1689+
mask = numpy.logical_or(mask,mask_tmp)
1690+
16661691
return mask, mesh_currents
16671692

16681693
def plot_eddy(self,fig,ax,psi=None,dpsi_dt=None,nlevels=40,colormap='jet',clabel=r'$J_w$ [$A/m^2$]',symmap=False):

0 commit comments

Comments
 (0)