PlasmaDriftsLoader
- class PlasmaCalcs.quantities.plasma_drifts.PlasmaDriftsLoader
Bases:
PlasmaParametersLoaderplasma drifts.
Methods
__call__(var, *args[, name, item, verbose])returns value of var from self.
attach_extra_coords(arr)attach any self.extra_coords to array arr but only if it is an xarray.DataArray or xarray.Dataset
cls_help([qstr, only, tree, modules, ...])prints str for help with quants.
cls_var_tree(var, *[, missing_ok])return QuantTree of MatchedQuantity objects from matching var and all dependencies,
copy()returns a deep copy of self.
get_E0S1(*[, _skappa, _E0n0])E0S1 = sum_s E0S1s, where E0S1s = (qs ns skappa_s / (1 + skappa_s^2)),
dataset containing 'E0S1' and 'E0S2'.
get_E0S1s(*[, _skappa, _E0n0])E0S1s = qs ns skappa_s / (1 + skappa_s^2).
get_E0S2(*[, _skappa, _E0n0])E0S2 = sum_s E0S2s, where E0S2s = (qs ns skappa_s^2/ (1 + skappa_s^2)),
get_E0S2s(*[, _skappa, _E0n0])E0S2s = qs ns skappa_s^2/ (1 + skappa_s^2).
get_E0_etaJ_perpB(*[, _E0S1, _E0S2])E0_perp_B = E0_etaJ_perpB + ..., where E0_etaJ_perpB = eta0_J * J_perp_B.
get_E0_hall(*[, _E0S1, _E0S2])E0_perp_B = E0_hall + ..., where E0_hall = eta0_hall * J x Bhat.
E0_un0_perpB = E0_etaJ_perpB + E0_hall
E0_un0_perpmodB = |E0_un0_perpB|.
E0_un0_perpmodB_min = minimum possible value of |E0_un0_perpB|, at each point.
E0_un0_perpmodB_simple = simple estimate of |E0_un0_perpB|, at each point.
get_E0n0(*, E0n0type)n0 for E0 calculations.
n type for E0 calculations.
speed determined from E_un0 and B: |E_un0 perp to B| / |B|.
E_un0 = electric field in the neutral frame, where u_n=0.
get_E_un0_perpmod_B(**kw_perpmod)E_un0_perpmod_B == |E_un0 perp to B| == magnitude of E, perp to B, in u_neutral=0 frame.
string telling method that will be used to get E_un0.
speed determined from J perp to B, and ne: |J_perp to B| / (ne * |qe|).
get_behavior([keys])return value of self.behavior.
get_beta()plasma beta.
sound speed.
sound speed squared.
get_eta0_J(*[, _E0S1, _E0S2])E0_perp_B = eta0_J * J_perp_B + ..., where eta0_J = E0S1 * |B| / (E0S1^2 + E0S2^2).
get_eta0_hall(*[, _E0S1, _E0S2])E0_perp_B = eta0_hall J x Bhat + ..., where eta0_hall = - E0S2 * |B| / (E0S1^2 + E0S2^2)
(unsigned) gyrofrequency.
(unsigned) kappa (magnetization parameter).
Debye length (of self.fluid).
squared Debye length (of self.fluid).
"total" Debye length; ldebye_subset = sqrt(epsilon0 kB / sum_fluids(n q^2 / (kB T)))
total Debye length for all fluids; ldebye_total = sqrt(epsilon0 kB / sum_fluids(n q^2 / (kB T)))
collisional mean free path.
ion-to-electron density ratio.
get_nusn_from_drift(var, *[, _match])nusn, calculated by assuming u satisfies momentum equation to zeroth order.
get_psi()psi = (1/(kappae * kappai)) == (nuen * nuin) / (gyrof_e * gyrof_i).
psi_i = (1/(kappae * kappai)) == (nuen * nuin) / (gyrof_e * gyrof_i).
rosenberg criterion for multiple ions: rosenberg_multi = (nusn_multi / wplasma_multi)^2.
collision frequency for rosenberg criterion with multiple ions.
plasma frequency for rosenberg criterion with multiple ions.
n such that rosenberg_qn == 1, for each fluid.
n / rosenberg_n.
Rosenberg criterion for quasineutrality, for each fluid: rosenberg_qn = (nusn / wplasma)^2.
get_set_or_cached(var)returns var if found in self.setvars or self.cache, with compatible behavior_attrs.
signed gyrofrequency.
signed kappa (magnetization parameter).
get_skappa_from_hall(var, *[, _match])signed kappa (magnetization parameter) that statisfies u_hall = u, in the E x B direction.
get_skappa_from_momE(var, *[, _match])signed kappa (magnetization parameter) that statisfies momentum equation in the E direction.
get_skappa_from_momExB(var, *[, _match])signed kappa (magnetization parameter) that statisfies momentum equation in the E x B direction.
get_skappa_from_pedersen(var, *[, _match])signed kappa (magnetization parameter) that statisfies u_pedersen = u, in the E direction.
get_u_EdotB(*[, _E, _B])EdotB drift velocity.
equilibrium velocity; solution to the momentum equation with collisions,
get_u_hall(*[, _E, _B])Hall drift velocity.
get_u_pedersen(*[, _E, _B])Pedersen drift velocity.
Alfven speed.
Alfven speed squared.
get_vars(vars, *args[, return_type, ...])returns values of vars from self.
thermal velocity.
thermal velocity for neutrals.
"plasma frequency".
electron plasma frequency; Langmuir oscillations.
has_var(var)return whether self can load var.
help([qstr, only, tree, modules, signature, ...])prints str for help with quants.
help_call_options([search])prints help for kw_call_options.
help_quants_str([qstr, only, tree, modules, ...])returns str for help with quants.
help_str([qstr, only])returns cls.help_quants_str(qstr=qstr, only=only, **kw).
kw_call_options(*[, sorted])returns list of kwarg names which can be used to set attrs self during self.__call__.
load_direct(var, *args, **kw)load var "directly", from some source which is not known by the main part of PlasmaCalcs.
load_fromfile(var, *args, **kw)load var directly from a file.
maintaining_attrs(*attrs, **attrs_as_flags)returns context manager which restores attrs of self to their original values, upon exit.
match_var(var, *[, check])match var from cls.KNOWN_VARS or cls.KNOWN_PATTERNS, or raise FormulaMissingError.
match_var_loading_dims(var, **kw_loading_dims)return dims for loading var across.
match_var_result_dims(var, **kw_result_dims)return dims which result of cls(var) will vary across.
match_var_result_size(var, *[, maindims])return size (number of elements) which self(var) will have.
match_var_tree([var])return QuantTree of MatchedQuantity objects from matching var and all dependencies,
plot_check_nusn_from_drift(*[, u, drift, ...])plots PlasmaCalcs.timelines() for comparing nusn to nusn inferred from drifts.
quant_tree([var])return QuantTree of MatchedQuantity objects from matching var and all dependencies,
set_var(var, value[, behavior_attrs, ...])set var in self.
set_var_internal(var, value, behavior_attrs)set var in self.
set_vtherm(value, **kw)set thermal velocity, by setting T.
tree([var])return QuantTree of MatchedQuantity objects from matching var and all dependencies,
unset_var(var[, behavior_attrs, missing_ok])remove var from self.setvars (but only at values stored with relevant behavior).
unset_var_internal(var, behavior_attrs[, ...])unset var from self.setvars.
using_at_call_depth(depth, **attrs_and_values)context manager for setting attrs_and_values but only while call_depth == depth.
using_at_next_call_depth(**attrs_and_values)context manager for setting attrs_and_values but only while call_depth == self.call_depth + 1
using_attrs([attrs_as_dict, _unset_sentinel])returns context manager which sets attrs of obj upon entry; restores original values upon exit.
apply self.toplevel_scale_coords to arr, if nonempty, else return arr unchanged.
_battrs_for_set_var_internal(behavior_attrs)returns behavior_attrs which will be used by set_var_internal, given these inputs.
_battrs_for_unset_var_internal(behavior_attrs)returns behavior_attrs which will be used by unset_var_internal, given these inputs.
_call_hijacker(var, *args__None, **kw__None)returns False or name of hijacker method to use instead of self(var) call.
_call_postprocess(result, *, var[, name, item])postprocess result from self.__call__.
_call_postprocess_toplevel(result, *, var[, ...])additional postprocessing for self.__call__ when call_depth=1.
_call_preprocess(result, *, var)preprocessing during self.__call__.
_get_maybe_missing_var(var, *args[, ...])return value of var, or None if FormulaMissingError and missing_vars 'ignore' or 'warn'.
_handle_typevar_nan(*[, errmsg])crash with TypevarNanError if self.typevar_crash_if_nan, else return 'nan'.
_help_matches(qstr, k, v)returns whether qstr matches k or v, and thus should be displayed during self.help(qstr).
returns dict of docstrings for specialized kw call options for self.
context manager for incrementing call_depth.
pop all self.kw_call_options() from kw, returning dict of popped options.
_provided_val(var[, _val, _known_vals])returns the value of var, either from _known_vals or _val.
specialize popped kw_call_options, adjusting keys and/or values as needed,
Attributes
E0_NE0_MODE_OPTIONScontrols how to get ne when calculating E0.
E_UN0_MODE_OPTIONSmode for calculating E_un0, the electric field in the neutral frame (where u_n=0).
KNOWN_PATTERNSKNOWN_SETTERSKNOWN_VARSwhether to assign self.behavior values as attrs of result when calling self.
max call_depth at which to assign_behavior_attrs to result,
whether to use include_xr=False if self.assign_behavior_attrs,
dict of {attr: self.attr} for attr in self.behavior_attrs.
list of attrs in self which control behavior of self.
depth of the current call to self.
stores the value of call_depth, and helps to manage attrs dependent on call_depth value.
cls_behavior_attrsbool: whether self.load_fromfile is enabled during self.load_direct.
dict of {coord_name: coord_value} to attach to outputs of self(var).
alias to __call__
known_patternknown_setterknown_varalias to maintaining_attrs
list of attrs in self which control behavior of self, but which are NOT in self.dimensions.
alias to set_var
alias to set_var
VarCache of vars set via self.set_var().
dict of {coord_name: coord_scaling} to apply to top-level outputs of self(var).
bool.
alias to unset_var
alias to using_attrs
- property E0_ne0_mode
controls how to get ne when calculating E0. See self.E0_NE0_MODE_OPTIONS for details.
- property E_un0_mode
mode for calculating E_un0, the electric field in the neutral frame (where u_n=0).
See self.E_UN0_MODE_OPTIONS for details on the various options.
- __call__(var, *args, name=UNSET, item=False, verbose=UNSET, **kw)
returns value of var from self.
result is probably an xarray.DataArray, but not guaranteed.var: str or iterable of strs.Name of the var(s) to load. E.g. ‘n’ for number density, or [‘n’, ‘u’] for number density & velocity.If multiple vars: returns an xarray.Dataset of all vars, via self.get_vars.Determine how to load each var, as follows:- (caching) if var in self.cache, with matching self.behavior_attrs, use value from cache.[TODO] - caching not yet implemented. May allow for better efficiency.- (setvars) if var in self.setvars, with matching self.behavior_attrs, use value from setvars.[TODO] - improve set_var functionality.set_var will allow user to apply PlasmaCalcs calculations to arbitrary values,not just values from one of the hookups. Useful for testing & quick calculations.- (KNOWN_VARS) if var in self.KNOWN_VARS,use the corresponding function to get it.- (KNOWN_PATTERNS) if var matches a pattern from self.KNOWN_PATTERNS,use the corresponding function to get it.- (direct) attempt to load var “directly”, via self.load_direct.load_direct will almost always end up loading values directly from a file (e.g., “data”).This may include converting var to fromfile_var, i.e. match file naming conventions,and/or dimensions being loaded. E.g. ‘b’ may become ‘bz’ when loading across ‘component’.Then, check if fromfile_var in setvars and cache, returning relevant value if found.Lastly, call self.load_fromfile(fromfile_var).Those are checked in the order listed.If none of those work, raise FormulaMissingError.name: UNSET, None, or strtry to set result.name = name.If can’t set result.name, but result.attrs exists, set result.attrs[‘name’] = name, instead.UNSET –> use name = var.item: boolif True, convert result to single value (e.g., python float) via result.item().This will cause crash if result is not a single value;it will also cause all metadata stored in the result to be lost.verbose: UNSET, bool, or intset self.verbose during this call to self.UNSET –> use self.verbose (unchanged)kw may additionally contain any keys from self.kw_call_options().if it does, pop those values, and temporarily set the corresponding attr.E.g.: self(‘n’, units=’si’, fluid=1)–> temporarily set units=’si’, fluid=1, while getting ‘n’.See self.help_call_options() for more details.[EFF] passes _match=re.fullmatch(pattern, var) to the getter function,if the match is from KNOWN_PATTERNS (but not if it is from KNOWN_VARS).misc note: if self._call_hijacker(…), instead return result from the corresponding method.e.g. if it returns “_get_with_chunks” then return self._get_with_chunks(var, …).Call hijacking occurs after setting behavior attrs (insidewith self.using(...):block)but before altering call depth (outsidewith self._increment_call_depth():block).
- _apply_toplevel_scale_coords(arr)
apply self.toplevel_scale_coords to arr, if nonempty, else return arr unchanged.
- _battrs_for_set_var_internal(behavior_attrs, forall=[], *, ukey=None)
returns behavior_attrs which will be used by set_var_internal, given these inputs.
see help(self.set_var_internal) for details.
- _battrs_for_unset_var_internal(behavior_attrs, forall=[], *, ukey=None)
returns behavior_attrs which will be used by unset_var_internal, given these inputs.
see help(self.unset_var_internal) for details.
- _call_hijacker(var, *args__None, **kw__None)
returns False or name of hijacker method to use instead of self(var) call.
Here, just returns False, always. Subclass might override.
- _call_postprocess(result, *, var, name=UNSET, item=UNSET)
postprocess result from self.__call__. Called during self.__call__.
(self.call_depth inside here will tell depth of the current call; depth=1 for top level.)result: any value, probably an xarray.DataArrayresult from self.__call__, before postprocessing.var, name, item: UNSET or valuepassed directly from self.__call__.The implementation here does the following (subclasses might override / add to this):(1) if self.verbose >= 4, print a message about getting var.(2) result = self.attach_extra_coords(result).(3) set result.name = name, or result.attrs[‘name’] = name, if possible.(4) if self.assign_behavior_attrs at this call depth, do so now.(5) if self.call_depth == 1, call self._call_postprocess_toplevel.(6) if item, convert result to single value via result.item().
- _call_postprocess_toplevel(result, *, var, name=UNSET, item=UNSET)
additional postprocessing for self.__call__ when call_depth=1.
called from self._call_postprocess, after doing other postprocessing, when call_depth=1.result: any value, probably an xarray.DataArrayresult from self.__call__, after other postprocessing (exceptitem).var, name, item: UNSET or valuepassed directly from self.__call__.Don’t need to handle these here because self._call_postprocess will handle it.The implementation here does the following (subclasses might override / add to this):(1) self._apply_toplevel_scale_coords (does nothing if self.toplevel_scale_coords is empty)
- _call_preprocess(result, *, var)
preprocessing during self.__call__. Called during self.__call__.
(self.call_depth inside here will tell depth of the current call; depth=1 for top level.)result: any value, probably RESULT_MISSINGresult from self.__call__, before preprocessing. Usually RESULT_MISSING.var: strvar being loaded. Passed directly from self.__call__.The implementation here does the following (subclasses might override / add to this):(1) if self.verbose >= 2 or DEFAULTS.DEBUG >= 7, print a message about getting var.(2) return result, unchanged.If the returned result is anything other than RESULT_MISSING,self.__call__ will return it instead of loading var normally.
- _get_maybe_missing_var(var, *args, missing_vars=UNSET, **kw)
return value of var, or None if FormulaMissingError and missing_vars ‘ignore’ or ‘warn’.
missing_vars: UNSET, ‘ignore’, ‘warn’, or ‘raise’what to do if any var causes FormulaMissingError.UNSET –> use self.missing_vars if it exists, else ‘raise’.‘ignore’ –> return None.‘warn’ –> return None, but also print a warning.‘raise’ –> raise FormulaMissingError.
- _handle_typevar_nan(*, errmsg='')
crash with TypevarNanError if self.typevar_crash_if_nan, else return ‘nan’.
if crashing, use error message:errmsg + “nTo return ‘nan’ instead of crashing, set self.typevar_crash_if_nan=False.”
- classmethod _help_matches(qstr, k, v)
returns whether qstr matches k or v, and thus should be displayed during self.help(qstr).
qstr: str
the str to match; from self.help(qstr)k: varnamethe varname to test for matches.key from self.KNOWN_VARS.keys(), or key.str from self.KNOWN_PATTERNS.keys().v: LoadableQuantitythe LoadableQuantity to test for matches.value from self.KNOWN_VARS.values() or self.KNOWN_PATTERNS.values().matches if any of these are true:qstr == ‘’qstr in k.split(‘_’) # size limitation and split(‘_’) because, e.g. during help(‘n’),len(qstr)>=3 and qstr in k # want vars related to number density, not all vars with the letter ‘n’.qstr in module.split(‘.’) (where, module == v.get_f_module(cls))‘.’ in qstr and qstr in modulelen(qstr)>=3 and qstr in value from module.split(‘.’)len(qstr)>=3 and qstr in v.fnamere.fullmatch(k, qstr) # if k is a Patternotherwise, does not match.
- _help_specialized_kw_call_options()
returns dict of docstrings for specialized kw call options for self.
The implementation here just returns an empty dict, but subclass may override.
- _increment_call_depth()
context manager for incrementing call_depth.
use “with self._increment_call_depth():” inside of __call__, e.g.:
def __call__(self, *args, **kw):with self._increment_call_depth():# do stuff; possibly including calling self again.Equivalent to self.call_depth_manager.increment()
- _pop_kw_call_options(kw)
pop all self.kw_call_options() from kw, returning dict of popped options.
- _provided_val(var, _val=None, _known_vals={})
returns the value of var, either from _known_vals or _val.
if _val provided, return it; if ‘_{var}’ in _known_vals, return it;if both provided, crash with InputConflictError (unless they are the same object),else, return None.Can use this internally to avoid redundant recalculations. (See e.g. VectorArithmeticLoader)
- _specialized_kw_call_options(kw)
specialize popped kw_call_options, adjusting keys and/or values as needed,
to be suitable to pass to self.using(**kw).kw may be edited IN PLACE.Overriding this is discouraged, unless using property setters/getters is truly insufficient.If overriding this method, consider also overriding self._help_specialized_kw_call_options,to add documentation (inside self.help_call_options()) for any specialized kw call options.self.__call__ uses this method as follows:using=self._pop_kw_call_options(kw)using = self._specialize_using_kw_call_options(using)with self.using(**using):# <– majority of self.__call__ functionality goes here.The implementation here just returns kw, unchanged.
- property assign_behavior_attrs
whether to assign self.behavior values as attrs of result when calling self.
False –> don’t use self.behavior code architecture to assign attrs.True –> equivalent to ‘nondefault’‘nondefault’ –> self.behavior.assign_nondefault_attrs(result)(for brevity, it does not assign behavior attrs with “default” value.)‘all’ –> self.behavior.assign_attrs(result).[EFF] only assigns attrs at call_depth >= self.assign_behavior_attrs_max_call_depth.(default: only assigns attrs at call_depth=1, i.e. at top level.
- property assign_behavior_attrs_max_call_depth
max call_depth at which to assign_behavior_attrs to result,
if self.assign_behavior_attrs indicates to assign behavior attrs.default 1, i.e. only assign if at top level.Use None to indicate “no max depth”.
- property assign_behavior_attrs_skip_xr
whether to use include_xr=False if self.assign_behavior_attrs,
during self.behavior.assign_nondefault_attrs.Use this if you want to assign behavior attrs EXCEPT array-valued behavior attrs.
- attach_extra_coords(arr)
attach any self.extra_coords to array arr but only if it is an xarray.DataArray or xarray.Dataset
- property behavior
dict of {attr: self.attr} for attr in self.behavior_attrs. Note dims are separate;
dims go in behavior.dims. E.g. Behavior({‘units’:’si’,…}, dims={‘snap’:0,…}).
- property behavior_attrs
list of attrs in self which control behavior of self.
Here, returns self.cls_behavior_attrs.Subclasses could override if any behavior attrs are not known at the class-level,e.g. if MySubclass’s list of behavior attrs varies between instances of MySubclass.
- property call_depth
depth of the current call to self. depth = number of calls to self from within self.
E.g., call_depth while calculating gyrofrequency:
# call_depth == 0, for any code run here (outside any call to self).self(‘gyrof’)# call_depth == 1, for any code run here (inside ‘gyrof’ call but not inside deeper calls).q = self(‘q’)# call_depth == 2, for code inside ‘q’ call.mod_B = self(‘mod_B’)# call_depth == 2, for code inside ‘mod_B’ call.self(‘B’)# call_depth == 3, for code inside ‘B’ call.m = self(‘m’)# call_depth == 2, for code inside ‘m’ call.result = q * mod_B / mCannot be set directly; can only be manipulated via self.call_depth_manager.
- property call_depth_manager
stores the value of call_depth, and helps to manage attrs dependent on call_depth value.
- classmethod cls_help(qstr=None, only=None, *, tree=None, modules=False, signature=False, doc=True, dense=False, print=True, **kw)
prints str for help with quants. Fails for any quants which depend on present values of a cls instance.
qstr: None or str
None –> tells info about this class & how to use this function.in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,and describes behavior of calling help with a string.str –> return str for help with all quants related to str.use empty str to get help for all quants.only: None or strIf provided, only get help for a subset of relevant quantities.None –> get help with all quantities related to qstr.‘VARS’ –> only get help with KNOWN_VARS.‘PATTERNS’ –> only get help with KNOWN_PATTERNS.‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.if provided when qstr is None, treat qstr as ‘’ instead.tree: None or boolHow much help to give for quantities in cls.cls_var_tree(qstr).False –> don’t even check cls.cls_var_tree(qstr).True –> help for all quantities in cls.cls_var_tree.None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).modules: boolWhether to include modules in result.If True, result will be grouped into sections with modules written at top.signature: signature: boolwhether to include line with signature in help string.e.g. “help_str(f, *, module=True, signature=True, indent=None)”doc: doc: boolwhether to include lines with docstring in help string.e.g. “return str for help(f).” … and all the other docs in here.dense: boolWhether to reduce whitespace in result.E.g. True –> no newlines between functions. False –> one newline between functions.print: boolwhether to print the result. If False, return the result instead of printing.
- classmethod cls_var_tree(var, *, missing_ok=False)
return QuantTree of MatchedQuantity objects from matching var and all dependencies,
using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.missing_ok: boolwhether to be lenient sometimes when missing details that would allow to fully determine deps.see help(MatchedQuantity.dep_vars) for more details.
- copy()
returns a deep copy of self.
[TODO] implement something less hacky than using the pickle module?
- property enable_fromfile
bool: whether self.load_fromfile is enabled during self.load_direct.
If False, raise QuantCalcError if load_direct can’t get value without load_fromfile().
- property extra_coords
dict of {coord_name: coord_value} to attach to outputs of self(var).
Useful if planning to join the output of self(var) with output from a different QuantityLoader.E.g. self.extra_coords={‘run’: ‘run 0’} and other.extra_coords={‘run’: ‘run 1’},then xr.concat([self(‘n’), other(‘n’)], ‘run’) gives ‘n’ from self AND other.(this is nice if self and other have same values for dims. Otherwise, might struggle.)
- property get
alias to __call__
- get_E0S1(*, _skappa=None, _E0n0=None)
E0S1 = sum_s E0S1s, where E0S1s = (qs ns skappa_s / (1 + skappa_s^2)),
and the sum is across all charged fluids (from self.fluids).see help(self.get_E0_un0_perpB) for more details. Note: ne depends on self.E0_ne0_mode.[EFF] for efficiency, can provide _skappa and/or n (via _E0n0) if known.
- get_E0S1_and_S2()
dataset containing ‘E0S1’ and ‘E0S2’. Equivalent to self([‘E0S1’, ‘E0S2’]),
but more efficient (only computes skappa and n one time).E0S1 = sum_s (qs ns skappa_s / (1 + skappa_s^2))E0S2 = sum_s (qs ns skappa_s^2/ (1 + skappa_s^2))Note: ne depends on self.E0_ne0_mode.
- get_E0S1s(*, _skappa=None, _E0n0=None)
E0S1s = qs ns skappa_s / (1 + skappa_s^2).
See help(self.get_E0_un0_perpB) for more details. Note: ne depends on self.E0_ne0_mode.See also: self.get_E0S1() which sums across all charged fluids.[EFF] for efficiency, can provide _skappa and/or n (via _E0n0) if known(though, they must have ‘fluid’ coord matching self.fluid).
- get_E0S2(*, _skappa=None, _E0n0=None)
E0S2 = sum_s E0S2s, where E0S2s = (qs ns skappa_s^2/ (1 + skappa_s^2)),
and the sum is across all charged fluids (from self.fluids).see help(self.get_E0_un0_perpB) for more details. Note: ne depends on self.E0_ne0_mode.[EFF] for efficiency, can provide _skappa and/or n (via _E0n0) if known.
- get_E0S2s(*, _skappa=None, _E0n0=None)
E0S2s = qs ns skappa_s^2/ (1 + skappa_s^2).
See help(self.get_E0_un0_perpB) for more details. Note: ne depends on self.E0_ne0_mode.See also: self.get_E0S2() which sums across all charged fluids.[EFF] for efficiency, can provide _skappa and/or n (via _E0n0) if known(though, they must have ‘fluid’ coord matching self.fluid).
- get_E0_etaJ_perpB(*, _E0S1=None, _E0S2=None)
E0_perp_B = E0_etaJ_perpB + …, where E0_etaJ_perpB = eta0_J * J_perp_B.
see help(self.get_E0_un0_perpB_fromJ) for more details.
- get_E0_hall(*, _E0S1=None, _E0S2=None)
E0_perp_B = E0_hall + …, where E0_hall = eta0_hall * J x Bhat.
see help(self.get_E0_un0_perpB) for more details.
- get_E0_un0_perpB()
E0_un0_perpB = E0_etaJ_perpB + E0_hall
== eta0_J * J_perp_B + eta0_hall * J x Bhat== (E0S1 |B| J_perp_B + E0S2 B cross J) / (E0S1^2 + E0S2^2), whereE0S1 = sum_s (qs ns skappa_s / (1 + skappa_s^2)),E0S2 = sum_s (qs ns skappa_s^2/ (1 + skappa_s^2)),Note: ne depends on self.E0_ne0_mode.This is the electric field in the un=0 frame of reference, assuming:- zeroth order equilibrium velocities from multifluid equations,- including only collisions with neutrals,- considering only E (& J) perp to B; ignoring E0 (& J) parallel to B.
- get_E0_un0_perpmodB()
E0_un0_perpmodB = |E0_un0_perpB|.
Should be equivalent to self(‘mod_E0_un0_perpB’), aside from rounding errors.[EFF] the method here uses an algebraic simplification of the E0_un0_perpB formula:E0_un0_perpB == (E0S1 |B| J_perp_B + E0S2 B cross J) / (E0S1^2 + E0S2^2)–> (do some algebra, and utilizing J_perp_B dot B = 0) –>E0_un0_perpmodB = (|B| |J_perp_B|) / sqrt(E0S1^2 + E0S2^2)
- get_E0_un0_perpmodB_min()
E0_un0_perpmodB_min = minimum possible value of |E0_un0_perpB|, at each point.
E0_un0_perpmodB_min = (1/sqrt(2)) * |B| |J_perp_B| / (ne |qe|)Regardless of kappa (& nusn) values for electrons and ions, will always have:E0_un0_perpmodB >= E0_un0_perpmodB_min.Logic which proves this fact (below, using “K” as shorthand for “skappa”):E0_un0_perpmodB has sqrt(E0S1^2 + E0S2^2) in the denominator;–> when sqrt(E0S1^2 + E0S2^2) is largest, E0_un0_perpmodB will be smallest.sqrt(E0S1^2 + E0S2^2) is largest when |E0S1| and |E0S2| are both largest.(1) |E0S1| <= sum_s (|qs| ns |Ks| / (1 + Ks^2))(2) |E0S2| <= sum_s (qs ns Ks^2 / (1 + Ks^2))For ANY real K, the relevant quantities are bounded by:(i) 0 < |K| / (1 + K^2) <= 1/2(ii) 0 < K^2 / (1 + K^2) < 1which can be readily shown using introductory calculus:|K|/(1+K^2) has local extrema (derivative=0) only at K=1, where |K|/(1+K^2)=1/2;it tends to 0 when K->0; and it tends to 0 when K->inf.K^2/(1+K^2) has local extrema (derivative=0) only at K=0, where it equals 0;it tends to 0 when K->0; and it tends to 1 when K->inf.Applying (i) to expression (1) above yields:|E0S1| <= sum_s |qs| ns * 1/2Utilizing quasineutrality (sum_s qs ns = 0) and qe < 0 and qi > 0, provides:sum_s |qs| ns = ne |qe| + sum_i ni qi = 2 ne |qe|–> |E0S1| <= ne |qe|Meanwhile for expression (2), note that because qe < 0 and qi > 0,ne qe (Ke^2 / (1 + Ke^2)) has opposite the sign as sum_i ni qi Ki^2 / (1 + Ki^2),so the largest possible |E0S1| occurs when one of those two terms is as small as possible.Applying (ii) to each term, and quasineutrality to the second term, yields:|ne qe (Ke^2 / (1 + Ke^2))| < ne |qe||sum_i ni qi Ki^2 / (1 + Ki^2)| < sum_i ni qi = ne |qe|–> |E0S2| < ne |qe|Combining yields:sqrt(E0S1^2 + E0S2^2) < sqrt(2) ne |qe|Thus, we always have:(|B| |J_perp_B|) / sqrt(E0S1^2 + E0S2^2) >= (|B| |J_perp_B|) / (sqrt(2) * ne |qe|)i.e. E0_un0_perpmodB >= E0_un0_perpmodB_min.
- get_E0_un0_perpmodB_simple()
E0_un0_perpmodB_simple = simple estimate of |E0_un0_perpB|, at each point.
E0_un0_perpmodB_simple = (|B| |J_perp_B|) / (ne |qe|)This is a simple estimate of |E0_un0_perpB|, accurate when kappae>>1 and kappai<<1.
- get_E0n0(*, E0n0type)
n0 for E0 calculations. Electron result depends on self.E0_ne0_mode.
In ‘direct’ mode, just returns self(‘n’).In ‘QN’ mode, gives self(‘n’) for ions, but sum_i(qi ni)/|qe| for electrons.(When in ‘direct’ mode, E0n0type should be ‘n’ for all species.When in ‘QN’ mode, E0n0type will be ‘e’ for electrons, ‘n’ for ions.)
- get_E0n0type()
n type for E0 calculations. Depends on self.E0_ne0_mode.
In ‘direct’ mode, always ‘n’.In ‘QN’ mode, either ‘n’ (for ions) or ‘e’ (for electrons).
- get_EBspeed()
speed determined from E_un0 and B: |E_un0 perp to B| / |B|.
- get_E_un0()
E_un0 = electric field in the neutral frame, where u_n=0.
Result depends on self.E_un0_mode; see help(type(self).E_un0_mode) for details.
- get_E_un0_perpmod_B(**kw_perpmod)
E_un0_perpmod_B == |E_un0 perp to B| == magnitude of E, perp to B, in u_neutral=0 frame.
This is usually equivalent to using self.magnitude(self.take_perp_to(B, E_un0)),but if E_un0_mode = ‘E0_perpmodB’ will use more efficient method (self(‘E0_un0_perpmodB’)),and if E_un0_mode = ‘E0_perpmodB_min’ will use different method (self(‘E0_un0_perpmodB_min’)).kwargs are passed to self.get_perpmod, if applicable.
- get_E_un0_type()
string telling method that will be used to get E_un0. Based on self.E_un0_mode.
possible results include (but may be adjusted further by subclasses):‘nan’ <–> will crash. (e.g. this occurs if E_un0_mode = ‘E0_perpmodB_min’)‘E+unxB’ <–> self(‘E’) + self(‘u_neutral_cross_B’)‘E_u0’ <–> self(‘E_u0’)‘E+uxB’ <–> self(‘E’) + self(‘u_cross_B’)‘E’ <–> self(‘E’)‘E0_perpB’ <–> self(‘E0_un0_perpB’)
- get_JBspeed()
speed determined from J perp to B, and ne: |J_perp to B| / (ne * |qe|).
- get_behavior(keys=None)
return value of self.behavior.
keys: None or iterableif provided, only include these attrs.from nondim_behavior_attrs, or dims.
- get_beta()
plasma beta. beta = (pressure / magnetic pressure) = (P / (B^2 / (2 mu0)))
- get_csound()
sound speed. csound = sqrt(gamma * P / r)
- get_csound2()
sound speed squared. csound2 = gamma P / r.
- get_eta0_J(*, _E0S1=None, _E0S2=None)
E0_perp_B = eta0_J * J_perp_B + …, where eta0_J = E0S1 * |B| / (E0S1^2 + E0S2^2).
see help(self.get_E0_un0_perpB) for more details.[EFF] for efficiency, can provide _E0S1 and/or _E0S2 if known.
- get_eta0_hall(*, _E0S1=None, _E0S2=None)
E0_perp_B = eta0_hall J x Bhat + …, where eta0_hall = - E0S2 * |B| / (E0S1^2 + E0S2^2)
see help(self.get_E0_un0_perpB) for more details.[EFF] for efficiency, can provide _E0S1 and/or _E0S2 if known.
- get_gyrof()
(unsigned) gyrofrequency. gyrof == |sgyrof| == |q| |B| / m == |charge| * |B| / mass.
- get_kappa()
(unsigned) kappa (magnetization parameter). kappa = |skappa| == |gyrof| / nusn.
kappa = |gyrofrequency| / collision frequency of self.fluid with neutrals.
- get_ldebye()
Debye length (of self.fluid). ldebye = sqrt(epsilon0 kB T / (n q^2))
- get_ldebye2()
squared Debye length (of self.fluid). ldebye2 = epsilon0 kB T / (n q^2)
- get_ldebye_subset()
“total” Debye length; ldebye_subset = sqrt(epsilon0 kB / sum_fluids(n q^2 / (kB T)))
sum is taken over the fluids in self.fluid.Equivalent: sqrt( 1 / sum_fluids(1/ldebye^2) )
- get_ldebye_total()
total Debye length for all fluids; ldebye_total = sqrt(epsilon0 kB / sum_fluids(n q^2 / (kB T)))
sum is taken over all the fluids in self.fluids.Equivalent: sqrt( 1 / sum_fluids(1/ldebye^2) )
- get_mean_free_path()
collisional mean free path. lmfp = vtherm / nusn = thermal velocity / collision frequency.
- get_niefrac()
ion-to-electron density ratio. niefrac = ni / ne.
Result always corresponds to fluid=IONS, regardless of current self.fluid.
- get_nusn_from_drift(var, *, _match=None)
nusn, calculated by assuming u satisfies momentum equation to zeroth order.
There are various options for how to solve for nusn, as explained below (see {drift}).All solutions use nusn = sgyrof / skappa, where skappa is determined viaskappa = self(‘skappa’+var[len(‘nusn’):]).E.g. ‘nusn_from_means_momExB’ –> use skappa = self(‘skappa_from_means_momExB’).The description below helps explain the various options.‘nusn_from_{means_}{u_}{drift}’E.g. ‘nusn_from_means_momExB’, ‘nusn_from_hall’, ‘nusn_from_means_moment1_momB’{means_} = ‘means_’ or ‘’.if ‘means_’, take means of vars: ‘sgyrof’, any vars relevant to the chosen {drift} option.{u_} = ‘’ or any other var then ‘_’.if provided, use this var instead of ‘u’ for velocity. (Doesn’t affect “u_neutral” though.){drift} = ‘momExB’, ‘momE’, ‘hall’, or ‘pedersen’indicates how to solve for nusn. Use the similarly-named var when getting skappa.‘momExB’ –> get skappa from the momentum equation in the E x B direction.‘momE’ –> get skappa from the momentum equation in the E direction.‘hall’ –> get skappa from u_hall = u, in the E x B direction.‘pedersen’ –> get skappa from u_pedersen = u, in the E direction.
- get_psi()
psi = (1/(kappae * kappai)) == (nuen * nuin) / (gyrof_e * gyrof_i).
Commonly used in ionospheric Farley-Buneman instability analysis.psi is calculated using the formula above, for the single ion in self.fluids.self.fluids must contain exactly 1 ion and exactly 1 electron,else this method will crash with FluidValueError or FluidKeyError.equivalent to psi_i in the case of exactly 1 ion in self.fluid and self.fluids.
- get_psi_i()
psi_i = (1/(kappae * kappai)) == (nuen * nuin) / (gyrof_e * gyrof_i).
Commonly used in ionospheric Farley-Buneman instability analysis.psi_i gives the value of psi for each ion in self.fluid, using the formula above.fails with FluidValueError if current self.fluid includes any non-ions.fails with FluidKeyError if current self.fluid does not include any ions.see also: psi
- get_rosenberg_multi()
rosenberg criterion for multiple ions: rosenberg_multi = (nusn_multi / wplasma_multi)^2.
quasineutrality is “reasonable” (during farley-buneman analysis) iff rosenberg_multi << 1.This criterion should be more accurate than using rosenberg_qn for each ion, separately.(Below uses ‘…’ to denote “terms independent of wplasma_i and nu_in”.)Rosenberg 1998 equation 17, derived from equation 14, assumed only 1 ion.However, equation 14 comes from 13, where wplasma_i and nu_in only appear as (Ai/wplasma_i^2).where Ai = omega * (omega + i nu_in) + … (see equation 15).equation 13 looks like: … + (Ai/wplasma_i^2) = 0From equation 4 I infer the dispersion relation with multiple ions will be like:… + sum_i (Ai/wplasma_i^2) = 0.Expanding this sum reveals that it can be expressed in the same algebraic form as with 1 ion:… + Am/wplasma_m^2 = 0, when:wplasma_m^2 = 1 / (1/wplasma_1^2 + 1/wplasma_2^2 + …),Am = omega * (omega + i nu_mn) + …nu_mn = nu1 * weight1 + nu2 * weight2 + … / (weight1 + weight2 + …),where weightj = wplasma_1^2 * wplasma_2^2 * … / wplasma_j^2.Thus, the remaining steps done by Rosenberg to derive the criterion should apply in the same way,and for multiple ions we can conclude the criterion is (nu_mn / wplasma_m)^2 << 1.Okay, actually, in practice, it’s probably not useful to use this…it mostly just selects the least-dense ion, due to the 1/wplasma^2 scaling.Also, the criterion means “instability gets dampened when collisions are faster than plasma oscillations”But for multiple ions, it’s really more like, the instability for THAT ion gets dampened…(Also, I think one of the assumptions in the paper probably fails when wplasma is small…)
- get_rosenberg_multi_nusn()
collision frequency for rosenberg criterion with multiple ions.
nusn_multi = nu1 * weight1 + nu2 * weight2 + … / (weight1 + weight2 + …),where weightj = wplasma_1^2 * wplasma_2^2 * … / wplasma_j^2.see rosenberg_multi for details.
- get_rosenberg_multi_wplasma()
plasma frequency for rosenberg criterion with multiple ions.
wplasma_multi^2 = 1 / (1 / wplasma1^2 + 1 / wplasma2^2 + …),with sum across all ions in self(‘wplasma’, fluids=None)see rosenberg_multi for details.
- get_rosenberg_n()
n such that rosenberg_qn == 1, for each fluid.
Equivalent: rosenberg_qn * n.To satisfy Rosenberg criterion, need rosenberg_qn << 1.rosenberg_qn = (nusn / wplasma)^2 = nusn^2 * m * eps0 / (n * q^2),which is proportional to 1 / n–> n is “good” if n >> rosenberg_n.Note: this also happens to be the solution to lmfp == ldebye…lmfp = (vtherm/nusn) = ((kB T / m)^0.5 / nusn) == (epsilon0 kB T / (n q^2))^0.5 = ldebye–> (nusn^-2 m^-1) == (epsilon0 n^-1 q^-2)–> n == epsilon0 nusn^2 m / q^2.
- get_rosenberg_n_margin()
n / rosenberg_n. margin of safety for rosenberg criterion. “safe” if margin is large.
- get_rosenberg_qn()
Rosenberg criterion for quasineutrality, for each fluid: rosenberg_qn = (nusn / wplasma)^2.
quasineutrality is “reasonable” (during farley-buneman analysis) iff rosenberg_qn << 1 for ions.(Intuitively: quasineutrality reasonable iff ‘collisions much slower than plasma oscillations’)If multiple ions, consider using self(‘rosenberg_multi’) instead of one criterion per ion.see Rosenberg 1998, equation 17, for details.
- get_set_or_cached(var)
returns var if found in self.setvars or self.cache, with compatible behavior_attrs.
otherwise, raise CacheNotApplicableError.if var is found in self.setvars and has relevant, but not matching behavior_attrs,self.load_across_dims will be used to load the value.
- get_sgyrof()
signed gyrofrequency. sgyrof == q |B| / m == charge * |B| / mass. Negative when charge < 0.
- get_skappa()
signed kappa (magnetization parameter). skappa = sgyrof / nusn. Negative when charge < 0.
skappa = gyrofrequency / collision frequency of self.fluid with neutrals.gyrofrequency == q * |B| / (mass * nusn).
- get_skappa_from_hall(var, *, _match=None)
signed kappa (magnetization parameter) that statisfies u_hall = u, in the E x B direction.
‘skappa_from_{means_}{u_}hall’E.g. ‘skappa_from_means_hall’, ‘skappa_from_hall’, ‘skappa_from_means_moment1_hall’{means_} = ‘means_’ or ‘’.if ‘means_’, take means of vars: ‘u’, ‘u_neutral’, ‘mod_B’, ‘E_cross_B’{u_} = ‘’ or any other var then ‘_’.if provided, use this var instead of ‘u’ for velocity. (Doesn’t affect “u_neutral” though.)E.g. eppic calculator might use ‘moment1’ here, as in ‘skappa_from_moment1_hall’.Algebraic solution:formula for u_hall (from solving momentum equation for u in the E x B direction):u_hall = (kappa**2 / (1 + kappa**2)) * (E x B) / |B|**2solving for kappa**2, assuming u instead of u_hall, yields:(u dot (E x B)) == (kappa**2 / (1 + kappa**2)) * (|E x B|**2 / |B|**2)A + A * kappa**2 - kappa**2 == 0, where A = (u dot (E x B)) / (|E x B|**2 / |B|**2)kappa**2 = A / (1 - A)–> skappa = +- sqrt(A / (1 - A)),There are two solutions; return solution with the same sign as self(‘q’) (i.e. fluid’s charge)
- get_skappa_from_momE(var, *, _match=None)
signed kappa (magnetization parameter) that statisfies momentum equation in the E direction.
‘skappa_from_{means_}{u_}momE’E.g. ‘skappa_from_means_momE’, ‘skappa_from_momE’, ‘skappa_from_means_moment1_momE’{means_} = ‘means_’ or ‘’.if ‘means_’, take means of vars: ‘u’, ‘u_neutral’, ‘mod_E’, ‘mod_B’, ‘E’, ‘E_cross_B’{u_} = ‘’ or any other var then ‘_’.if provided, use this var instead of ‘u’ for velocity. (Doesn’t affect “u_neutral” though.)E.g. eppic calculator might use ‘moment1’ here, as in ‘skappa_from_moment1_momE’.Algebraic solution:momentum equation, rearranged using skappa = q * |B| / (m * nusn):0 = q (E + u x B) - m * nusn * (u - u_neutral)0 = skappa (E + u x B) - |B| (u - u_neutral)dotting with E:0 = skappa (|E|^2 + (u x B) dot E) - |B| (u - u_neutral) dot E # note uxB.E == BxE.u == -ExB.u–> skappa = |B| (u - u_neutral) dot E / (|E|^2 - u dot (E x B))Note: results untrustworthy when kappa >> 1, since that involves dividing by a value close to 0.
- get_skappa_from_momExB(var, *, _match=None)
signed kappa (magnetization parameter) that statisfies momentum equation in the E x B direction.
‘skappa_from_{means_}{u_}momExB’E.g. ‘skappa_from_means_momExB’, ‘skappa_from_momExB’, ‘skappa_from_means_moment1_momExB’{means_} = ‘means_’ or ‘’.if ‘means_’, take means of vars: ‘u’, ‘u_neutral’, ‘mod_B’, ‘E_cross_B’, ‘u_cross_B’{u_} = ‘’ or any other var then ‘_’.if provided, use this var instead of ‘u’ for velocity. (Doesn’t affect “u_neutral” though.)E.g. eppic calculator might use ‘moment1’ here, as in ‘skappa_from_moment1_momExB’.Algebraic solution:momentum equation, rearranged using skappa = q * |B| / (m * nusn):0 = q (E + u x B) - m * nusn * (u - u_neutral)0 = skappa (E + u x B) - |B| (u - u_neutral)dotting with E x B:0 = skappa [(u x B) dot (E x B)] - |B| [(u - u_neutral) dot (E x B)]–> skappa = |B| [(u - u_neutral) dot (E x B)] / [(u x B) dot (E x B)]
- get_skappa_from_pedersen(var, *, _match=None)
signed kappa (magnetization parameter) that statisfies u_pedersen = u, in the E direction.
‘skappa_from_{means_}{u_}pedersen’E.g. ‘skappa_from_means_pedersen’, ‘skappa_from_pedersen’, ‘skappa_from_means_moment1_pedersen’{means_} = ‘means_’ or ‘’.if ‘means_’, take means of vars: ‘u’, ‘u_neutral’, ‘mod_B’, ‘E’, ‘mod_E’,{u_} = ‘’ or any other var then ‘_’.if provided, use this var instead of ‘u’ for velocity. (Doesn’t affect “u_neutral” though.)E.g. eppic calculator might use ‘moment1’ here, as in ‘skappa_from_moment1_pedersen’.Algebraic solution:formula for u_pedersen (from solving momentum equation for u in the E direction):u_pedersen = (skappa / (1 + skappa**2)) * E / |B|solving for skappa, assuming u instead of u_pedersen, yields:(u dot E) == (skappa / (1 + skappa**2)) * (|E|**2 / |B|)A + A * skappa**2 - skappa == 0, where A = (u dot E) / (|E|**2 / |B|)skappa = (1 +- sqrt((-1)^2 - 4 * A * A)) / (2 * A),There are two solutions; the correct choice can be determined by using the momentum equation;the correct choice for the +- sign turns out to be: -sign(q) where q = self(‘q’) == fluid’s charge.Note: results untrustworthy when kappa >> 1, since that involves dividing by a value close to 0.
- get_u_EdotB(*, _E=None, _B=None)
EdotB drift velocity. u_EdotB = (skappa**3 / (1 + skappa**2)) * (E_un0 dot B) B / |B|^3
(Commonly neglected, but comes from the same physical equation as hall & pedersen drifts;from solving equilibrium momentum equation for u, when neglecting all derivatives.)[EFF] for efficiency, can provide E and/or B, if already known.
- get_u_drift()
equilibrium velocity; solution to the momentum equation with collisions,
assuming zero acceleration and zero spatial gradients.u_drift = u_hall + u_pedersen + u_EdotB.
- get_u_hall(*, _E=None, _B=None)
Hall drift velocity. u_hall = (kappa**2 / (1 + kappa**2)) * (E_un0 x B) / |B|**2,
where kappa is the magnetization parameter, kappa = gyrof / nusn.[EFF] for efficiency, can provide E and/or B, if already known.
- get_u_pedersen(*, _E=None, _B=None)
Pedersen drift velocity. u_pedersen = (skappa / (1 + skappa**2)) * E_un0 / |B|,
where skappa is the (signed) magnetization parameter, skappa = q * |B| / (m * nusn).[EFF] for efficiency, can provide E and/or B, if already known.
- get_valfven()
Alfven speed. valfven = |B| / sqrt(mu0 * r)
- get_valfven2()
Alfven speed squared. valfven2 = |B|^2 / (mu0 * r)
- get_vars(vars, *args, return_type='dataset', missing_vars=UNSET, **kw)
returns values of vars from self.
result is probably an xarray.Dataset, but not guaranteed; also depends on return_type.Equivalent to self(vars, *args, return_type=’dataset’, **kw).(Actually, self(vars, …) will call self.get_vars(vars, …).)vars: iterable of strsNames of the vars to load. [‘n’, ‘u’] for number density & velocity.if any of these vars returns a return_type object, expand its keys,e.g. if ‘myDSvar’ returns dataset with ‘myvar1’, ‘myvar2’,then [‘n’, ‘myDSvar’] gives dataset with ‘n’, ‘myvar1’, ‘myvar2’.return_type: ‘dataset’ or ‘dict’if ‘dataset’, return result as xarray.Dataset.the data_var names will be the same as the var names.if ‘dict’, return result as dict of {var: value}.missing_vars: UNSET, ‘ignore’, ‘warn’, or ‘raise’what to do if any vars cause FormulaMissingError at any point in the error stack.UNSET –> use self.missing_vars if it exists, else ‘raise’.‘ignore’ –> ignore missing vars, and don’t include them in the result.‘warn’ –> ignore missing vars, but print a warning.‘raise’ –> raise FormulaMissingError if any vars are missing.additional args & kwargs are passed to self(…).
- get_vtherm()
thermal velocity. vtherm = sqrt(kB T / m)
- get_vtherm_n()
thermal velocity for neutrals. vtherm_n = sqrt(kB T_n / m_n)
- get_wplasma()
“plasma frequency”. wplasma = sqrt(n q^2 / (m epsilon0))
This is analogous to the “true” plasma frequency of Langmuir oscillations,which is calculated using the same formula but applied to electrons.wplasma is equivalent to wplasmae if self.fluid is electrons.
- get_wplasmae()
electron plasma frequency; Langmuir oscillations. wpe = sqrt(ne qe^2 / (me epsilon0))
- has_var(var)
return whether self can load var. True if self.match_var(var) is found, else False.
Subclasses might override, to include checks for whether var can be loaded from data.[TODO] also check if var in self.cache or self.setvars.
- help(qstr=None, only=None, *, tree=None, modules=False, signature=False, doc=True, dense=False, print=True)
prints str for help with quants.
qstr: None or str
None –> tells info about this class & how to use this function.in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,and describes behavior of calling help with a string.str –> return str for help with all quants related to str.use empty str to get help for all quants.only: None or strIf provided, only get help for a subset of relevant quantities.None –> get help with all quantities related to qstr.‘VARS’ –> only get help with KNOWN_VARS.‘PATTERNS’ –> only get help with KNOWN_PATTERNS.‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.if provided when qstr is None, treat qstr as ‘’ instead.tree: None or boolHow much help to give for quantities in cls.cls_var_tree(qstr).False –> don’t even check cls.cls_var_tree(qstr).True –> help for all quantities in cls.cls_var_tree.None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).modules: boolWhether to include modules in result.If True, result will be grouped into sections with modules written at top.signature: signature: boolwhether to include line with signature in help string.e.g. “help_str(f, *, module=True, signature=True, indent=None)”doc: doc: boolwhether to include lines with docstring in help string.e.g. “return str for help(f).” … and all the other docs in here.dense: boolWhether to reduce whitespace in result.E.g. True –> no newlines between functions. False –> one newline between functions.
- help_call_options(search=None)
prints help for kw_call_options.
if search is provided, only print help for keys containing search.
- classmethod help_quants_str(qstr=None, only=None, *, tree=None, modules=True, signature=False, doc=True, dense=False, _instance=None)
returns str for help with quants.
qstr: None or str
None –> tells info about this class & how to use this function.in particular, tells that quants are stored cls.KNOWN_VARS and cls.KNOWN_PATTERNS,and describes behavior of calling help with a string.str –> return str for help with all quants related to str.use empty str to get help for all quants.only: None or strIf provided, only get help for a subset of relevant quantities.None –> get help with all quantities related to qstr.‘VARS’ –> only get help with KNOWN_VARS.‘PATTERNS’ –> only get help with KNOWN_PATTERNS.‘TREE’ –> only get help with quantities in cls.cls_var_tree(str).‘EXACT’ –> only get help for the KNOWN_VAR exactly matching qstr.if provided when qstr is None, treat qstr as ‘’ instead.tree: None or boolHow much help to give for quantities in cls.cls_var_tree(qstr).False –> don’t even check cls.cls_var_tree(qstr).True –> help for all quantities in cls.cls_var_tree.None –> help for quantities in cls.cls_var_tree(qstr).flat_branches_until_vars()i.e. patterns & vars in tree but ignore any nodes with LoadableVar ancestors.e.g. qstr=’mean_mod_beta’ –> help with ‘mean_(.+)’, ‘mod_(.+)’, and ‘beta’,but no help with dependencies of ‘beta’ (‘q’, ‘mod_B’, ‘m’).modules: boolWhether to include modules in result.If True, result will be grouped into sections with modules written at top.signature: signature: boolwhether to include line with signature in help string.e.g. “help_str(f, *, module=True, signature=True, indent=None)”doc: doc: boolwhether to include lines with docstring in help string.e.g. “return str for help(f).” … and all the other docs in here.dense: boolWhether to reduce whitespace in result.E.g. True –> no newlines between functions. False –> one newline between functions._instance: None or QuantityLoader instanceif provided, use _instance.match_var_tree() instead of cls.cls_var_tree().
- classmethod help_str(qstr=None, only=None, **kw)
returns cls.help_quants_str(qstr=qstr, only=only, **kw).
cls.help() calls help_str.subclasses might overwrite help_str, but probably won’t touch help_quants_str.
- kw_call_options(*, sorted=True)
returns list of kwarg names which can be used to set attrs self during self.__call__.
(see self.__call__ for more details).Here, returns list(self.behavior_attrs) + list(self._extra_kw_for_quantity_loader_call)
- load_direct(var, *args, **kw)
load var “directly”, from some source which is not known by the main part of PlasmaCalcs.
The implementation here just returns self.load_fromfile() (or crashes if not self.enable_fromfile),but subclasses may override to include more checks. (see DirectLoader)(Here also sets self._load_direct_used_override = None to indicate no override was used,i.e. result is from load_fromfile, not from something like setvars nor cache.)return the result (probably a numpy array, but not guaranteed).
- load_fromfile(var, *args, **kw)
load var directly from a file. Other methods should usually use load_direct, instead.
the implementation here just raises LoadingNotImplementedError;subclasses should implement this method in order to load any values from files.
- property maintaining
alias to maintaining_attrs
- maintaining_attrs(*attrs, **attrs_as_flags)
returns context manager which restores attrs of self to their original values, upon exit.
E.g. maintaining_attrs(obj, ‘attr1’, ‘attr2’, attr3=True, attr4=False)–> will restore upon exit, original values of obj.attr1, attr2, and attr3, but not attr4.
- classmethod match_var(var, *, check=['KNOWN_VARS', 'KNOWN_PATTERNS'])
match var from cls.KNOWN_VARS or cls.KNOWN_PATTERNS, or raise FormulaMissingError.
returns result=MatchedQuantity(var, loadable, _match=_match) where:
loadable is the LoadableQuantity associated with this var,_match is:None, if var in cls.KNOWN_VARS;re.fullmatch(pattern, var), if var matches any pattern in cls.KNOWN_PATTERNS.if var matches multiple patterns, only the first matching pattern is used.Uses MatchedVar if match from KNOWN_VARS, MatchedPattern if from KNOWN_PATTERNS.(note that both MatchedVar and MatchedPattern subclass MatchedQuantity.)check: str or list of str from [‘KNOWN_VARS’, ‘KNOWN_PATTERNS’]where to check for matches. Default is to check KNOWN_VARS and KNOWN_PATTERNS.E.g. to only check KNOWN_PATTERNS, use check=[‘KNOWN_PATTERNS’].loadable and _match can be retrieved via result.loadable and result._match.
- match_var_loading_dims(var, **kw_loading_dims)
return dims for loading var across.
Result will probably vary across these dims (but not guaranteed, if any dependency uses reduces_dims.)These are all Dimension dims, not maindims. (E.g. ‘fluid’ and ‘snap’, but not ‘x’, ‘y’, ‘z’).Equivalent: self.match_var_tree(var).loading_dims(**kw_loading_dims)
- match_var_result_dims(var, **kw_result_dims)
return dims which result of cls(var) will vary across.
These are all Dimension dims, not maindims. (E.g. ‘fluid’ and ‘snap’, but not ‘x’, ‘y’, ‘z’).Equivalent: cls.match_var_tree(var).result_dims(**kw_result_dims)
- match_var_result_size(var, *, maindims=True, **kw_result_dims)
return size (number of elements) which self(var) will have.
(Efficient; doesn’t actually get self(var).)Depends on current values of relevant dims. (E.g., self.fluid, not self.fluids)maindims: boolif True, include maindims_shape when calculating size.
- match_var_tree(var=UNSET, **kw_quant_tree_from_quantity_loader)
return QuantTree of MatchedQuantity objects from matching var and all dependencies,
using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).See also: type(self).cls_var_tree, for the classmethod version of this function.Most of the time it is possible to get tree without any details from self,but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.additional kwargs will be passed to QuantTree.from_quantity_loader(…),which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
- matched_pattern_cls
alias of
MatchedPattern
- matched_var_cls
alias of
MatchedVar
- property nondim_behavior_attrs
list of attrs in self which control behavior of self, but which are NOT in self.dimensions.
- plot_check_nusn_from_drift(*, u='u', drift='momExB', cycle1={'ls': ['-', '--', '-.', ':']}, means=True, log=True, **kw_timelines)
plots PlasmaCalcs.timelines() for comparing nusn to nusn inferred from drifts.
This is meant to be used as a quick check. Use this code as an example if you need more low-level control.u: str or iterable of strsvar to use for velocity. Might want something else, e.g. EppicCalculator might use u=’moment1’iterable of strs –> get multiple.drift: str or iterable of strstells the way to infer skappa, and thus nusn. Options: ‘momExB’, ‘momE’, ‘hall’, ‘pedersen’.iterable of strs –> get multiple.cycle1: dict of listsparameters to use for matplotlib plotting if getting multiple u or drift.means: boolwhether to take means of lower-level vars while getting skappa.(e.g. use ‘skappa_from_means_momExB’ instead of ‘skappa_from_momExB’, if True.)log: boolwhether to take log10 of the ratios (nusn_from_drift / nusn) before plotting.returns plt.gcf().
- quant_tree(var=UNSET, **kw_quant_tree_from_quantity_loader)
return QuantTree of MatchedQuantity objects from matching var and all dependencies,
using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).See also: type(self).cls_var_tree, for the classmethod version of this function.Most of the time it is possible to get tree without any details from self,but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.additional kwargs will be passed to QuantTree.from_quantity_loader(…),which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
- property set
alias to set_var
- set_var(var, value, behavior_attrs=None, forall=[], *, ukey=None, forced=False, **kw_using)
set var in self. When later doing self(var) to get var, return the set value,
but only if self.behavior is compatible with the relevant parts of self.behavior when var was set.This function will use, if it exists:self.KNOWN_SETTERS[var](self, value, behavior_attrs, forall=forall)Otherwise, calls:self.set_var_internal(var, value, self.behavior_attrs, forall=forall)var: strthe var to set in self.value: number, xarray, iterable or 1D array, array with shape matching self.maindims_shape.the value to set var to.number –> set var to this number.xarray –> set var to this xarray.[TODO](not yet implemented) iterable or 1D array –> set var to these values along dim=’testing’.[TODO](not yet implemented) array with shape matching self.maindims_shape –> set var to this array.behavior_attrs: None or listtells which attrs from self control behavior of the set var.The set var will only be retrieved when behavior_attrs of self are compatible.E.g. set_var(‘n’, [‘fluid’, ‘snap’]) –> saves ‘n’ in cache with current fluid & snap.Will only load ‘n’ if self.fluid and self.snap == cached fluid and snap for ‘n’.if var in self.KNOWN_SETTERS, cannot provide behavior_attrs here.else, use self.behavior_attrs if None.forall: list of stringsif provided, tells which attrs of self do NOT control the behavior of the set var.E.g. forall=[‘snap’] –> ‘snap’ will NOT be included in behavior_attrs.(anything in behavior_attrs AND forall will be removed from the final behavior_attrs)ukey: None or strif provided, tells string to give to UnitsManager when converting value’s units.When ukey is known, setting value in any unit system will enable to read it in all unit systems.E.g. set_var(‘n’, 1e10, …, ukey=’n’, units=’si’)–> self(‘n’, units=’raw’) == self(‘n’, units=’si’) * self.u(‘u’, ‘raw’, convert_from=’si’)if not provided, value will be associated with current unit system;attempted to read value in any other unit system will not used the cached value set here.E.g. set_var(‘u’, 1e10, …, units=’si’) # ukey not provided–> self(‘u’, units=’raw’) –> uses self’s other logic for getting ‘u’, not from setvars.note: if provided, ‘units’ will be added to behavior_attrs if not already in there.forced: bool, default Truehandles the case where self.KNOWN_SETTERS[var] doesn’t exist. In that case…True –> set var in self, anyway.False –> crash; raise FormulaMissingErroradditional kwargs, if provided, go to self.using(**kw) during the operation.returns list of set quantities.
- set_var_internal(var, value, behavior_attrs, forall=[], *, ukey=None)
set var in self. KNOWN_SETTERS functions may wish to use this method.
(KNOWN_SETTERS functions should NOT use self.set_var, to avoid recursion issue.)This function has the internal logic for self.set_var;set_var calls set_var_internal when self.KNOWN_SETTERS[var] not provided.var: strthe var to set in self.value: number, xarray, iterable or 1D array, array with shape matching self.maindims_shape.the value to set var to. See help(self.set_var) for more info.behavior_attrs: list of stringsthe behavior attrs relevant to setting this var;getting var only gives value when current behavior attrs values are compatible with the cached ones.forall: list of stringsif provided, tells which behavior attrs do NOT control the behavior of the set var.e.g. behavior_attrs=[‘snap’, ‘fluid’], forall=[‘snap’] –> use [‘fluid’], only.ukey: None or strif provided, tells string to give to UnitsManager when converting value’s units;when ukey is provided, can retrieve value in any unit system (probably ‘si’ or ‘raw’).when ukey not provided, if ‘units’ in used behavior attrs, can only retrieve value in that unit system.
- set_vtherm(value, **kw)
set thermal velocity, by setting T.
vtherm = sqrt(kB T / m) –> set T to (m vtherm^2 / kB).
- property setvar
alias to set_var
- property setvars
VarCache of vars set via self.set_var(). Returns these values when appropriate,
i.e. whenever self.behavior is compatible with the behavior in the cache.To empty the cache, use self.setvars.clear() to empty the cache.
- property toplevel_scale_coords
dict of {coord_name: coord_scaling} to apply to top-level outputs of self(var).
(Never applies to internal calls of self(var), only applies at self.call_depth==1.)Useful if making plots and want to scale coords by some factor.E.g., self.toplevel_scale_coords = {‘t’: 1000} to convert s to ms.CAUTION: coord units labels will remain unaffected.
- tree(var=UNSET, **kw_quant_tree_from_quantity_loader)
return QuantTree of MatchedQuantity objects from matching var and all dependencies,
using self.KNOWN_VARS and self.KNOWN_PATTERNS when searching for matches.var must be provided; var=UNSET will raise an error (helpful if tried calling this as a classmethod).See also: type(self).cls_var_tree, for the classmethod version of this function.Most of the time it is possible to get tree without any details from self,but sometimes not. e.g. when getting collision frequencies, self.fluid affects deps.additional kwargs will be passed to QuantTree.from_quantity_loader(…),which passes kwargs from self.kw_call_options() into self.using(**kw) while getting deps.
- property typevar_crash_if_nan
bool. whether to crash methods if typevar output would be ‘nan’.
False –> return NaN when typevar gives ‘nan’, instead of crashing.“typevar” here refers to any var used for checking which formula to use, from various options,e.g. ‘ntype’ in MhdMultifluidLoader or ‘ionfrac_type’ in MhdIonizationLoader.The relevant methods can check if self.typevar_crash_if_nan before returning a ‘nan’ result.
- property unset
alias to unset_var
- unset_var(var, behavior_attrs=[], *, missing_ok=True, **kw_using)
remove var from self.setvars (but only at values stored with relevant behavior).
[TODO] define rules for which vars unset which other vars…e.g. for eppic right now, set_var(‘n’) sets ‘den’ but not ‘n’;unset_var(‘n’) unsets nothing… but should probably alias to unset_var(‘den’).behavior_attrs: list of stringsonly remove cached values where self.behavior matches cached behavior for these attrs.if empty, remove all cached values for var, regardless of associated behavior.missing_ok: boolwhether it is okay for there to be zero matching cached values for var.raise CacheNotApplicableError if missing_ok=False when there are no matching cached values.additional kwargs, if provided, go to self.using(**kw) during the operation.return list of CachedQuantity objects which were removed from self.setvars.
- unset_var_internal(var, behavior_attrs, forall=[], *, ukey=None, missing_ok=True)
unset var from self.setvars.
KNOWN_SETTERS functions may wish to use this method, to unset dependent values.E.g. if u depends on n, and n is changed, may wish to unset the value of u.behavior_attrs: list of stringsthe behavior attrs relevant to setting this var.forall: list of stringsif provided, tells which behavior attrs to ignore when unsetting the var.ukey: None or stringif provided, ignore ‘units’ behavior attr when unsetting the var(due to assuming that ukey was provided when setting the var,hence that the set var could be retrieved in any units system)missing_ok: boolwhether it is okay for there to be zero matching cached values for var.raise CacheNotApplicableError if missing_ok=False when there are no matching cached values.return list of CachedQuantity objects which were removed from self.setvars.
- property using
alias to using_attrs
- using_at_call_depth(depth, **attrs_and_values)
context manager for setting attrs_and_values but only while call_depth == depth.
E.g.:
with self.using_at_call_depth(3, verbose=3):self(‘sgyrof’)# while self.call_depth == 3 inside of this ‘with’ block, uses self.verbose=3.# but everywhere else, uses original value of verbose.# assuming originally verbose=False (or unset), this example will print:| | (call_depth=2) get var=’q’| | (call_depth=2) get var=’mod_B’| | (call_depth=2) get var=’m’# compare this to simply using self.verbose=3, which would print:| (call_depth=1) get var=’sgyrof’| | (call_depth=2) get var=’q’| | (call_depth=2) get var=’mod_B’| | | (call_depth=3) get var=’B_dot_B’| | | | (call_depth=4) get var=’B_xyz’| | | | | (call_depth=5) get var=’B’| | (call_depth=2) get var=’m’Equivalent to self.call_depth_manager.using_obj_attrs_at(depth, **attrs_and_values)
- using_at_next_call_depth(**attrs_and_values)
context manager for setting attrs_and_values but only while call_depth == self.call_depth + 1
Equivalent to self.using_at_call_depth(self.call_depth + 1, **attrs_and_values).
(Also equivalent to self.call_depth_manager.using_obj_attrs_at_next(**attrs_and_values).)
- using_attrs(attrs_as_dict={}, _unset_sentinel=ATTR_UNSET, **attrs_and_values)
returns context manager which sets attrs of obj upon entry; restores original values upon exit.
_unset_sentinel: any value, default ATTR_UNSETupon entry, delete any attrs with value _unset_sentinel (compared via ‘is’).E.g. using_attrs(obj, _unset_sentinel=None, x=None) –> del obj.x upon entry.