You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
6.6 KiB
233 lines
6.6 KiB
/*.......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;
|
|
OUTPUT(mon) = out;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|