Plasma State Pitfalls
Here are some open holes that I (and others) have recently fallen
into. Nota bene:
1) Defining coordinate grids in Plasma State. Coordinate
grids have different properties and requirements in Plasma State than
other arrays. Quoting Doug McCune:
To completely define a grid, there are 3
steps:
1) define its size:
ps%nrho_icrf = inum
2) allocate the grid and associated profile arrays:
call ps_alloc_plasma_state(ierr, state=ps)
(state argument optional).
3) fill in the grid's individual values. E.g. for an evenly spaced grid:
do ii=1,inum
ps%rho_icrf(ii) = (ii-1)*1.0_rspec/(inum-1)
enddo
1) define its size:
ps%nrho_icrf = inum
2) allocate the grid and associated profile arrays:
call ps_alloc_plasma_state(ierr, state=ps)
(state argument optional).
3) fill in the grid's individual values. E.g. for an evenly spaced grid:
do ii=1,inum
ps%rho_icrf(ii) = (ii-1)*1.0_rspec/(inum-1)
enddo
ALL THREE STEPS must be completed before
calling ps_store_plasma_state.
Our mistake was to call ps_store_plasma_state before filling the
grid with data and attempting to fill it later. Whereas other
arrays evolve in time, grids do not. They are defined for
the whole simulation and must be initialized with the grid values
before being stored. Different grids can be defined at different
times with multiple calls to ps_alloc_plasma state and
ps_store_plasma_state, but a single grid needs to be done completely
before calling ps_store_plasma_state.
2) There are several different types (7 at last count) of plasma
species in the state. [thermal, fast, minority, , all] and each
exists as a separate list. Some of these lists can have
zero species in them, but species "all" has to be set or you
will get plasma state errors. "all" is a separate list
containing a union of all the other lists. You set "all"
by just calling the function ps_merge_speices_lists(ierr). It is
required that you call ps_merge_speices_lists even if you only have
thermal ion species. If you don't do this you will get Plasma
State internal error messages that look like:
?ps_name_check: blank names detected in:
all_name
list is dimensioned ( 0 : 1 ).
...name # 0 is blank.
...name # 1 is blank.
list is dimensioned ( 0 : 1 ).
...name # 0 is blank.
...name # 1 is blank.
(Default
Message) error "state_file_write" in routine
PS_STORE_PLASMA_STATE
failed to
write state to file: TEST_monitor_ps.cdf
3) Every plasma species has: name (character), charge,
mass, type, atomic charge when fully stripped. I'm not sure
whether the state requires that all of these be set, but certainly the
name must be. There exists a handy function in the plasma state
called ps_label_spectype that will set all these things for you.
The calling sequence is
SUBROUTINE
ps_label_spectype(iZatom,iZcharge,iAMU,itype, &
label, qatom, qcharge, mass)
!--------------------------------
! D. McCune Oct 10 2006
! module subroutine for plasma species labeling
!src
! ...to be used during initialization of plasma state system at the
! start of a simulation...
!
! Mod dmc Mar 2007-- DELETED: tokamakium support.
!--------------------------------
integer, intent(in) :: iZatom ! atomic number: 1 for H, 2 for He, ...
! special: -1 for electrons
integer, intent(in) :: iZcharge ! ionic charge btw 1 and iZatom
! ignored for electrons
integer, intent(in) :: iAMU ! atomic weight in AMU, nearest integer
! ignored unless 1 <= iZatom <= 2
integer, intent(inout) :: iType ! species "type", defined as follows:
! For thermal species, itype can be input or output:
! if itype.eq.-1: electrons (thermal; blank suffix)
! if 1.le.itype.le.3: thermal ion species (blank suffix)
!
! if itype.eq.0: *modify on output* according to value of iZatom:
! -1 for electrons (iZatom=-1)
! 1 for thermal ions (1 <= iZatom <= 2)
! 2 for "impurity" thermal ions (iZatom > 2)
!
! To specify a non-thermal species, a type code must be provided as input:
!
! if itype.eq.4: beam specie (suffix="beam")
! if itype.eq.5: RF Minority specie (suffix="rfmi")
! if itype.eq.6: fusion product species (suffix="fusn")
label, qatom, qcharge, mass)
!--------------------------------
! D. McCune Oct 10 2006
! module subroutine for plasma species labeling
!src
! ...to be used during initialization of plasma state system at the
! start of a simulation...
!
! Mod dmc Mar 2007-- DELETED: tokamakium support.
!--------------------------------
integer, intent(in) :: iZatom ! atomic number: 1 for H, 2 for He, ...
! special: -1 for electrons
integer, intent(in) :: iZcharge ! ionic charge btw 1 and iZatom
! ignored for electrons
integer, intent(in) :: iAMU ! atomic weight in AMU, nearest integer
! ignored unless 1 <= iZatom <= 2
integer, intent(inout) :: iType ! species "type", defined as follows:
! For thermal species, itype can be input or output:
! if itype.eq.-1: electrons (thermal; blank suffix)
! if 1.le.itype.le.3: thermal ion species (blank suffix)
!
! if itype.eq.0: *modify on output* according to value of iZatom:
! -1 for electrons (iZatom=-1)
! 1 for thermal ions (1 <= iZatom <= 2)
! 2 for "impurity" thermal ions (iZatom > 2)
!
! To specify a non-thermal species, a type code must be provided as input:
!
! if itype.eq.4: beam specie (suffix="beam")
! if itype.eq.5: RF Minority specie (suffix="rfmi")
! if itype.eq.6: fusion product species (suffix="fusn")
! if itype.eq.7: fast electrons
!-------------
character*(*), intent(out) :: label ! generated species
label
REAL(KIND=rspec), intent(out) :: qatom ! charge of fully stripped ion
REAL(KIND=rspec), intent(out) :: qcharge ! actual charge
REAL(KIND=rspec), intent(out) :: qatom ! charge of fully stripped ion
REAL(KIND=rspec), intent(out) :: qcharge ! actual charge
REAL(KIND=rspec), intent(out) :: mass ! mass
in kg
This can be found in plasma_state_mod.f90. Examples of its use
are in the swim_state_test.f90 program in the
trunk/components/state/src/test directory, and in my simple fake EPA
component trunk/components/epa/change_n_T/change_n_T_EPA.f90.
Here's what it looks like in action:
ps%s_type = 0
CALL ps_label_spectype(-1, -1, 0, ps%s_type(0), &
ps%s_name(0), ps%qatom_s(0), ps%q_s(0), ps%m_s(0)) ! electron
CALL ps_label_spectype(1, 1, 2, ps%s_type(1), &
ps%s_name(1), ps%qatom_s(1), ps%q_s(1), ps%m_s(1)) ! Deuterium
CALL ps_label_spectype(-1, -1, 0, ps%s_type(0), &
ps%s_name(0), ps%qatom_s(0), ps%q_s(0), ps%m_s(0)) ! electron
CALL ps_label_spectype(1, 1, 2, ps%s_type(1), &
ps%s_name(1), ps%qatom_s(1), ps%q_s(1), ps%m_s(1)) ! Deuterium
You put in (charge, atomic number ->charge-fully-striped, mass
rounded to nearest au, and specied type 0 -> thermal) and you get
out all the ps% stuff you need (including the character name). Using
this is a good way to be sure we all use EXACTLY the same ion masses
every time.
4) Going through this exercise has convinced me that every
component needs an init function that allocates and sets all of the
grids, and that allocates and initializes all of the time evolving
profiles and other data that that component provides. That way
we will know where everything is initialized. We will be in much
better shape to sort out the requirements of components that
depend on initial data from other components in order to intialize
themselves.
Happy SWIMming.
DBB
--
Donald B. Batchelor
Plasma Theory Group
Phone: (865) 574-1288
Fax: (865) 576-7926
E-mail: batchelordb@ornl.gov
Oak Ridge National Laboratory
Fusion Energy Division
P. O. Box 2008
Oak Ridge, TN 37831-6169
Plasma Theory Group
Phone: (865) 574-1288
Fax: (865) 576-7926
E-mail: batchelordb@ornl.gov
Oak Ridge National Laboratory
Fusion Energy Division
P. O. Box 2008
Oak Ridge, TN 37831-6169