function varargout = chi_e(varargin) %#codegen
% Electron heat conductivity module for RAPTOR
%
%   params = chi_e; % get default parameters
%   [chie,dchie_dx] = chi_e(x,xdot,g,v,vdot,u,it,model,params) % run module
%
% returns heat conductivity and derivatives. all outputs are on grid [rhogauss]
%
% Several options are available, set by 'cp.modeltype' options:
%   *'chi_FF': Use analytical transport model from F. Felici thesis
%   *'chi_BgB': Bohm-Gyrobohm
%   *'chi_QLKNN4Dkin': 4D-input NN Based conductivity model from qualikiz
%   *'chi_QLKNN10D': 10D version
%   *'chi_MS': Use analytical transport model from Kim, PPCF 2016(58) 055002
%   *'chi_manual' assign to cp a scalar, or array of size [nrhogauss,1] for manual chie.

% note that q*rho/s = rho/(iota*s) = -rho/(iota * diota/drho*(rho/iota))
% = 1/(diota/drho)

coder.extrinsic('chi_MS');

%% DEFAULT PARAMETERS

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Input processing

if nargin == 0
  varargout{1} = RAPTORmodule('chi_FF');
  return %empty call, probably to get default structures
elseif nargin == 1
  error('deprecated use, use RAPTORmodule instead')
elseif nargin==6
  stap   = varargin{1};
  geop   = varargin{2};
  trap   = varargin{3};
  it     = varargin{4};
  model  = varargin{5};
  params = varargin{6};
else
  error('must call with 0 or 6 inputs');
end

%%%% CHIE MODULE
% initialize
dchie_dx = zeros(model.rgrid.nrhogauss,model.dims.nx);
dchii_dx = zeros(model.rgrid.nrhogauss,model.dims.nx);
dchie_dxdot = zeros(model.rgrid.nrhogauss,model.dims.nx);
dchii_dxdot = zeros(model.rgrid.nrhogauss,model.dims.nx);
dchie_du = zeros(model.rgrid.nrhogauss,model.dims.nu);
dchii_du = zeros(model.rgrid.nrhogauss,model.dims.nu);

switch model.chi_e.name
  case 'chi_FF'
    if nargout<=2
      [chie,chii] = chi_FF(stap,geop,trap,it,model,params.chi_e);
    else
      [chie,chii,dchie_dx,dchii_dx] = chi_FF(stap,geop,trap,it,model,params.chi_e);
    end
    
  case 'chi_BgB'
    if nargout<=2
      [chie,chii] = chi_BgB(stap,geop,trap,it,model,params.chi_e) ;
    else
      [chie,chii,dchie_dx,dchii_dx] = chi_BgB(stap,geop,trap,it,model,params.chi_e) ;
    end
    
  case 'chi_QLKNN4Dkin'
    [tcoeff,dtcoeff_dx] = chi_QLKNN4Dkin(stap,geop,trap,it,model,params.chi_e);
    chie = tcoeff.chie;
    chii = tcoeff.chii;
    dchie_dx = dtcoeff_dx.dchie_dx;
    dchii_dx = dtcoeff_dx.dchii_dx;
    
  case 'chi_QLKNN10D'
    [tcoeff,dtcoeff_dx] = chi_QLKNN10D(stap,geop,trap,it,model,params.chi_e);

    chie = tcoeff.chie;
    chii = tcoeff.chii;
    dchie_dx = dtcoeff_dx.dchie_dx;
    dchii_dx = dtcoeff_dx.dchii_dx;
    
  case 'chi_MS'
    if nargout<=2
      [chie,chii] = chi_MS(stap,geop,trap,it,model,params.chi_e) ;
    else
      [chie,chii,dchie_dx,dchii_dx,dchie_dxdot,dchii_dxdot,dchie_du,dchii_du] =...
        chi_MS(stap,geop,trap,it,model,params.chi_e) ;
    end
  case 'chi_manual' % 3 possibilities: constant, time-independent profile or time-dependent profille
    [chie,chii,dchie_dx,dchii_dx,dchie_dxdot,dchii_dxdot,dchie_du,dchii_du] = ...
      chi_manual(stap,geop,trap,it,model,params.chi_e);
  otherwise
    error('invalid setting for chi_e model');
end

% outputs
varargout{1} = chie;
varargout{2} = chii;

if nargout>2
  varargout{3} = dchie_dx;
  varargout{4} = dchii_dx;
  varargout{5} = dchie_dxdot;
  varargout{6} = dchii_dxdot;
  varargout{7} = dchie_du;
  varargout{8} = dchii_du;
end

return
