mirror of
https://git.code.sf.net/p/ngspice/ngspice
synced 2026-08-22 13:57:32 +02:00
Add a generator for SEE (single event effects) pulses as a code model.
To be used like aseegen1 NULL [%id(xcell.n1 m1) %id(xcell.n2 m2) %id(xcell.n1 m1) %id(xcell.n2 m2)] seemod1 .model seemod1 seegen (tdelay = 11n tperiod=25n tfall='tfall' trise='trise' let='let' cdepth='d') see README.SEEgenerator for details
This commit is contained in:
@@ -10,3 +10,4 @@ zener
|
||||
memristor
|
||||
sidiode
|
||||
pswitch
|
||||
seegenerator
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*.......1.........2.........3.........4.........5.........6.........7.........8
|
||||
================================================================================
|
||||
|
||||
FILE seegenerator/cfunc.mod
|
||||
|
||||
Public Domain
|
||||
|
||||
Universty Duisburg-Essen
|
||||
Duisburg, Germany
|
||||
Project Flowspace
|
||||
|
||||
AUTHORS
|
||||
|
||||
19 May 2025 Holger Vogt
|
||||
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the model-specific routines used to
|
||||
functionally describe the see (single event effects) generator code model.
|
||||
|
||||
|
||||
INTERFACES
|
||||
|
||||
FILE ROUTINE CALLED
|
||||
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
Inputs from and outputs to ARGS structure.
|
||||
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
NONE
|
||||
|
||||
===============================================================================*/
|
||||
|
||||
/*=== INCLUDE FILES ====================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
|
||||
static void
|
||||
cm_seegen_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
double *last_t_value = STATIC_VAR (last_t_value);
|
||||
if (last_t_value)
|
||||
free(last_t_value);
|
||||
STATIC_VAR (last_t_value) = NULL;
|
||||
int *pulse_number = STATIC_VAR (pulse_number);
|
||||
if (pulse_number)
|
||||
free(pulse_number);
|
||||
STATIC_VAR (pulse_number) = NULL;
|
||||
break;
|
||||
double *last_ctrl = STATIC_VAR (last_ctrl);
|
||||
if (last_ctrl)
|
||||
free(last_ctrl);
|
||||
STATIC_VAR (last_ctrl) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION void cm_seegen()
|
||||
|
||||
AUTHORS
|
||||
|
||||
19 May 2025 Holger Vogt
|
||||
|
||||
SUMMARY
|
||||
|
||||
This function implements the see generator code model.
|
||||
|
||||
INTERFACES
|
||||
|
||||
FILE ROUTINE CALLED
|
||||
|
||||
CMutil.c void cm_smooth_corner();
|
||||
void cm_smooth_discontinuity();
|
||||
void cm_climit_fcn()
|
||||
|
||||
RETURNED VALUE
|
||||
|
||||
Returns inputs and outputs via ARGS structure.
|
||||
|
||||
GLOBAL VARIABLES
|
||||
|
||||
NONE
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
model source:
|
||||
Ygor Quadros de Aguiar, Frédéric Wrobel. Jean-Luc Autran, Rubén García Alía
|
||||
Single-Event Effects, from Space to Accelerator Environments
|
||||
Springer 2025
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
/*=== CM_SEEGEN ROUTINE ===*/
|
||||
|
||||
void cm_seegen(ARGS) /* structure holding parms,
|
||||
inputs, outputs, etc. */
|
||||
{
|
||||
double tfall; /* pulse fall time */
|
||||
double trise; /* pulse rise time */
|
||||
double tdelay; /* delay until first pulse */
|
||||
double inull; /* max. current of pulse */
|
||||
double let; /* linear energy transfer */
|
||||
double cdepth; /* charge collection depth */
|
||||
double angle; /* particle entrance angle */
|
||||
double tperiod; /* pulse repetition period */
|
||||
double ctrlthres; /* control voltage threshold */
|
||||
double ctrl; /* control input */
|
||||
double out; /* output current */
|
||||
double *last_t_value; /* static storage of next pulse time */
|
||||
int *pulse_number; /* static storage of next pulse time */
|
||||
double *last_ctrl; /* static storage of last ctrl value */
|
||||
double tcurr = TIME; /* current simulation time */
|
||||
|
||||
if (ANALYSIS == MIF_AC) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Retrieve frequently used parameters... */
|
||||
|
||||
tfall = PARAM(tfall);
|
||||
trise = PARAM(trise);
|
||||
tdelay = PARAM(tdelay);
|
||||
tperiod = PARAM(tperiod);
|
||||
inull = PARAM(inull);
|
||||
let = PARAM(let);
|
||||
cdepth = PARAM(cdepth);
|
||||
angle = PARAM(angle);
|
||||
ctrlthres = PARAM(ctrlthres);
|
||||
|
||||
if (PORT_NULL(ctrl))
|
||||
ctrl = 1;
|
||||
else
|
||||
ctrl = INPUT(ctrl);
|
||||
|
||||
if (INIT==1) {
|
||||
/* Allocate storage for last_t_value */
|
||||
STATIC_VAR(last_t_value) = (double *) malloc(sizeof(double));
|
||||
last_t_value = (double *) STATIC_VAR(last_t_value);
|
||||
*last_t_value = tdelay;
|
||||
STATIC_VAR(pulse_number) = (int *) malloc(sizeof(int));
|
||||
pulse_number = (int *) STATIC_VAR(pulse_number);
|
||||
*pulse_number = 1;
|
||||
STATIC_VAR(last_ctrl) = (double *) malloc(sizeof(double));
|
||||
last_ctrl = (double *) STATIC_VAR(last_ctrl);
|
||||
*last_ctrl = ctrl;
|
||||
/* set breakpoints at first pulse start and pulse maximum times */
|
||||
double tatmax = *last_t_value + tfall * trise * log(trise/tfall) / (trise - tfall);
|
||||
cm_analog_set_perm_bkpt(*last_t_value);
|
||||
cm_analog_set_perm_bkpt(tatmax);
|
||||
}
|
||||
else {
|
||||
|
||||
last_t_value = (double *) STATIC_VAR(last_t_value);
|
||||
pulse_number = (int *) STATIC_VAR(pulse_number);
|
||||
last_ctrl = (double *) STATIC_VAR(last_ctrl);
|
||||
|
||||
if (*last_ctrl < ctrlthres && ctrl >= ctrlthres) {
|
||||
*last_t_value = *last_t_value + tcurr;
|
||||
*last_ctrl = ctrl;
|
||||
}
|
||||
|
||||
/* the double exponential current pulse function */
|
||||
if (tcurr < *last_t_value)
|
||||
out = 0;
|
||||
else {
|
||||
if (inull == 0) {
|
||||
double LETeff = let/cos(angle);
|
||||
double Qc = 1.035e-14 * LETeff * cdepth;
|
||||
inull = Qc / (tfall - trise);
|
||||
}
|
||||
out = inull * (exp(-(tcurr-*last_t_value)/tfall) - exp(-(tcurr-*last_t_value)/trise));
|
||||
}
|
||||
if (tcurr > *last_t_value + tperiod * 0.9) {
|
||||
/* return some info */
|
||||
cm_message_printf("port name: out, node pair no.: %d, \nnode names: %s, %s, pulse time: %e",
|
||||
*pulse_number, cm_get_node_name("out", *pulse_number - 1),
|
||||
cm_get_neg_node_name("out", *pulse_number - 1), *last_t_value);
|
||||
/* set the time for the next pulse */
|
||||
*last_t_value = *last_t_value + tperiod;
|
||||
/* set breakpoints at new pulse start and pulse maximum times */
|
||||
double tatmax = *last_t_value + tfall * trise * log(trise/tfall) / (trise - tfall);
|
||||
cm_analog_set_perm_bkpt(*last_t_value);
|
||||
cm_analog_set_perm_bkpt(tatmax);
|
||||
(*pulse_number)++;
|
||||
if (*pulse_number > PORT_SIZE(out)) {
|
||||
if (PARAM(perlim) == FALSE)
|
||||
*pulse_number = 1;
|
||||
else
|
||||
*last_t_value = 1e12; /* stop any output */
|
||||
}
|
||||
}
|
||||
if (*pulse_number - 1 < PORT_SIZE(out))
|
||||
OUTPUT(out[*pulse_number - 1]) = out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*.......1.........2.........3.........4.........5.........6.........7.........8
|
||||
================================================================================
|
||||
Public Domain
|
||||
|
||||
|
||||
Universty Duisburg-Essen
|
||||
Duisburg, Germany
|
||||
Project Flowspace
|
||||
|
||||
AUTHORS
|
||||
|
||||
Holger Vogt 19 May 2025
|
||||
|
||||
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the interface specification file for the
|
||||
analog seegen code model.
|
||||
|
||||
===============================================================================*/
|
||||
|
||||
NAME_TABLE:
|
||||
|
||||
C_Function_Name: cm_seegen
|
||||
Spice_Model_Name: seegen
|
||||
Description: "single event effect generator"
|
||||
|
||||
|
||||
PORT_TABLE:
|
||||
|
||||
Port_Name: ctrl out
|
||||
Description: "control input" "output"
|
||||
Direction: in out
|
||||
Default_Type: v i
|
||||
Allowed_Types: [v,vd,i,id] [i,id]
|
||||
Vector: no yes
|
||||
Vector_Bounds: - [1 -]
|
||||
Null_Allowed: yes no
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: tfall trise
|
||||
Description: "pulse fall time" "pulse rise time"
|
||||
Data_Type: real real
|
||||
Default_Value: 500e-12 20e-12
|
||||
Limits: - -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: tdelay inull
|
||||
Description: "pulse delay" "max current"
|
||||
Data_Type: real real
|
||||
Default_Value: 0 0
|
||||
Limits: - -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: tperiod ctrlthres
|
||||
Description: "pulse repetition" "control voltage threshold"
|
||||
Data_Type: real real
|
||||
Default_Value: 0 0.5
|
||||
Limits: - -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: let cdepth
|
||||
Description: "lin energy transfer" "charge collection depth"
|
||||
Data_Type: real real
|
||||
Default_Value: 10 1
|
||||
Limits: - -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: angle perlim
|
||||
Description: "particle angle" "pulse repetition"
|
||||
Data_Type: real boolean
|
||||
Default_Value: 0 TRUE
|
||||
Limits: [0 1.57079] -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: last_t_value
|
||||
Data_Type: pointer
|
||||
Vector: no
|
||||
Description: "next pulse start time"
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: pulse_number
|
||||
Data_Type: pointer
|
||||
Vector: no
|
||||
Description: "number of pulse"
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: last_ctrl
|
||||
Data_Type: pointer
|
||||
Vector: no
|
||||
Description: "last control value"
|
||||
Reference in New Issue
Block a user