Changeset 8993


Ignore:
Timestamp:
Jun 23, 2016 9:18:34 AM (3 years ago)
Author:
efredriksson
Message:

#4815 Major cleanup of run-time

  • Removed old Jacobian/partial derivatives code
  • Removed old DAE and init system interface
  • Moved things between jmi.x and jmi_util.x so they are easier to find
  • There are only one set of index/type to/from value reference functions
Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/base.c

    r8300 r8993  
    181181    jmi_z_offset_strings(&(*jmi)->z_t.strings.offsets);
    182182
    183     jmi_init(jmi, N_real_ci, N_real_cd,  N_real_pi,    N_real_pi_s,    N_real_pi_f,    N_real_pi_e,    N_real_pd,
    184              N_integer_ci, N_integer_cd, N_integer_pi, N_integer_pi_s, N_integer_pi_f, N_integer_pi_e, N_integer_pd,
    185              N_boolean_ci, N_boolean_cd, N_boolean_pi, N_boolean_pi_s, N_boolean_pi_f, N_boolean_pi_e, N_boolean_pd,
    186              N_real_dx, N_real_x, N_real_u, N_real_w,
    187              N_real_d, N_integer_d, N_integer_u, N_boolean_d, N_boolean_u,
    188              N_outputs, (int (*))Output_vrefs,
    189              N_sw, N_sw_init, N_time_sw,N_state_sw, N_guards, N_guards_init,
    190              N_dae_blocks, N_dae_init_blocks,
    191              N_initial_relations, (int (*))DAE_initial_relations,
    192              N_relations, (int (*))DAE_relations, N_dynamic_state_sets,
    193              (jmi_real_t *) DAE_nominals,
    194              Scaling_method, N_ext_objs, Homotopy_block, jmi_callbacks);
     183    jmi_init(jmi, N_real_ci,      N_real_cd,      N_real_pi,      N_real_pi_s,
     184                  N_real_pi_f,    N_real_pi_e,    N_real_pd,      N_integer_ci,
     185                  N_integer_cd,   N_integer_pi,   N_integer_pi_s, N_integer_pi_f,
     186                  N_integer_pi_e, N_integer_pd,   N_boolean_ci,   N_boolean_cd,
     187                  N_boolean_pi,   N_boolean_pi_s, N_boolean_pi_f, N_boolean_pi_e,
     188                  N_boolean_pd,   N_real_dx,      N_real_x,       N_real_u,
     189                  N_real_w,       N_real_d,       N_integer_d,    N_integer_u,
     190                  N_boolean_d,    N_boolean_u,    N_sw,           N_sw_init,
     191                  N_time_sw,      N_state_sw,     N_guards,       N_guards_init,
     192                  N_dae_blocks,   N_dae_init_blocks, N_initial_relations,
     193                  (int (*))DAE_initial_relations, N_relations,
     194                  (int (*))DAE_relations, N_dynamic_state_sets,
     195                  (jmi_real_t *) DAE_nominals, Scaling_method, N_ext_objs,
     196                  Homotopy_block, jmi_callbacks);
    195197
    196198$C_dynamic_state_add_call$
    197199
    198200    model_add_blocks(jmi);
    199    
    200201    model_init_add_blocks(jmi);
    201202
    202     /* Initialize the DAE interface */
    203     jmi_dae_init(*jmi, *model_dae_F, N_eq_F, NULL, 0, NULL, NULL,
    204                  *model_dae_dir_dF,
    205                  CAD_dae_n_nz,(int (*))CAD_dae_nz_rows,(int (*))CAD_dae_nz_cols,
    206                  CAD_ODE_A_n_nz, (int (*))CAD_ODE_A_nz_rows, (int(*))CAD_ODE_A_nz_cols,
    207                  CAD_ODE_B_n_nz, (int (*))CAD_ODE_B_nz_rows, (int(*))CAD_ODE_B_nz_cols,
    208                  CAD_ODE_C_n_nz, (int (*))CAD_ODE_C_nz_rows, (int(*))CAD_ODE_C_nz_cols,
    209                  CAD_ODE_D_n_nz, (int (*))CAD_ODE_D_nz_rows, (int(*))CAD_ODE_D_nz_cols,
    210                  *model_dae_R, N_eq_R, NULL, 0, NULL, NULL,*model_ode_derivatives,
    211                  *model_ode_derivatives_dir_der,
    212                  *model_ode_outputs,*model_ode_initialize,*model_ode_guards,
    213                  *model_ode_guards_init,*model_ode_next_time_event);
    214 
    215     /* Initialize the Init interface */
    216     jmi_init_init(*jmi, *model_init_F0, N_eq_F0, NULL,
    217                   0, NULL, NULL,
    218                   *model_init_F1, N_eq_F1, NULL,
    219                   0, NULL, NULL,
    220                   *model_init_Fp, N_eq_Fp, NULL,
    221                   0, NULL, NULL,
    222                   *model_init_eval_parameters,
    223                   *model_init_R0, N_eq_R0, NULL,
    224                   0, NULL, NULL);
     203    /* Initialize the model equations interface */
     204    jmi_model_init(*jmi,
     205                   *model_ode_derivatives_dir_der,
     206                   *model_ode_derivatives,
     207                   *model_ode_event_indicators,
     208                   *model_ode_initialize,
     209                   *model_init_eval_parameters,
     210                   *model_ode_next_time_event);
    225211   
    226212    /* Initialize the delay interface */
    227     jmi_init_delay_if(*jmi, N_delays, N_spatialdists, *model_init_delay, *model_sample_delay, N_delay_sw);
     213    jmi_init_delay_if(*jmi, N_delays, N_spatialdists, *model_init_delay,
     214                      *model_sample_delay, N_delay_sw);
    228215
    229216    return 0;
  • trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/base.h

    r8300 r8993  
    2828int model_ode_derivatives(jmi_t* jmi);
    2929int model_ode_initialize(jmi_t* jmi);
    30 int model_dae_R(jmi_t* jmi, jmi_real_t** res);
     30int model_ode_event_indicators(jmi_t* jmi, jmi_real_t** res);
    3131int model_init_R0(jmi_t* jmi, jmi_real_t** res);
    3232void model_add_blocks(jmi_t** jmi);
  • trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/equ.c

    r7967 r8993  
    3535}
    3636
    37 int model_dae_R(jmi_t* jmi, jmi_real_t** res) {
     37int model_ode_event_indicators(jmi_t* jmi, jmi_real_t** res) {
    3838$C_DAE_event_indicator_residuals$
    3939    return 0;
  • trunk/RuntimeLibrary/src/fmi1_me/fmi1_me.c

    r8305 r8993  
    361361    }
    362362
    363     /* For debugging Jacobians */
    364 /*
    365     n_states = ((fmi1_me_t *)c)->jmi->n_real_x;
    366     jac = (jmi_real_t*)calloc(n_states*n_states,sizeof(jmi_real_t));
    367     fmi_get_jacobian(c, FMI_STATES, FMI_DERIVATIVES, jac, n_states);
    368 
    369     for (i=0;i<n_states;i++) {
    370         for (j=0;j<n_states;j++) {
    371             printf("%f, ",jac[i + j*n_states]);
    372         }
    373         printf("\n");
    374     }
    375 
    376     free(jac);
    377 */
    378 
    379363#ifdef JMI_PROFILE_RUNTIME
    380364    {
     
    414398   
    415399    retval = jmi_get_event_indicators(jmi, eventIndicators, ni);
    416     if (retval != 0) {
    417         return fmiError;
    418     }
    419    
    420     return fmiOK;
    421 }
    422 
    423 fmiStatus fmi1_me_get_partial_derivatives(fmiComponent c, fmiStatus (*setMatrixElement)(void* data, fmiInteger row, fmiInteger col, fmiReal value), void* A, void* B, void* C, void* D){   
    424 
    425 /* fmi_get_jacobian is not an FMI function. Still use fmiStatus as return arguments?. Is there an error handling policy? Standard messages? Which function should return errors?*/
    426    
    427     fmiStatus fmiFlag;
    428     fmiReal* jac;
    429     fmi1_me_t* fmi1_me = (fmi1_me_t*)c;
    430     jmi_t* jmi = &fmi1_me->jmi;
    431     int nA;
    432     int nB;
    433     int nC;
    434     int nD;
    435     int nx;
    436     int nu;
    437     int ny;
    438     int jac_size;
    439     int i;
    440     int row;
    441     int col;
    442 
    443     int n_outputs;
    444     int* output_vrefs;
    445 
    446     clock_t /*c0, c1,*/ d0, d1;
    447     jmi_real_t setElementTime;
    448 
    449     /* c0 = clock(); */
    450 
    451     setElementTime = 0;
    452 
    453     /* Get number of outputs that are variability = "continuous", ny */
    454     n_outputs = ny = jmi->n_outputs;
    455     if (!(output_vrefs = (int*)fmi1_me -> fmi_functions.allocateMemory(n_outputs, sizeof(int)))) {
    456         jmi_log_comment(jmi->log, logError, "Out of memory.");
    457         return fmiError;
    458     }
    459        
    460     jmi_get_output_vrefs(jmi, output_vrefs);
    461 
    462     /* This analysis needs to be extended to account for discrete reals*/
    463     for(i = 0; i < n_outputs; i++)
    464         if (get_type_from_value_ref(output_vrefs[i])!= 0)
    465             ny--;   
    466     fmi1_me -> fmi_functions.freeMemory(output_vrefs);
    467    
    468     nx = jmi->n_real_x;
    469     nu = jmi->n_real_u;
    470    
    471     nA = nx*nx;
    472     nB = nx*nu;
    473     nC = ny*nx;
    474     nD = ny*nu;
    475 
    476     /*
    477     if (fmi1_me -> fmi_logging_on) {
    478         jmi_log_node(jmi->log, logInfo, "size_of_A", "<m: %d, n:%d>", nx, nx);
    479         jmi_log_node(jmi->log, logInfo, "size_of_B", "<m: %d, n:%d>", nx, nu);
    480         jmi_log_node(jmi->log, logInfo, "size_of_C", "<m: %d, n:%d>", ny, nx);
    481         jmi_log_node(jmi->log, logInfo, "size_of_D", "<m: %d, n:%d>", ny, nu);
    482     }
    483      */
    484 
    485     /* Allocate a big chunk of memory that is enough to compute all Jacobians */
    486     jac_size = nA + nB + nC + nD;
    487 
    488     /* Allocate memory for the biggest matrix, use this for all matrices. */
    489     if (!(jac = fmi1_me -> fmi_functions.allocateMemory(sizeof(fmiReal),jac_size))) {
    490         jmi_log_comment(jmi->log, logError, "Out of memory.");
    491         return fmiError;
    492     }
    493 
    494     /* Individual calls to evaluation of A, B, C, D matrices can be made
    495      * more efficiently by evaluating several Jacobian at the same time.
    496      */
    497 
    498     /* Get the internal A matrix */
    499     fmiFlag = fmi1_me_get_jacobian(c, FMI_STATES, FMI_DERIVATIVES, jac, nA);
    500     if (fmiFlag > fmiWarning) {
    501         jmi_log_comment(jmi->log, logError, "Evaluating the A matrix failed.");
    502         fmi1_me -> fmi_functions.freeMemory(jac);
    503         return fmiFlag;
    504     }
    505 
    506     /* Update external A matrix */
    507     for (row=0;row<nx;row++) {
    508         for (col=0;col<nx;col++) {
    509             d0 = clock();
    510             fmiFlag = setMatrixElement(A,row+1,col+1,jac[row + col*nx]);
    511             d1 = clock();
    512             setElementTime += ((fmiReal)(d1-d0))/(CLOCKS_PER_SEC);
    513             if (fmiFlag > fmiWarning) {
    514                 jmi_log_comment(jmi->log, logError, "setMatrixElement failed to update matrix A");
    515                 fmi1_me -> fmi_functions.freeMemory(jac);
    516                 return fmiFlag;
    517             }
    518         }
    519     }
    520 
    521     /* Get the internal B matrix */
    522     fmiFlag = fmi1_me_get_jacobian(c, FMI_INPUTS, FMI_DERIVATIVES, jac, nB);
    523     if (fmiFlag > fmiWarning) {
    524         jmi_log_comment(jmi->log, logError, "Evaluating the B matrix failed.");
    525         fmi1_me -> fmi_functions.freeMemory(jac);
    526         return fmiFlag;
    527     }
    528     /* Update external B matrix */
    529     for (row=0;row<nx;row++) {
    530         for (col=0;col<nu;col++) {
    531             d0 = clock();
    532             fmiFlag = setMatrixElement(B,row+1,col+1,jac[row + col*nx]);
    533             d1 = clock();
    534             setElementTime += ((fmiReal)(d1-d0))/(CLOCKS_PER_SEC);
    535             if (fmiFlag > fmiWarning) {
    536                 jmi_log_comment(jmi->log, logError, "setMatrixElement failed to update matrix B");
    537                 fmi1_me -> fmi_functions.freeMemory(jac);
    538                 return fmiFlag;
    539             }
    540         }
    541     }
    542 
    543     /* Get the internal C matrix */
    544     fmiFlag = fmi1_me_get_jacobian(c, FMI_STATES, FMI_OUTPUTS, jac, nC);
    545     if (fmiFlag > fmiWarning) {
    546         jmi_log_comment(jmi->log, logError, "Evaluating the C matrix failed.");
    547         fmi1_me -> fmi_functions.freeMemory(jac);
    548         return fmiFlag;
    549     }
    550     /* Update external C matrix */
    551     for (row=0;row<ny;row++) {
    552         for (col=0;col<nx;col++) {
    553             d0 = clock();
    554             fmiFlag = setMatrixElement(C,row + 1, col + 1, jac[row+col*ny]);
    555             d1 = clock();
    556             setElementTime += ((fmiReal)(d1-d0))/(CLOCKS_PER_SEC);
    557             if (fmiFlag > fmiWarning) {
    558                 jmi_log_comment(jmi->log, logError, "setMatrixElement failed to update matrix C");
    559                 fmi1_me -> fmi_functions.freeMemory(jac);
    560                 return fmiFlag;
    561             }
    562         }
    563     }
    564 
    565     /* Get the internal D matrix */
    566     fmiFlag = fmi1_me_get_jacobian(c, FMI_INPUTS, FMI_OUTPUTS, jac, nD);
    567     if (fmiFlag > fmiWarning) {
    568         jmi_log_comment(jmi->log, logError, "Evaluating the D matrix failed.");
    569         fmi1_me -> fmi_functions.freeMemory(jac);
    570         return fmiFlag;
    571     }
    572     /* Update external D matrix */
    573     for (row=0;row<ny;row++) {
    574         for (col=0;col<nu;col++) {
    575             d0 = clock();
    576             fmiFlag = setMatrixElement(D,row + 1, col + 1,jac[row + col*ny]);
    577             d1 = clock();
    578             setElementTime += ((fmiReal) ((long)(d1-d0))/(CLOCKS_PER_SEC));
    579             if (fmiFlag > fmiWarning) {
    580                 jmi_log_comment(jmi->log, logError, "setMatrixElement failed to update matrix D");
    581                 fmi1_me -> fmi_functions.freeMemory(jac);
    582                 return fmiFlag;
    583             }
    584         }
    585     }
    586 
    587     fmi1_me -> fmi_functions.freeMemory(jac);
    588 
    589     /* c1 = clock(); */
    590     /*printf("Jac eval call: %f\n", ((fmiReal) ((long)(c1-c0))/(CLOCKS_PER_SEC)));*/
    591     /*printf(" - setMatrixElementTime: %f\n", setElementTime);*/
    592     return fmiOK;
    593 }
    594 
    595 /*Evaluates the A, B, C and D matrices using finite differences, this functions has
    596 only been used for debugging purposes*/
    597 fmiStatus fmi1_me_get_jacobian_fd(fmiComponent c, int independents, int dependents, fmiReal jac[], size_t njac){
    598     int i;
    599     int j;
    600     int k;
    601     int offs;
    602     fmiReal h = 0.000001;
    603     size_t nvvr = 0;
    604     size_t nzvr = 0;
    605     fmiReal* z1;
    606     fmiReal* z2;
    607    
    608     int n_outputs;
    609     int* output_vrefs;
    610     int n_outputs2;
    611     int* output_vrefs2;
    612    
    613     fmi1_me_t* self = (fmi1_me_t*)c;
    614     jmi_t* jmi = &self->jmi;
    615    
    616     n_outputs = jmi->n_outputs;
    617     n_outputs2 = n_outputs;
    618    
    619     output_vrefs = (int*)calloc(n_outputs, sizeof(int));
    620     output_vrefs2 = (int*)calloc(n_outputs, sizeof(int));
    621    
    622     jmi_get_output_vrefs(jmi, output_vrefs);
    623     j = 0;
    624     for(i = 0; i < n_outputs; i++){
    625         if(get_type_from_value_ref(output_vrefs[i]) == 0){
    626             output_vrefs2[j] = output_vrefs[i];
    627             j++;       
    628         }else{
    629             n_outputs2--;
    630         }
    631     }
    632    
    633     offs = jmi->offs_real_x;
    634     if(independents&FMI_STATES){
    635         nvvr += jmi->n_real_x;
    636     }else{
    637         offs = jmi->offs_real_u;
    638     }
    639     if(independents&FMI_INPUTS){
    640         nvvr += jmi->n_real_u;
    641     }
    642     if(dependents&FMI_DERIVATIVES){
    643         nzvr += jmi->n_real_dx;
    644     }
    645     if(dependents&FMI_OUTPUTS){
    646         nzvr += n_outputs2;
    647     }
    648    
    649     z1 = (fmiReal*)calloc(nzvr, sizeof(fmiReal));
    650     z2 = (fmiReal*)calloc(nzvr, sizeof(fmiReal));
    651    
    652     for(i = 0; (size_t)i < nvvr; i++){
    653         k = 0;
    654         if((*(jmi->z))[offs+i] != 0){
    655             h = (*(jmi->z))[offs+i]*0.000000015;
    656         }else{
    657             h = 0.000001;
    658         }
    659         (*(jmi->z))[offs+i] += h;
    660         jmi->block_level = 0; /* to recover from errors */       
    661         jmi_generic_func(jmi, jmi->dae->ode_derivatives);
    662         if(dependents&FMI_DERIVATIVES){
    663             for(j = 0; j < jmi->n_real_dx; j++){
    664                 z1[k] = (*(jmi->z))[jmi->offs_real_dx+j];
    665                 k++;
    666             }
    667         }
    668        
    669         if(dependents&FMI_OUTPUTS){
    670             for(j = 0; j < n_outputs2; j++){
    671                 z1[k] = (*(jmi->z))[get_index_from_value_ref(output_vrefs2[j])];
    672                 k++;
    673             }
    674         }
    675        
    676         (*(jmi->z))[offs+i] -= 2*h;
    677         jmi->block_level = 0; /* to recover from errors */
    678        
    679         jmi_generic_func(jmi, jmi->dae->ode_derivatives);
    680         k = 0;
    681         if(dependents&FMI_DERIVATIVES){
    682             for(j = 0; j < jmi->n_real_dx; j++){
    683                 z2[k] = (*(jmi->z))[jmi->offs_real_dx+j];
    684                 k++;
    685             }
    686         }
    687         if(dependents&FMI_OUTPUTS){
    688             for(j = 0; j < n_outputs2; j++){
    689                 z2[k] = (*(jmi->z))[get_index_from_value_ref(output_vrefs2[j])];
    690                 k++;
    691             }
    692         }
    693         (*(jmi->z))[offs+i] += h;
    694        
    695         for(j = 0; (size_t)j < nzvr;j++){
    696             jac[i*nzvr+j] = (z1[j] - z2[j])/(2*h);
    697         }
    698        
    699     }
    700    
    701     free(output_vrefs);
    702     free(output_vrefs2);
    703     free(z1);
    704     free(z2);
    705    
    706     return fmiOK;
    707 }
    708 
    709 /*Evaluates the A, B, C and D matrices*/
    710 fmiStatus fmi1_me_get_jacobian(fmiComponent c, int independents, int dependents, fmiReal jac[], size_t njac) {
    711    
    712     int i;
    713     int j;
    714     int k;
    715     int index;
    716     int output_off = 0;
    717    
    718     /*
    719     int passed = 0;
    720     int failed = 0;
    721     */
    722    
    723 /**    fmiReal rel_tol;
    724     fmiReal abs_tol; */
    725    
    726     int offs;
    727     jmi_real_t** dv;
    728     jmi_real_t** dz;
    729 
    730 
    731     /*Used for debugging
    732     fmiReal tol = 0.001;   
    733     fmiReal* jac2;*/
    734    
    735     size_t nvvr = 0;
    736     size_t nzvr = 0;
    737    
    738     int n_outputs;
    739     int* output_vrefs;
    740     int n_outputs_real;
    741     int* output_vrefs_real;
    742     fmi1_me_t* self = (fmi1_me_t*)c;
    743     jmi_t* jmi = &self->jmi;
    744     /* clock_t c0, c1; */
    745 
    746     /* c0 = clock(); */
    747     n_outputs = jmi->n_outputs;
    748     n_outputs_real = n_outputs;
    749    
    750     /*dv and the dz are stored in the same vector*/
    751     dv = jmi->dz;
    752     dz = jmi->dz;
    753    
    754     /* Used for debbugging
    755     jac2 = (fmiReal*)calloc(njac, sizeof(fmiReal));
    756     */
    757    
    758     offs = jmi->n_real_dx;
    759    
    760     for(i = 0; i<jmi->n_real_dx+jmi->n_real_x+jmi->n_real_u+jmi->n_real_w;i++){
    761         (*dz)[i] = 0;
    762     }
    763 
    764     if ((dependents==FMI_DERIVATIVES) && (independents==FMI_STATES) && jmi->color_info_A != NULL) {
    765         /* Compute Jacobian A with compression */
    766         for (i=0;i<jmi->color_info_A->n_groups;i++) {
    767             for(k = 0; k<jmi->n_real_dx+jmi->n_real_x+jmi->n_real_u+jmi->n_real_w;k++){
    768                 (*dz)[k] = 0;
    769             }
    770             /* Set the seed vector */
    771             for (j=0;j<jmi->color_info_A->n_cols_in_group[i];j++) {
    772                 (*dv)[jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j] + jmi->n_real_dx] = 1.;
    773             }
    774             /*
    775             for (j=0;j<jmi->n_v;j++) {
    776                 printf(" * %d %f\n",j,(*(jmi->dz))[j]);
    777             }
    778             */
    779             /* Evaluate directional derivative */
    780             if (i==0) {
    781                 jmi->cached_block_jacobians = 0;
    782             } else {
    783                 jmi->cached_block_jacobians = 1;
    784             }
    785             jmi->block_level = 0; /* to recover from errors */
    786            
    787             jmi_generic_func(jmi, jmi->dae->ode_derivatives_dir_der);
    788             /* Extract Jacobian values */
    789             for (j=0;j<jmi->color_info_A->n_cols_in_group[i];j++) {
    790                 for (k=jmi->color_info_A->col_start_index[jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j]];
    791                      k<jmi->color_info_A->col_start_index[jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j]]+
    792                        jmi->color_info_A->col_n_nz[jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j]];
    793                         k++) {
    794                     jac[(jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j])*(jmi->n_real_x) +
    795                         jmi->color_info_A->rows[k]] = (*dz)[jmi->color_info_A->rows[k]];
    796                 }
    797             }
    798             /* Reset seed vector */
    799             for (j=0;j<jmi->color_info_A->n_cols_in_group[i];j++) {
    800                 (*dv)[jmi->color_info_A->group_cols[jmi->color_info_A->group_start_index[i] + j] + jmi->n_real_dx] = 0.;
    801             }
    802         }
    803         /* c1 = clock(); */
    804 
    805         /*printf("Jac A eval call: %f\n", ((fmiReal) ((long)(c1-c0))/(CLOCKS_PER_SEC)));*/
    806 
    807     } else {
    808 
    809         output_vrefs = (int*)calloc(n_outputs, sizeof(int));
    810         output_vrefs_real = (int*)calloc(n_outputs, sizeof(int));
    811 
    812         jmi_get_output_vrefs(jmi, output_vrefs);
    813         j = 0;
    814         for(i = 0; i < n_outputs; i++){
    815             if(get_type_from_value_ref(output_vrefs[i]) == 0){
    816                 output_vrefs_real[j] = output_vrefs[i];
    817                 j++;
    818             }else{
    819                 n_outputs_real--;
    820             }
    821         }
    822 
    823         /*nvvr: number of x and/or u variables used
    824       nzvr: number of dx and/or w variables used*/
    825 
    826         if(independents&FMI_STATES){
    827             nvvr += jmi->n_real_x;
    828         }else{
    829             offs += jmi->n_real_x;
    830         }
    831         if(independents&FMI_INPUTS){
    832             nvvr += jmi->n_real_u;
    833         }
    834         if(dependents&FMI_DERIVATIVES){
    835             nzvr += jmi->n_real_dx;
    836             output_off = jmi->n_real_dx;
    837         }
    838         if(dependents&FMI_OUTPUTS){
    839             nzvr += n_outputs_real;
    840         }
    841 
    842         /*For every x and/or u variable...*/
    843         for(i = 0; (size_t)i < nvvr; i++){
    844             (*dv)[i+offs] = 1;
    845             jmi->block_level = 0; /* to recover from errors */
    846 
    847             /*Evaluate directional derivative*/
    848             jmi_generic_func(jmi, jmi->dae->ode_derivatives_dir_der);
    849 
    850             /*Jacobian elements ddx/dx and/or ddx/du*/
    851             if(dependents&FMI_DERIVATIVES){
    852                 for(j = 0; j<jmi->n_real_dx;j++){
    853                     jac[i*nzvr+j] = (*dz)[j];
    854                 }
    855             }
    856 
    857             /*Jacobian elements dy/dx and/or dy/du*/
    858             if(dependents&FMI_OUTPUTS){
    859                 for(j = 0; j<n_outputs_real;j++){
    860                     index = get_index_from_value_ref(output_vrefs_real[j]);
    861                     if(index < jmi->n_real_x + jmi->n_real_u){
    862                         if(index == i + offs){
    863                             jac[i*nzvr+output_off+j] = 1;
    864                         } else{
    865                             jac[i*nzvr+output_off+j] = 0;
    866                         }
    867                     } else{
    868                         jac[i*nzvr+j+output_off] = (*dz)[index-jmi->offs_real_dx];
    869                     }
    870                 }
    871             }
    872             /*reset dz vector*/
    873             for(j = 0; j<jmi->n_real_dx+jmi->n_real_x+jmi->n_real_u+jmi->n_real_w;j++){
    874                 (*dz)[j] = 0;
    875             }
    876 
    877         }
    878 
    879         free(output_vrefs);
    880         free(output_vrefs_real);
    881 
    882     }
    883     /*
    884     ---This section has been used for debugging---
    885     fmi_get_jacobian_fd(c, independents, dependents, jac2, njac);
    886    
    887     for(j = 0; j < nvvr; j++){
    888         for(k = 0; k < nzvr; k++){
    889             i = j*nzvr + k;
    890             if(jac[i] != 0 && jac2[i] != 0){
    891                 rel_tol = 1.0 - jac2[i]/jac[i];
    892                 if((rel_tol < tol) && (rel_tol > -tol)){
    893                     passed++;
    894                 } else{
    895                     failed++;
    896                     printf("\ni: %d,j: %d, cad: %f, fd: %f, rel_tol: %f",k, j, jac[i], jac2[i], rel_tol);
    897                 }
    898             } else{
    899                 abs_tol = jac[i]-jac2[i];
    900                 if((abs_tol < tol) && (abs_tol > -tol)){
    901                     passed++;
    902                 } else{
    903                     failed++;
    904                     printf("\ni: %d, j: %d, cad: %f, fd: %f, abs_tol: %f",k, j, jac[i], jac2[i], abs_tol);
    905                 }
    906             }
    907         }
    908     }
    909     printf("\nPASSED: %d\tFAILED: %d\n\n", passed, failed);
    910 
    911     free(jac2);
    912     */
    913    
    914     /*
    915     c1 = clock();
    916     */
    917    
    918     /*printf("Jac eval call: %f\n", ((fmiReal) ((long)(c1-c0))/(CLOCKS_PER_SEC)));*/
    919     return fmiOK;
    920 }
    921 
    922 /*Evaluate the directional derivative dz/dv dv*/
    923 fmiStatus fmi1_me_get_directional_derivative(fmiComponent c, const fmiValueReference z_vref[], size_t nzvr, const fmiValueReference v_vref[], size_t nvvr, fmiReal dz[], const fmiReal dv[]) {
    924     fmiInteger retval;
    925     fmi1_me_t* self = (fmi1_me_t*)c;
    926     jmi_t* jmi = &self->jmi;
    927    
    928     if (c == NULL) {
    929         return fmiFatal;
    930     }
    931    
    932     retval = jmi_get_directional_derivative(jmi,
    933                                             z_vref, nzvr, v_vref, nvvr,
    934                                             dv, dz);
    935400    if (retval != 0) {
    936401        return fmiError;
  • trunk/RuntimeLibrary/src/fmi2/fmi2_me.c

    r8979 r8993  
    388388    /* Negate the values of the retrieved "negate alias" variables. */
    389389    for (i = 0; i < nvr; i++) {
    390         if (is_negated(vr[i])) {
     390        if (jmi_value_ref_is_negated(vr[i])) {
    391391            value[i] = -value[i];
    392392        }
     
    412412    /* Negate the values of the retrieved "negate alias" variables. */
    413413    for (i = 0; i < nvr; i++) {
    414         if (is_negated(vr[i])) {
     414        if (jmi_value_ref_is_negated(vr[i])) {
    415415            value[i] = -value[i];
    416416        }
     
    471471    for (i = 0; i < nvr; i++) {
    472472        /* Negate the values before setting the "negate alias" variables. */
    473         if (is_negated(vr[i])) {
     473        if (jmi_value_ref_is_negated(vr[i])) {
    474474            fmi2_me->work_real_array[i] = -value[i];
    475475        } else {
     
    504504    /* Negate the values before setting the "negate alias" variables. */
    505505    for (i = 0; i < nvr; i++) {
    506         if (is_negated(vr[i])) {
     506        if (jmi_value_ref_is_negated(vr[i])) {
    507507            fmi2_me->work_int_array[i] = -value[i];
    508508        } else {
  • trunk/RuntimeLibrary/src/jmi/jmi.c

    r8736 r8993  
    3838void jmi_z_delete(jmi_z_t* z) {
    3939    free(z->strings.values);
     40}
     41
     42void jmi_model_init(jmi_t* jmi,
     43                    jmi_generic_func_t model_ode_derivatives_dir_der,
     44                    jmi_generic_func_t model_ode_derivatives,
     45                    jmi_residual_func_t model_ode_event_indicators,
     46                    jmi_generic_func_t model_ode_initialize,
     47                    jmi_generic_func_t model_init_eval_parameters,
     48                    jmi_next_time_event_func_t model_ode_next_time_event) {
     49   
     50    /* Create jmi_model_t struct */
     51    jmi_model_t* model = (jmi_model_t*)calloc(1, sizeof(jmi_model_t));
     52    jmi->model = model;
     53   
     54    jmi->model->ode_derivatives = model_ode_derivatives;
     55    jmi->model->ode_derivatives_dir_der = model_ode_derivatives_dir_der;
     56    jmi->model->ode_initialize = model_ode_initialize;
     57    jmi->model->ode_next_time_event = model_ode_next_time_event;
     58    jmi->model->ode_event_indicators = model_ode_event_indicators;
     59    jmi->model->init_eval_parameters = model_init_eval_parameters;
     60}
     61
     62void jmi_model_delete(jmi_t* jmi) {
     63    if (jmi->model) {
     64        free(jmi->model);
     65    }
    4066}
    4167
     
    5076        int n_real_d, int n_integer_d, int n_integer_u,
    5177        int n_boolean_d, int n_boolean_u,
    52         int n_outputs, int* output_vrefs,
    5378        int n_sw, int n_sw_init, int n_time_sw, int n_state_sw,
    5479        int n_guards, int n_guards_init,
     
    6489    /* Create jmi struct */   
    6590    jmi_ = *jmi;
    66     /* Set struct pointers in jmi */
    67     jmi_->dae = NULL;
    68     jmi_->init = NULL;
    69     /* jmi_->user_func = NULL; */
    70 
     91   
    7192    /* Set sizes of dae vectors */
    7293    jmi_->n_real_ci = n_real_ci;
     
    97118    jmi_->n_boolean_d = n_boolean_d;
    98119    jmi_->n_boolean_u = n_boolean_u;
    99 
    100     jmi_->n_outputs = n_outputs;
    101     jmi_->output_vrefs = (int*)calloc(n_outputs,sizeof(int));
    102     for (i=0;i<n_outputs;i++) {
    103         jmi_->output_vrefs[i] = output_vrefs[i];
    104     }
    105120
    106121    jmi_->n_sw = n_sw;
     
    207222
    208223    jmi_->variable_scaling_factors = (jmi_real_t*)calloc(jmi_->n_z,sizeof(jmi_real_t));
    209     jmi_->scaling_method = JMI_SCALING_NONE;
     224    jmi_->scaling_method = scaling_method;
    210225
    211226    for (i=0;i<jmi_->n_z;i++) {
     
    233248    jmi_->real_u_work = (jmi_real_t*)calloc(jmi_->n_real_u,sizeof(jmi_real_t));
    234249   
    235     jmi_->scaling_method = scaling_method;
    236250
    237251    jmi_->n_initial_relations = n_initial_relations;
     
    285299
    286300    return 0;
    287 
    288301}
    289302
     
    292305
    293306    jmi_me_delete_modules(jmi);
    294 
    295307    jmi_z_delete(&jmi->z_t);
    296 
    297     if (jmi->dae != NULL) {
    298         jmi_func_delete(jmi->dae->F);
    299         jmi_func_delete(jmi->dae->R);
    300         jmi_delete_simple_color_info(&jmi->color_info_A);
    301         jmi_delete_simple_color_info(&jmi->color_info_B);
    302         jmi_delete_simple_color_info(&jmi->color_info_C);
    303         jmi_delete_simple_color_info(&jmi->color_info_D);
    304         free(jmi->dae);
    305         jmi->dae = 0;
    306     }
    307 
    308     jmi_delete_init(&(jmi->init));
    309 
    310     for (i=0; i < jmi->n_dae_init_blocks;i=i+1){ /*Deallocate init BLT blocks.*/
     308    jmi_model_delete(jmi);
     309
     310    /* Deallocate init BLT blocks */
     311    for (i = 0; i < jmi->n_dae_init_blocks; i++) {
    311312        jmi_delete_block_residual(jmi->dae_init_block_residuals[i]);
    312313    }
    313         free(jmi->dae_init_block_residuals);
    314     for (i=0; i < jmi->n_dae_blocks;i=i+1){ /*Deallocate BLT blocks.*/
     314    free(jmi->dae_init_block_residuals);
     315   
     316    /* Deallocate BLT blocks */
     317    for (i = 0; i < jmi->n_dae_blocks; i++) {
    315318        jmi_delete_block_residual(jmi->dae_block_residuals[i]);
    316319    }
    317         free(jmi->dae_block_residuals);
     320    free(jmi->dae_block_residuals);
    318321   
    319322    for (i=0; i < jmi->n_dynamic_state_sets; i++) {
     
    324327    jmi_chattering_delete(jmi->chattering);
    325328
    326     free(jmi->output_vrefs);
    327329    free(*(jmi->z));
    328330    free(jmi->z);
     
    410412}
    411413
    412 int jmi_func_F(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res) {
     414int jmi_generic_func(jmi_t *jmi, jmi_generic_func_t func) {
    413415    int return_status;
    414416    int depth = jmi_prepare_try(jmi);
    415 
    416     if (jmi_try(jmi, depth)) {
     417    if (jmi_try(jmi, depth))
    417418        return_status = -1;
    418     }
    419     else {
    420         return_status = func->F(jmi, &res);
    421     }
    422 
    423     jmi_finalize_try(jmi, depth);
    424 
    425     return return_status;
    426 }
    427 
    428 int jmi_func_cad_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    429              jmi_real_t *dF, jmi_real_t* dv) {
    430     int return_status;
    431     int depth = jmi_prepare_try(jmi);
    432     if (jmi_try(jmi, depth)) {
    433         return_status = -1;
    434     }
    435     else {
    436         return_status = func->cad_dir_dF(jmi, &res, &dF, &dv);
    437     }
     419    else
     420        return_status = func(jmi);
    438421    jmi_finalize_try(jmi, depth);
    439422    return return_status;
    440 }
    441 
    442 int jmi_ode_f(jmi_t* jmi) {
    443     int i;
    444     jmi_real_t* dx;
    445     jmi_real_t* dx_res;
    446    
    447     if (jmi->n_real_w != 0) { /* Check if not ODE */
    448         return -1;
    449     }
    450 
    451     dx = jmi_get_real_dx(jmi);
    452     for(i=0;i<jmi->n_real_dx;i++) {
    453         dx[i]=0;
    454     }
    455 
    456     dx_res = calloc(jmi->n_real_x,sizeof(jmi_real_t));
    457 
    458     /*jmi->dae->F->F(jmi, &res);*/
    459     jmi_func_F(jmi,jmi->dae->F,dx_res);
    460 
    461     for(i=0;i<jmi->n_real_dx;i++) {
    462         dx[i]=dx_res[i];
    463     }
    464 
    465     free(dx_res);
    466 
    467     return 0;
    468 }
    469 
    470 int jmi_ode_df(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac) {
    471 
    472     if (jmi->n_real_w != 0) { /* Check if not ODE */
    473         return -1;
    474     }
    475 
    476     if (eval_alg & JMI_DER_SYMBOLIC) {
    477 
    478         int i;
    479         jmi_real_t* dx = jmi_get_real_dx(jmi);
    480         for(i=0;i<jmi->n_real_dx;i++) {
    481             dx[i]=0;
    482         }
    483 
    484         return jmi_func_sym_dF(jmi, jmi->dae->F, sparsity,
    485                 independent_vars & ~JMI_DER_DX, mask, jac) ;
    486     } else {
    487         return -1;
    488     }
    489 }
    490 
    491 int jmi_ode_df_n_nz(jmi_t* jmi, int eval_alg, int* n_nz) {
    492 
    493     int ret_val;
    494 
    495     if (jmi->n_real_w != 0) { /* Check if not ODE */
    496         return -1;
    497     }
    498 
    499     if (eval_alg & JMI_DER_SYMBOLIC) {
    500         int df_n_cols;
    501         int* mask = calloc(jmi->n_z,sizeof(int));
    502         int i;
    503         for (i=0;i<jmi->n_z;i++) {
    504             mask[i] = 1;
    505         }
    506         ret_val =  jmi_func_sym_dF_dim(jmi, jmi->dae->F, JMI_DER_SPARSE,
    507                JMI_DER_ALL & (~JMI_DER_DX), mask,
    508                 &df_n_cols, n_nz);
    509         free(mask);
    510         return ret_val;
    511     } else {
    512         return -1;
    513     }
    514 }
    515 
    516 int jmi_ode_df_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    517         int *mask, int* row, int* col) {
    518 
    519     if (jmi->n_real_w != 0) { /* Check if not ODE */
    520         return -1;
    521     }
    522 
    523     if (eval_alg & JMI_DER_SYMBOLIC) {
    524 
    525         return jmi_func_sym_dF_nz_indices(jmi, jmi->dae->F, independent_vars & (~JMI_DER_DX),
    526                 mask, row, col);
    527     } else {
    528         return -1;
    529     }
    530 
    531 }
    532 
    533 int jmi_ode_df_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    534         int *df_n_cols, int *df_n_nz) {
    535 
    536     if (jmi->n_real_w != 0) { /* Check if not ODE */
    537         return -1;
    538     }
    539 
    540     if (eval_alg & JMI_DER_SYMBOLIC) {
    541         return jmi_func_sym_dF_dim(jmi, jmi->dae->F, sparsity, independent_vars & (~JMI_DER_DX), mask,
    542                 df_n_cols, df_n_nz);
    543     } else {
    544         return -1;
    545     }
    546423}
    547424
     
    560437
    561438    jmi->block_level = 0; /* to recover from errors */
    562     return_status = jmi_generic_func(jmi, jmi->dae->ode_derivatives);
     439    return_status = jmi_generic_func(jmi, jmi->model->ode_derivatives);
    563440
    564441    if ((jmi->jmi_callbacks.log_options.log_level >= 5)) {
     
    571448}
    572449
    573 int jmi_ode_derivatives_dir_der(jmi_t* jmi, jmi_real_t *dv) {
     450int jmi_ode_derivatives_dir_der(jmi_t* jmi) {
    574451
    575452    int return_status;
    576453    jmi->block_level = 0; /* to recover from errors */
    577454   
    578     return_status = jmi_generic_func(jmi, jmi->dae->ode_derivatives_dir_der);
     455    return_status = jmi_generic_func(jmi, jmi->model->ode_derivatives_dir_der);
    579456
    580457    return return_status;
    581458}
    582459
    583 int jmi_ode_outputs(jmi_t* jmi) {
    584 
    585     int return_status;
    586    
    587     return_status = jmi_generic_func(jmi, jmi->dae->ode_outputs);
    588 
    589     return return_status;
    590 }
    591460
    592461int jmi_ode_initialize(jmi_t* jmi) {
     
    601470    }
    602471
    603     return_status = jmi_generic_func(jmi, jmi->dae->ode_initialize);
     472    return_status = jmi_generic_func(jmi, jmi->model->ode_initialize);
    604473
    605474    if ((jmi->jmi_callbacks.log_options.log_level >= 5)) {
     
    609478    return return_status;
    610479}
    611 
    612 int jmi_ode_guards(jmi_t* jmi) {
    613 
    614     int return_status;
    615 
    616     return_status = jmi_generic_func(jmi, jmi->dae->ode_guards);
    617    
    618     return return_status;
    619 }
    620 
    621 int jmi_ode_guards_init(jmi_t* jmi) {
    622 
    623     int return_status;
    624 
    625     return_status = jmi_generic_func(jmi, jmi->dae->ode_guards_init);
    626 
    627     return return_status;
    628 }
    629 
    630480int jmi_ode_next_time_event(jmi_t* jmi, jmi_time_event_t* event) {
    631481
     
    635485    if (jmi_try(jmi, depth)) {
    636486        return_status = -1;
    637     }
    638     else {
    639         return_status = jmi->dae->ode_next_time_event(jmi, event);
     487    } else {
     488        return_status = jmi->model->ode_next_time_event(jmi, event);
    640489    }
    641490    jmi_finalize_try(jmi, depth);
     
    643492}
    644493
    645 int jmi_dae_F(jmi_t* jmi, jmi_real_t* res) {
    646 
    647     /*jmi->dae->F->F(jmi, &res);*/
    648     jmi_func_F(jmi,jmi->dae->F,res);
    649 
    650     return 0;
    651 }
    652 
    653 int jmi_dae_dF(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac) {
    654     if (eval_alg & JMI_DER_SYMBOLIC) {
    655         return jmi_func_sym_dF(jmi, jmi->dae->F, sparsity,
    656                 independent_vars, mask, jac) ;
    657     } else if (eval_alg & JMI_DER_CAD) {
    658         return  jmi_func_cad_dF(jmi, jmi->dae->F, sparsity,
    659                 independent_vars, mask, jac);
    660     } else if (eval_alg & JMI_DER_FD) {
    661         return jmi_func_fd_dF(jmi, jmi->dae->F, sparsity,
    662                 independent_vars, mask, jac);
    663     } else {
    664         return -1;
    665     }
    666 }
    667 
    668 int jmi_dae_dF_n_nz(jmi_t* jmi, int eval_alg, int* n_nz) {
    669     if (eval_alg & JMI_DER_SYMBOLIC) {
    670         return jmi_func_sym_dF_n_nz(jmi, jmi->dae->F, n_nz);
    671     } else if (eval_alg & JMI_DER_CAD) {
    672         return jmi_func_cad_dF_n_nz(jmi, jmi->dae->F, n_nz);
    673     } else if (eval_alg & JMI_DER_FD) {
    674         return jmi_func_fd_dF_n_nz(jmi, jmi->dae->F, n_nz);
    675     } else {
    676         return -1;
    677     }
    678 }
    679 
    680 int jmi_dae_dF_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    681         int *mask, int* row, int* col) {
    682 
    683     if (eval_alg & JMI_DER_SYMBOLIC) {
    684         return jmi_func_sym_dF_nz_indices(jmi, jmi->dae->F, independent_vars, mask, row, col);
    685     } else if (eval_alg & JMI_DER_CAD) {
    686         return jmi_func_cad_dF_nz_indices(jmi, jmi->dae->F, independent_vars, mask, row, col);
    687     } else if (eval_alg & JMI_DER_FD) {
    688         return jmi_func_fd_dF_nz_indices(jmi, jmi->dae->F, independent_vars, mask, row, col);
    689     } else {
    690         return -1;
    691     }
    692 
    693 }
    694 
    695 int jmi_dae_dF_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    696         int *dF_n_cols, int *dF_n_nz) {
    697 
    698     if (eval_alg & JMI_DER_SYMBOLIC) {
    699         return jmi_func_sym_dF_dim(jmi, jmi->dae->F, sparsity, independent_vars, mask,
    700                 dF_n_cols, dF_n_nz);
    701     } else if (eval_alg & JMI_DER_CAD) {
    702         return jmi_func_cad_dF_dim(jmi, jmi->dae->F, sparsity, independent_vars, mask,
    703                 dF_n_cols, dF_n_nz);
    704     } else if (eval_alg & JMI_DER_FD) {
    705         return jmi_func_fd_dF_dim(jmi, jmi->dae->F, sparsity, independent_vars, mask,
    706                 dF_n_cols, dF_n_nz);
    707     } else {
    708         return -1;
    709     }
    710 
    711 }
    712 
    713 int jmi_dae_directional_dF(jmi_t* jmi, int eval_alg, jmi_real_t* res, jmi_real_t* dF, jmi_real_t* dz) {
    714    
    715     if (eval_alg & JMI_DER_SYMBOLIC) {
    716         return jmi_func_sym_directional_dF(jmi, jmi->dae->F, res, dF, dz);
    717     } else if (eval_alg & JMI_DER_CAD) {
    718         return jmi_func_cad_directional_dF(jmi, jmi->dae->F, res, dF, dz);
    719     } else if (eval_alg & JMI_DER_FD) {
    720         return jmi_func_fd_directional_dF(jmi, jmi->dae->F, res, dF, dz);
    721     } else{
    722         return -1;
    723     }
    724 }
    725 
    726494int jmi_dae_R(jmi_t* jmi, jmi_real_t* res) {
    727 
    728     /*jmi->dae->F->F(jmi, &res);*/
    729     jmi_func_F(jmi,jmi->dae->R,res);
    730 
    731     return 0;
     495    int return_status;
     496    int depth = jmi_prepare_try(jmi);
     497
     498    if (jmi_try(jmi, depth)) {
     499        return_status = -1;
     500    }
     501    else {
     502        return_status = jmi->model->ode_event_indicators(jmi, &res);
     503    }
     504
     505    jmi_finalize_try(jmi, depth);
     506
     507    return return_status;
    732508}
    733509
     
    763539}
    764540
    765 int jmi_init_F0(jmi_t* jmi, jmi_real_t* res) {
    766    
    767     return jmi_func_F(jmi,jmi->init->F0,res);
    768 }
    769 
    770 int jmi_init_dF0(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac) {
    771     if (eval_alg & JMI_DER_SYMBOLIC) {
    772         return jmi_func_sym_dF(jmi, jmi->init->F0, sparsity,
    773                 independent_vars, mask, jac) ;
    774     } else {
    775         return -1;
    776     }
    777 }
    778 
    779 int jmi_init_dF0_n_nz(jmi_t* jmi, int eval_alg, int* n_nz) {
    780 
    781     if (eval_alg & JMI_DER_SYMBOLIC) {
    782         return jmi_func_sym_dF_n_nz(jmi, jmi->init->F0, n_nz);
    783     } else {
    784         return -1;
    785     }
    786 }
    787 
    788 int jmi_init_dF0_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    789         int *mask, int* row, int* col) {
    790 
    791     if (eval_alg & JMI_DER_SYMBOLIC) {
    792         return jmi_func_sym_dF_nz_indices(jmi, jmi->init->F0, independent_vars, mask, row, col);
    793     } else {
    794         return -1;
    795     }
    796 
    797 }
    798 
    799 int jmi_init_dF0_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    800         int *dF_n_cols, int *dF_n_nz) {
    801 
    802     if (eval_alg & JMI_DER_SYMBOLIC) {
    803         return jmi_func_sym_dF_dim(jmi, jmi->init->F0, sparsity, independent_vars, mask,
    804                 dF_n_cols, dF_n_nz);
    805     } else {
    806         return -1;
    807     }
    808 
    809 }
    810 
    811 
    812 int jmi_init_F1(jmi_t* jmi, jmi_real_t* res) {
    813 
    814     return jmi_func_F(jmi,jmi->init->F1,res);
    815 
    816 }
    817 
    818 int jmi_init_dF1(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac) {
    819     if (eval_alg & JMI_DER_SYMBOLIC) {
    820         return jmi_func_sym_dF(jmi, jmi->init->F1, sparsity,
    821                 independent_vars, mask, jac) ;
    822     } else {
    823         return -1;
    824     }
    825 }
    826 
    827 int jmi_init_dF1_n_nz(jmi_t* jmi, int eval_alg, int* n_nz) {
    828 
    829     if (eval_alg & JMI_DER_SYMBOLIC) {
    830         return jmi_func_sym_dF_n_nz(jmi, jmi->init->F1, n_nz);
    831     } else {
    832         return -1;
    833     }
    834 }
    835 
    836 int jmi_init_dF1_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    837         int *mask, int* row, int* col) {
    838 
    839     if (eval_alg & JMI_DER_SYMBOLIC) {
    840         return jmi_func_sym_dF_nz_indices(jmi, jmi->init->F1, independent_vars, mask, row, col);
    841     } else {
    842         return -1;
    843     }
    844 
    845 }
    846 
    847 int jmi_init_dF1_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    848         int *dF_n_cols, int *dF_n_nz) {
    849 
    850     if (eval_alg & JMI_DER_SYMBOLIC) {
    851         return jmi_func_sym_dF_dim(jmi, jmi->init->F1, sparsity, independent_vars, mask,
    852                 dF_n_cols, dF_n_nz);
    853     } else {
    854         return -1;
    855     }
    856 }
    857 
    858 int jmi_init_Fp(jmi_t* jmi, jmi_real_t* res) {
    859 
    860     return jmi_func_F(jmi,jmi->init->Fp,res);
    861 
    862 }
    863 
    864 int jmi_init_dFp(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac) {
    865     if (eval_alg & JMI_DER_SYMBOLIC) {
    866         return jmi_func_sym_dF(jmi, jmi->init->Fp, sparsity,
    867                 independent_vars, mask, jac) ;
    868     } else {
    869         return -1;
    870     }
    871 }
    872 
    873 int jmi_init_dFp_n_nz(jmi_t* jmi, int eval_alg, int* n_nz) {
    874 
    875     if (eval_alg & JMI_DER_SYMBOLIC) {
    876         return jmi_func_sym_dF_n_nz(jmi, jmi->init->Fp, n_nz);
    877     } else {
    878         return -1;
    879     }
    880 }
    881 
    882 int jmi_init_dFp_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    883         int *mask, int* row, int* col) {
    884 
    885     if (eval_alg & JMI_DER_SYMBOLIC) {
    886         return jmi_func_sym_dF_nz_indices(jmi, jmi->init->Fp, independent_vars, mask, row, col);
    887     } else {
    888         return -1;
    889     }
    890 
    891 }
    892 
    893 int jmi_init_dFp_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    894         int *dF_n_cols, int *dF_n_nz) {
    895 
    896     if (eval_alg & JMI_DER_SYMBOLIC) {
    897 
    898         return jmi_func_sym_dF_dim(jmi, jmi->init->Fp, sparsity, independent_vars, mask,
    899                 dF_n_cols, dF_n_nz);
    900     } else {
    901         return -1;
    902     }
    903 }
    904 
    905541int jmi_init_eval_parameters(jmi_t* jmi) {
    906 
    907     int return_status;
    908 
    909     return_status = jmi_generic_func(jmi, jmi->init->eval_parameters);
    910 
    911     return return_status;
    912 }
    913 
    914 int jmi_init_R0(jmi_t* jmi, jmi_real_t* res) {
    915 
    916     /*jmi->dae->F->F(jmi, &res);*/
    917     jmi_func_F(jmi,jmi->init->R0,res);
    918 
    919     return 0;
     542    return jmi_generic_func(jmi, jmi->model->init_eval_parameters);
    920543}
    921544
  • trunk/RuntimeLibrary/src/jmi/jmi.h

    r8679 r8993  
    2222 **/
    2323
    24 /** \mainpage The JModelica.org C runtime library
    25  *
    26  * The JModelica C runtime library contains functions and data structures for
    27  * accessing the C model representation that is generated by the JModelica
    28  * Modelica and Optimica front-ends, respectively. The library is organized into
    29  * two main parts.
    30  *
    31  *  \section fmi_model_interfance The Functional Mock-up interface
    32  *   The Functional Mock-up Interface (FMI) defines a standard for model exchange
    33  *   with a small set of functions for model interaction while at the same time
    34  *   provide the necessary means for simulation of complex hybrid dynamic models.
    35  *   - <a href="group__fmi__public.html"> Documentation of the public Functional
    36  *     Mock-up interface</a>
    37  *   - <a target="_parent" href="http://www.functional-mockup-interface.org/">
    38  *     The Functional Mock-up interface</a>
    39  *  \section jmi_model_interface The JMI Model interface
    40  *   The JMI Model interface interface contains functions
    41  *    for evaluating the function generated by the compiler, including the DAE residual, the
    42  *    residual functions for the DAE initialization problem, and the functions related to
    43  *    the optimization problem such as cost functions and constraint residual functions.
    44  *    The JMI Model interface also supports evaluation of symbolic Jacobians (if available)
    45  *    and/or Jacobians computed by means of automatic differentiation. Sparsity patterns for
    46  *    Jacobians are supported.
    47  *      - <a href="group__Jmi.html"> Documentation of the public JMI Model interface </a>
    48  *      - <a href="group__Jmi__internal.html"> Documentation of the internal JMI Model interface </a>
    49  *
    50  * \section limitations Limitations
    51  * The JModelica.org JMI interface is under development. The function signatures
    52  * are likely to change in the future - all feedback is very welcome. The following
    53  * limitations apply:
    54  *   - Symbolic Jacobians are not provided by the compiler. This is actually
    55  *   a limitation in the code generation module, but as a consequence, the
    56  *   JMI_DER_SYMBOLIC flag cannot be used in the JMI interface.
    57  *   - The ODE interface is very limited and requires a Modelica model to be
    58  *   stated on explicit ODE form (\f$\dot x=f(x,u)\f$) in order to work.
    59  *
    60  */
    61 
    62 /**
    63  * \defgroup Jmi The JMI Model interface
    64  *
    65  * \brief Documentation of the public JMI Model interface.
    66  *
    67  *  \section DesignConsiderations Design considerations
    68  *
    69  * The JMI Model interface is intended to be used in a wide range of
    70  * applications and on multiple platforms. This also includes embedded
    71  * platforms in HILS applications.
    72  *
    73  * It is desirable that the JMI Model interface can be easily interfaced
    74  * with Python. Python is the intended language for scripting in JModelica and it is
    75  * therefore important that the generated code is straight forward to use with the
    76  * Python extensions or ctypes framework.
    77  *
    78  * The JMI Model interface is intended to be used by wide range of users,
    79  * with different backgrounds and programming skills. It is therefore desirable that
    80  * the interface is as simple and intuitive as possible.
    81  *
    82  * Given these motivations, it is reasonable to use pure C where possible, and to a
    83  * limited extent C++ where needed (e.g. in solver interfaces and in most likely in the
    84  * AD framework).
    85  *
    86  * It should also be possible to build shared libraries, in order to
    87  * build applications that contains several models.
    88  *
    89  *
    90  * \section MathDescr Mathematical description of the JMI Model interface
    91  *
    92  *   The jmi interface consists of three parts: DAE, DAE initialization and optimization.
    93  *   Essentially, the jmi interface consists of a collection of functions that are
    94  *   offered to the user for evaluation of the DAE residual, cost functions, constraints
    95  *   etc. These functions takes as arguments one more of the following three argument
    96  *   types:
    97  *
    98  *   Parameters (denoted \f$p\f$):
    99  *    - \f$c_i^r\f$   independent real constant
    100  *    - \f$c_d^r\f$   dependent real constants
    101  *    - \f$p_i^r\f$   independent real parameters
    102  *    - \f$p_d^r\f$   dependent real parameters
    103  *    - \f$c_i^i\f$   independent integer constant
    104  *    - \f$c_d^i\f$   dependent integer constants
    105  *    - \f$p_i^i\f$   independent integer parameters
    106  *    - \f$p_d^i\f$   dependent integer parameters
    107  *    - \f$c_i^b\f$   independent boolean constant
    108  *    - \f$c_d^b\f$   dependent boolean constants
    109  *    - \f$p_i^b\f$   independent boolean parameters
    110  *    - \f$p_d^b\f$   dependent boolean parameters
    111  *
    112  *    with
    113  *
    114  *      \f$ p = [{c_i^r}^T, {c_d^r}^T, {p_i^r}^T, {p_d^r}^T, {c_i^i}^T, {c_d^i}^T, {p_i^i}^T, {p_d^i}^T, {c_i^b}^T, {c_d^b}^T, {p_i^b}^T, {p_d^b}^T]^T \f$
    115  *
    116  *   Variables (denoted \f$v\f$):
    117  *
    118  *    - \f$\dot x\f$    differentiated real variables
    119  *    - \f$x\f$     real variables that appear differentiated
    120  *    - \f$u\f$     real inputs
    121  *    - \f$w\f$     real algebraic variables
    122  *    - \f$t\f$     time
    123  *
    124  *    with
    125  *
    126  *    \f$v = [\dot x^T, x^T, u^T, w^T, t]^T\f$
    127  *
    128  *   Variables defined at particular time instants (denoted \f$q\f$):
    129  *
    130  *      - \f$\dot x(t_i)\f$    differentiated real variables evaluated at time \f$t_i, i \in 1..n_{tp}\f$
    131  *      - \f$x(t_i)\f$     real variables that appear differentiated evaluated at time \f$t_i, t_i \in 1..n_{tp}\f$
    132  *      - \f$u(t_i)\f$     real inputs evaluated at time \f$t_i, i \in 1..n_{tp}\f$
    133  *      - \f$w(t_i)\f$     real algebraic variables evaluated at time \f$t_i, i \in 1..n_{tp}\f$
    134  *
    135  *    \f$ q = [\dot x(t_1)^T, x(t_1)^T, u(t_1)^T, w(t_1)^T, ...,
    136  *           \dot x(t_{n_{tp}})^T, x(t_{n_{tp}})^T, u(t_{n_{tp}})^T, w(t_{n_{tp}})^T]^T\f$
    137  *
    138  *   Discrete variables which may only change during events (denoted \f$d\f$);
    139  *
    140  *      -  \f$d^r\f$  discrete real variables
    141  *      -  \f$d^i\f$  integer variables
    142  *      -  \f$u^i\f$  integer inputs
    143  *      -  \f$d^b\f$  boolean variables
    144  *      -  \f$u^b\f$  boolean inputs
    145  *      -  \f$s\f$  boolean switches mapped from relational expressions Notice that these boolean variables
    146  *      do not originate from boolean variable declarations, but from boolean valued expressions such as
    147  *      x>=3.
    148  *
    149  *    \f$ d = [{d^r}^T, {d^i}^T, {u^i}^T, {d^b}^T, {d^b}^T,s]^T\f$
    150  *
    151  *   All parameters, variables, point-wise evaluated variables and discrete variables are denoted z:
    152  *
    153  *     \f$ z = [p^T, v^T, q^T, d^T]^T \f$
    154  *
    155  *   \subsection DAE The DAE interface
    156  *
    157  *   The DAE interface is defined by the residual function \f$F(p,v,d)\f$ where
    158  *
    159  *     \f$ F(p,v,d) = 0 \f$
    160  *
    161  *  For details on the functions included in the DAE interface, see the <a href="group__DAE.html">DAE functions documentation. </a>
    162  *
    163  *    \subsection Init The DAE initialization interface
    164  *
    165  *   The DAE initialization interface is defined by the functions \f$F_0(p,v)\f$ and \f$F_1(p,v)\f$ where
    166  *
    167  *    \f$  F_0(p,v,d) = 0 \f$<br>
    168  *    \f$  F_1(p,v,d) = 0 \f$
    169  *
    170  *   \f$F_0\f$ represents the DAE system augmented with additional initial equations
    171  *   and start values that are fixed. \f$F_1\f$ on the other hand contains equations for
    172  *   initialization of variables for which the value given in the start attribute is
    173  *   not fixed.
    174  *
    175  *   In addition, a residual function for dependent parameters is provided
    176  *
    177  *    \f$  F_p(p) = 0 \f$
    178  *
    179  *   The iteration variables of this system are the elements in the \f$p_d^r\f$,
    180  *   \f$p_d^i\f$, \f$p_d^b\f$ vectors.
    181  *
    182  *   For details on the functions included in the DAE initialization interface, see the
    183  *   <a href="group__Initialization.html">DAE initialization functions documentation. </a>
    184  *
    185  *   \subsection Ode_interface The ODE interface
    186  *
    187  *   The ODE interace is defined by the relation
    188  *
    189  *   \f$\dot x = f(p,x,u,t,d). \f$
    190  *
    191  *   WARNING: The current version of the JMI interface supports only Modelica
    192  *   models which are written explicitly on ODE form. Accordingly, no
    193  *   algebraic variables are supported in this version.
    194  *
    195  *  \section Jacobians Evaluation of Jacobians
    196  *
    197  *  Evaluation of Jacobians is controlled by four arguments:
    198  *
    199  *   - eval_alg    This argument is used to select the method evaluation
    200  *                     for the Jacobian. JMI_DER_SYMBOLIC and JMI_DER_CPPAD
    201  *                     is currently supported.
    202  *   - sparsity          This argument is a mask that selects whether
    203  *                     sparse or dense evaluation of the Jacobian should
    204  *                     be used. The constants JMI_DER_SPARSE are used to
    205  *                     specify a sparse Jacobian, whereas JMI_DER_DENSE_COL_MAJOR
    206  *                     and JMI_DER_DENSE_ROW_MAJOR are used to specify dense
    207  *                     column major or row major Jacobians respectively.
    208  *   - independent_vars  This argument is used to specify which variable types
    209  *                     are considered to be independent variables in the Jacobian
    210  *                     evaluation. The constants JMI_DER_NN are used to indicate that
    211  *                     the Jacobian w.r.t. a particular vector should be evaluated.
    212  *   - mask              This array has the same size as the number of column of the dense
    213  *                     Jacobian (equal to the size of the vector \f$z\f$), and holds the value of 0 if the corresponding Jacobian
    214  *                     column should not be computed. If the value of an entry in
    215  *                     mask i 1, then the corresponding Jacobian column will be evaluated.
    216  *                     The evaluated Jacobian columns are stored in the first
    217  *                     entries of the output argument jac.
    218  *
    219  *  Notice that only Jacobian evaluation w.r.t. real parameters and variables
    220  *  is currently supported.
    221  *
    222  *  TODO: It may be interesting to include an additional layer that enables
    223  *  support for partially defined Jacobians. This would be beneficial if symbolic
    224  *  expressions for the Jacobian is available for some entries, but for other
    225  *  an AD algorithm is to be used.
    226  *
    227  * \section ErrorHandling Error handling
    228  */
    229 
    23024#ifndef _JMI_H
    23125#define _JMI_H
    23226
     27#include "jmi_ode_solver.h"
    23328#include "jmi_util.h"
    23429#include "jmi_global.h"
     
    25348#define JMI_TIME_EXACT 0            /**< \brief Time events that are exact shall be handled. */
    25449#define JMI_TIME_GREATER 1          /**< \brief Time events should be handled as time has passed the exact. */
    255 
    256 /*The option JMI_DER_CPPAD is no longer used and should be removed.*/
    257 #define JMI_DER_SYMBOLIC 1          /**< \brief Use symbolic evaluation of derivatives (if available). */
    258 #define JMI_DER_CPPAD 2             /**< \brief Use automatic differentiation (CppAD) to evaluate derivatives. */
    259 #define JMI_DER_CAD 4               /**< \brief Use automatic differentiation (generated C code) to evaluate derivatives. */
    260 #define JMI_DER_FD 8                /**< \brief Use finite differences to evaluate derivatives. */
    261 
    262 #define JMI_DER_CHECK_SCREEN_ON 1   /**< \brief Prints all evaluation errors on the screen, returns 0. */
    263 #define JMI_DER_CHECK_SCREEN_OFF 2  /**< \brief Return -1 if an evaluation error occur. */
    264 
    265 #define JMI_DER_SPARSE 1            /**< \brief Sparse evaluation of derivatives. */
    266 #define JMI_DER_DENSE_COL_MAJOR 2   /**<  \brief Dense evaluation (column major) of derivatives. */
    267 #define JMI_DER_DENSE_ROW_MAJOR 4   /**<  \brief Dense evaluation (row major) of derivatives. */
    268 
    269 /* Flags for evaluation of Jacobians w.r.t. parameters in the p vector */
    270 #define JMI_DER_P_OPT 8192          /**< \brief Evaluate derivatives w.r.t. real free parameters, \f$p_{opt}\f$.*/
    271 #define JMI_DER_CI 1                /**< \brief Evaluate derivatives w.r.t. real independent constants, \f$c_i\f$.*/
    272 #define JMI_DER_CD 2                /**< \brief Evaluate derivatives w.r.t. real dependent constants, \f$c_d\f$.*/
    273 #define JMI_DER_PI 4                /**< \brief Evaluate derivatives w.r.t. real independent parameters, \f$p_i\f$.*/
    274 #define JMI_DER_PD 8                /**< \brief Evaluate derivatives w.r.t. real dependent constants, \f$p_d\f$.*/
    275 /* Flags for evaluation of Jacobians w.r.t. variables in the v vector */
    276 #define JMI_DER_DX 16               /**< \brief Evaluate derivatives w.r.t. real derivatives, \f$\dot x\f$.*/
    277 #define JMI_DER_X 32                /**< \brief Evaluate derivatives w.r.t. real differentiated variables, \f$x\f$.*/
    278 #define JMI_DER_U 64                /**< \brief Evaluate derivatives w.r.t. real inputs, \f$u\f$.*/
    279 #define JMI_DER_W 128               /**< \brief Evaluate derivatives w.r.t. real algebraic variables, \f$w\f$.*/
    280 #define JMI_DER_T 256               /**< \brief Evaluate derivatives w.r.t. real time, \f$t\f$.*/
    281 
    282 /** \brief Evaluate derivatives w.r.t. all variables, \f$z\f$.*/
    283 #define JMI_DER_ALL (JMI_DER_CI | JMI_DER_CD | JMI_DER_PI | JMI_DER_PD |\
    284     JMI_DER_DX | JMI_DER_X | JMI_DER_U | JMI_DER_W | JMI_DER_T  )
    285 
    286 /**  \brief Evaluate derivatives w.r.t. all variables in \f$p\f$.*/
    287 #define JMI_DER_ALL_P JMI_DER_CI | JMI_DER_CD | JMI_DER_PI | JMI_DER_PD
    288 
    289 /**  \brief Evaluate derivatives w.r.t. all variables in \f$v\f$.*/
    290 #define JMI_DER_ALL_V JMI_DER_DX | JMI_DER_X | JMI_DER_U | JMI_DER_W |\
    291     JMI_DER_T
    29250
    29351/**  \brief Definitions of boolean true and false literals.*/
     
    31775#define JMI_DISCRETE_REALS_AND_NON_REALS_CHANGED -7
    31876
    319 #define JMI_UPDATE_STATES    1
    320 
    321  typedef enum {
    322      JMI_ODE_CVODE,
    323      JMI_ODE_EULER
    324  } jmi_ode_method_t;
    325 
    326 /* @} */
    327 
    328 /*
    329  *****************************************
    330  *
    331  *    Public interface
    332  *
    333  ****************************************
    334  */
    335 
    336 /**
    337  * \defgroup jmi_struct Creation, initialization and destruction of jmi_t structs
    338  * \brief The main data structure in the JMI Model interface is jmi_t, which contains
    339  * all information needed to evaluate the functions in the JMI Model interface.
    340  *
    341  * Typically,
    342  * a pointer to a jmi_t struct is passed as the first argument to functions in the interface.
    343  *
    344  *
     77#define JMI_UPDATE_STATES    1
     78 
     79 /* @} */
     80
     81/**
     82 * \defgroup jmi_function_typedefs Function typedefs
     83 *
     84 * \brief Function signatures to be used in the generated code
    34585 */
    34686
    34787/* @{ */
     88
     89/**
     90 * \brief A generic function signature that only takes a jmi_t struct as input.
     91 *
     92 * @param jmi A jmi_t struct.
     93 * @return Error code.
     94 */
     95typedef int (*jmi_generic_func_t)(jmi_t* jmi);
     96
     97/**
     98 * \brief A function signature for computation of the next time event.
     99 *
     100 * @param jmi A jmi_t struct.
     101 * @param event (Output) Information about the next time event.
     102 * @return Error code.
     103 */
     104typedef int (*jmi_next_time_event_func_t)(jmi_t* jmi, jmi_time_event_t* event);
     105
     106/**
     107 * \brief Function signature for evaluation of a residual function in
     108 * the generated code.
     109 *
     110 * Notice that this function signature is used for all functions in
     111 * the DAE and DAE initialization interfaces.
     112 *
     113 * @param jmi A jmi_t struct.
     114 * @param res (Output) The residual value.
     115 * @return Error code.
     116 *
     117 */
     118typedef int (*jmi_residual_func_t)(jmi_t* jmi, jmi_real_t** res);
     119
     120/**
     121 * \brief Function signature for evaluation of a directional derivative function
     122 * in the generated code.
     123 *
     124 * Notice that this function signature is used for all functions in
     125 * the DAE and DAE initialization.
     126 *
     127 * @param jmi A jmi_t struct.
     128 * @param res (Output) The residual value vector.
     129 * @param dF (Output) The directional derivative of the residual function.
     130 * @param dz the Seed vector of size n_x + n_x + n_u + n_w.
     131 * @return Error code.
     132 *
     133 */
     134typedef int (*jmi_directional_der_residual_func_t)(jmi_t* jmi, jmi_real_t** res,
     135        jmi_real_t** dF, jmi_real_t** dz);
     136 
     137 
     138 /* @} */
     139
     140/**
     141 * \defgroup jmi_structs_init The jmi_t and jmi_model_t
     142 *
     143 * \brief Functions for initialization of the jmi_t and jmi_model_t.
     144 *
     145 */
     146
     147/* @{ */
     148
     149/**
     150 * \brief Allocates memory and sets up the jmi_t struct.
     151 *
     152 * This function is typically called from within jmi_new in the generated code.
     153 * The reason for introducing this function is that the allocation of the
     154 * jmi_t struct should not be repeated in the generated code.
     155 *
     156 * @param jmi (Output) A pointer to a jmi_t pointer.
     157 * @param n_real_ci Number of real independent constants.
     158 * @param n_real_cd Number of real dependent constants.
     159 * @param n_real_pi Number of real independent parameters.
     160 * @param n_real_pd Number of real dependent parameters.
     161 * @param n_integer_ci Number of integer independent constants.
     162 * @param n_integer_cd Number of integer dependent constants.
     163 * @param n_integer_pi Number of integer independent parameters.
     164 * @param n_integer_pd Number of integer dependent parameters.
     165 * @param n_boolean_ci Number of boolean independent constants.
     166 * @param n_boolean_cd Number of boolean dependent constants.
     167 * @param n_boolean_pi Number of boolean independent parameters.
     168 * @param n_boolean_pd Number of boolean dependent parameters.
     169 * @param n_real_dx Number of real derivatives.
     170 * @param n_real_x Number of real differentiated variables.
     171 * @param n_real_u Number of real inputs.
     172 * @param n_real_w Number of real algebraics.
     173 * @param n_real_d Number of real discrete parameters.
     174 * @param n_integer_d Number of integer discrete parameters.
     175 * @param n_integer_u Number of integer inputs.
     176 * @param n_boolean_d Number of boolean discrete parameters.
     177 * @param n_boolean_u Number of boolean inputs.
     178 * @param n_sw Number of switching functions in DAE \$fF\$f.
     179 * @param n_sw_init Number of switching functions in DAE initialization system \$fF_0\$f.
     180 * @param n_guards Number of guards in DAE \$fF\$f.
     181 * @param n_guards_init Number of guards in DAE initialization system \$fF_0\$f.
     182 * @param n_dae_blocks Number of DAE blocks.
     183 * @param n_dae_init_blocks Number of DAE initialization blocks.
     184 * @param n_initial_relations Number of relational operators in the initial equations.
     185 * @param initial_relations Kind of relational operators in the initial equations. One of JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ.
     186 * @param n_relations Number of relational operators in the DAE equations.
     187 * @param relations Kind of relational operators in the DAE equations. One of: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ.
     188 * @param scaling_method Scaling method. Options are JMI_SCALING_NONE or JMI_SCALING_VARIABLES.
     189 * @param homotopy_block Block number of the block which contains homotopy operators, -1 if none.
     190 * @param jmi_callbacks A jmi_callback_t struct.
     191 * @return Error code.
     192 */
     193int jmi_init(jmi_t** jmi,
     194        int n_real_ci, int n_real_cd, int n_real_pi,
     195        int n_real_pi_s, int n_real_pi_f, int n_real_pi_e, int n_real_pd,
     196        int n_integer_ci, int n_integer_cd, int n_integer_pi,
     197        int n_integer_pi_s, int n_integer_pi_f, int n_integer_pi_e, int n_integer_pd,
     198        int n_boolean_ci, int n_boolean_cd, int n_boolean_pi,
     199        int n_boolean_pi_s, int n_boolean_pi_f, int n_boolean_pi_e, int n_boolean_pd,
     200        int n_real_dx, int n_real_x, int n_real_u, int n_real_w,
     201        int n_real_d, int n_integer_d, int n_integer_u,
     202        int n_boolean_d, int n_boolean_u,
     203        int n_sw, int n_sw_init, int n_time_sw, int n_state_sw,
     204        int n_guards, int n_guards_init,
     205        int n_dae_blocks, int n_dae_init_blocks,
     206        int n_initial_relations, int* initial_relations,
     207        int n_relations, int* relations, int n_dynamic_state_sets,
     208        jmi_real_t* nominals,
     209        int scaling_method, int n_ext_objs, int homotopy_block,
     210        jmi_callbacks_t* jmi_callbacks);
     211       
     212/**
     213 * Deallocates memory and deletes a jmi_t struct.
     214 *
     215 * @param jmi A pointer to the jmi_t struc to be deleted.
     216 */
     217int jmi_delete(jmi_t* jmi);
     218
     219/**
     220 * \brief Allocates a jmi_model_t struct.
     221 *
     222 * @param jmi A jmi_t struct.
     223 * @param model_ode_derivatives_dir_der A function pointer to the ODE directional derivative function.
     224 * @param model_ode_derivatives A function pointer to the ODE RHS function.
     225 * @param model_ode_event_indicators A function pointer to the ODE event indicators.
     226 * @param model_ode_initialize A function pointer to the ODE initialization function.
     227 * @param model_init_eval_parameters A function pointer for evaluating the calculated parameters.
     228 * @param model_ode_next_time_event A function pointer for evaluating the next time event.
     229 */
     230void jmi_model_init(jmi_t* jmi,
     231                    jmi_generic_func_t model_ode_derivatives_dir_der,
     232                    jmi_generic_func_t model_ode_derivatives,
     233                    jmi_residual_func_t model_ode_event_indicators,
     234                    jmi_generic_func_t model_ode_initialize,
     235                    jmi_generic_func_t model_init_eval_parameters,
     236                    jmi_next_time_event_func_t model_ode_next_time_event);
     237
     238/**
     239 * \brief Dallocates the jmi_model_t struct in jmi if it is not NULL.
     240 *
     241 * @param jmi A jmi_t struct.
     242 */
     243void jmi_model_delete(jmi_t* jmi);
     244
     245/**
     246 * \brief Contains a pointers to the runtime modules.
     247 */
     248struct jmi_modules_t {
     249    jmi_module_t *mod_get_set;
     250
     251    /* Add future modules here */
     252};
     253
     254typedef struct jmi_z_offsets {
     255    int o_ci, o_cd, o_pi, o_pd, o_ps, o_pf, o_pe;
     256    int n_ci, n_cd, n_pi, n_pd, n_ps, n_pf, n_pe, n;
     257} jmi_z_offsets_t;
     258
     259typedef struct jmi_z_strings {
     260    char** values;
     261    jmi_z_offsets_t offsets;
     262} jmi_z_strings_t;
     263
     264typedef struct jmi_z {
     265    jmi_z_strings_t strings;
     266} jmi_z_t;
     267
     268/**
     269 * \brief The main struct of the JMI Model interface containing
     270 * dimension information and model function pointers in jmi_model_t.
     271 *
     272 * jmi_t is the main struct in the JMI model interface. It contains
     273 * pointers to structs of types, jmi_model_t represents the model in
     274 * the form of function pointers contining the generated code.
     275 */
     276struct jmi_t {
     277    jmi_callbacks_t jmi_callbacks;       /**< \brief Struct containing callbacks the jmi runtime needs. */
     278   
     279    jmi_model_t* model;                  /**< \brief Struct contaning callbacks to the model functions. */
     280   
     281    jmi_generic_func_t init_delay;       /**< \brief Function for initializing delay structures. */
     282    jmi_generic_func_t sample_delay;     /**< \brief Function for initializing delay structures. */
     283
     284    jmi_z_t z_t;
     285
     286    int n_real_ci;                       /**< \brief Number of independent constants. */
     287    int n_real_cd;                       /**< \brief Number of dependent constants. */
     288    int n_real_pi;                       /**< \brief Number of independent parameters. */
     289    int n_real_pd;                       /**< \brief Number of dependent parameters. */
     290
     291    int n_integer_ci;                    /**< \brief Number of integer independent constants. */
     292    int n_integer_cd;                    /**< \brief Number of integer dependent constants. */
     293    int n_integer_pi;                    /**< \brief Number of integer independent parameters. */
     294    int n_integer_pd;                    /**< \brief Number of integer dependent parameters. */
     295
     296    int n_boolean_ci;                    /**< \brief Number of boolean independent constants. */
     297    int n_boolean_cd;                    /**< \brief Number of boolean dependent constants. */
     298    int n_boolean_pi;                    /**< \brief Number of boolean independent parameters. */
     299    int n_boolean_pd;                    /**< \brief Number of boolean dependent parameters. */
     300
     301    int n_real_dx;                       /**< \brief Number of derivatives. */
     302    int n_real_x;                        /**< \brief Number of differentiated states. */
     303    int n_real_u;                        /**< \brief Number of inputs. */
     304    int n_real_w;                        /**< \brief Number of algebraics. */
     305
     306    int n_real_d;                        /**< \brief Number of discrete variables. */
     307
     308    int n_integer_d;                     /**< \brief Number of integer discrete variables. */
     309    int n_integer_u;                     /**< \brief Number of integer inputs. */
     310
     311    int n_boolean_d;                     /**< \brief Number of boolean discrete variables. */
     312    int n_boolean_u;                     /**< \brief Number of boolean inputs. */
     313
     314    int n_sw;                            /**< \brief Number of switching functions in the DAE \f$F\f$. */
     315    int n_sw_init;                       /**< \brief Number of switching functions in the DAE initialization system\f$F_0\f$. */
     316    int n_time_sw;                       /**< \brief Number of switches related to time events in the DAE \f$F\f$. */
     317    int n_state_sw;                      /**< \brief Number of switches related to state events in the DAE \f$F\f$. */
     318
     319    int n_guards;                        /**< \brief Number of guards in the DAE \f$F\f$. */
     320    int n_guards_init;                   /**< \brief Number of guards in the DAE initialization system\f$F_0\f$. */
     321
     322    int n_v;                             /**< \brief Number of elements in \f$v\f$. Number of equations??*/
     323
     324    int n_z;                             /**< \brief Number of elements in \f$z\f$. */
     325   
     326    int n_dae_blocks;                    /**< \brief Number of BLT blocks. */
     327    int n_dae_init_blocks;               /**< \brief Number of initial BLT blocks. */
     328
     329    int n_delays;                        /**< \brief Number of (fixed and variable time) delay blocks. */
     330    int n_spatialdists;                  /**< \brief Number of spatialDistribution blocks. */
     331
     332    /* Offset variables in the z vector, for convenience. */
     333    /* Structural, final, and evaluated parameters "_pi_s", "_ip_f", and
     334     * "_pi_e" are subsets of independent parameters "_pi"
     335     * and their offsets are only used for generating error messages */
     336    int offs_real_ci;                    /**< \brief  Offset of the independent real constant vector in \f$z\f$. */
     337    int offs_real_cd;                    /**< \brief  Offset of the dependent real constant vector in \f$z\f$. */
     338    int offs_real_pi;                    /**< \brief  Offset of the independent real parameter vector in \f$z\f$. */
     339    int offs_real_pi_s;                  /**< \brief  Offset of the structural real parameter vector in \f$z\f$. */
     340    int offs_real_pi_f;                  /**< \brief  Offset of the final real parameter vector in \f$z\f$. */
     341    int offs_real_pi_e;                  /**< \brief  Offset of the evaluated real parameter vector in \f$z\f$. */
     342    int offs_real_pd;                    /**< \brief  Offset of the dependent real parameter vector in \f$z\f$. */
     343
     344    int offs_integer_ci;                 /**< \brief  Offset of the independent integer constant vector in \f$z\f$. */
     345    int offs_integer_cd;                 /**< \brief  Offset of the dependent integer constant vector in \f$z\f$. */
     346    int offs_integer_pi;                 /**< \brief  Offset of the independent integer parameter vector in \f$z\f$. */
     347    int offs_integer_pi_s;               /**< \brief  Offset of the structural integer parameter vector in \f$z\f$. */
     348    int offs_integer_pi_f;               /**< \brief  Offset of the final integer parameter vector in \f$z\f$. */
     349    int offs_integer_pi_e;               /**< \brief  Offset of the evaluated integer parameter vector in \f$z\f$. */
     350    int offs_integer_pd;                 /**< \brief  Offset of the dependent integer parameter vector in \f$z\f$. */
     351
     352    int offs_boolean_ci;                 /**< \brief  Offset of the independent boolean constant vector in \f$z\f$. */
     353    int offs_boolean_cd;                 /**< \brief  Offset of the dependent boolean constant vector in \f$z\f$. */
     354    int offs_boolean_pi;                 /**< \brief  Offset of the independent boolean parameter vector in \f$z\f$. */
     355    int offs_boolean_pi_s;               /**< \brief  Offset of the structural boolean parameter vector in \f$z\f$. */
     356    int offs_boolean_pi_f;               /**< \brief  Offset of the final boolean parameter vector in \f$z\f$. */
     357    int offs_boolean_pi_e;               /**< \brief  Offset of the evaluated boolean parameter vector in \f$z\f$. */
     358    int offs_boolean_pd;                 /**< \brief  Offset of the dependent boolean parameter vector in \f$z\f$. */
     359
     360    int offs_real_dx;                    /**< \brief  Offset of the derivative real vector in \f$z\f$. */
     361    int offs_real_x;                     /**< \brief  Offset of the differentiated real variable vector in \f$z\f$. */
     362    int offs_real_u;                     /**< \brief  Offset of the input real vector in \f$z\f$. */
     363    int offs_real_w;                     /**< \brief  Offset of the algebraic real variables vector in \f$z\f$. */
     364    int offs_t;                          /**< \brief  Offset of the time entry in \f$z\f$. */
     365    int offs_homotopy_lambda;            /**< \brief  Offset of the homotopy lambda entry in \f$z\f$. */
     366
     367    int offs_real_d;                     /**< \brief  Offset of the discrete real variable vector in \f$z\f$. */
     368
     369    int offs_integer_d;                  /**< \brief  Offset of the discrete integer variable vector in \f$z\f$. */
     370    int offs_integer_u;                  /**< \brief  Offset of the input integer vector in \f$z\f$. */
     371
     372    int offs_boolean_d;                  /**< \brief  Offset of the discrete boolean variable vector in \f$z\f$. */
     373    int offs_boolean_u;                  /**< \brief  Offset of the input boolean vector in \f$z\f$. */
     374
     375    int offs_sw;                         /**< \brief  Offset of the first switching function in the DAE \f$F\f$ */
     376    int offs_sw_init;                    /**< \brief  Offset of the first switching function in the DAE initialization system \f$F_0\f$ */
     377    int offs_state_sw;                   /**< \brief  Offset of the first switching function (state) in the DAE \f$F\f$ */
     378    int offs_time_sw;                    /**< \brief  Offset of the first switching function (time) in the DAE \f$F\f$ */
     379
     380    int offs_guards;                     /**< \brief  Offset of the first guard \f$F\f$ */
     381    int offs_guards_init;                /**< \brief  Offset of the first guard in the DAE initialization system \f$F_0\f$ */
     382
     383    int offs_pre_real_dx;                /**< \brief  Offset of the pre derivative real vector in \f$z\f$. */
     384    int offs_pre_real_x;                 /**< \brief  Offset of the pre differentiated real variable vector in \f$z\f$. */
     385    int offs_pre_real_u;                 /**< \brief  Offset of the pre input real vector in \f$z\f$. */
     386    int offs_pre_real_w;                 /**< \brief  Offset of the pre algebraic real variables vector in \f$z\f$. */
     387
     388    int offs_pre_real_d;                 /**< \brief  Offset of the pre discrete real variable vector in \f$z\f$. */
     389
     390    int offs_pre_integer_d;              /**< \brief  Offset of the pre discrete integer variable vector in \f$z\f$. */
     391    int offs_pre_integer_u;              /**< \brief  Offset of the pre input integer vector in \f$z\f$. */
     392
     393    int offs_pre_boolean_d;              /**< \brief  Offset of the pre discrete boolean variable vector in \f$z\f$. */
     394    int offs_pre_boolean_u;              /**< \brief  Offset of the pre input boolean vector in \f$z\f$. */
     395
     396    int offs_pre_sw;                     /**< \brief  Offset of the first pre switching function in the DAE \f$F\f$ */
     397    int offs_pre_sw_init;                /**< \brief  Offset of the first pre switching function in the DAE initialization system \f$F_0\f$ */
     398
     399    int offs_pre_guards;                 /**< \brief  Offset of the first pre guard \f$F\f$ */
     400    int offs_pre_guards_init;            /**< \brief  Offset of the first pre guard in the DAE initialization system \f$F_0\f$ */
     401
     402    jmi_real_t** z;                      /**< \brief  This vector contains the actual values. */
     403    jmi_real_t** z_last;                 /**< \brief  This vector contains the values from the last successful integration step. */
     404    jmi_real_t** dz;                     /**< \brief  This vector is used to store calculated directional derivatives */
     405    int dz_active_index;                 /**< \brief The element in dz_active_variables to be used (0..JMI_ACTIVE_VAR_BUFS_NUM). Needed for local iterations */
     406    int block_level;                     /**< \brief Block level for nested equation blocks. Currently 0 or 1. */
     407    jmi_real_t *dz_active_variables[1];  /**< \brief  This vector is used to store seed-values for active variables in block Jacobians */
     408#define JMI_ACTIVE_VAR_BUFS_NUM 3
     409    jmi_real_t *dz_active_variables_buf[JMI_ACTIVE_VAR_BUFS_NUM];  /**< \brief  This vector is the buffer used by dz_active_variables */
     410    void** ext_objs;                     /**< \brief This vector contains the external object pointers. */
     411   
     412    jmi_real_t* nominals;                             /**< \brief Nominal values of differentiated states. */
     413    jmi_real_t *variable_scaling_factors;             /**< \brief Scaling factors. For convenience the vector has the same size as z but only scaling of reals are used. */
     414    int scaling_method;                               /**< \brief Scaling method: JMI_SCALING_NONE, JMI_SCALING_VARIABLES */
     415    jmi_block_residual_t** dae_block_residuals;       /**< \brief A vector of function pointers to DAE equation blocks */
     416    jmi_block_residual_t** dae_init_block_residuals;  /**< \brief A vector of function pointers to DAE initialization equation blocks */
     417    int cached_block_jacobians;                       /**< \brief This flag indicates weather the Jacobian needs to be refactorized */
     418
     419    jmi_delay_t *delays;                 /**< \brief Delay blocks (fixed and variable time) */
     420    jmi_spatialdist_t *spatialdists;     /**< \brief spatialDistribution blocks */
     421    jmi_boolean delay_event_mode;        /**< \brief Controls operation of `jmi_delay_record_sample` and `jmi_spatialdist_record_sample` */
     422   
     423    jmi_dynamic_state_set_t* dynamic_state_sets; /**< \brief Struct for the list of dynamic state sets */
     424    jmi_int_t n_dynamic_state_sets;              /**< \brief Number of set of dynamic state variables */
     425
     426    jmi_int_t n_initial_relations;       /**< \brief Number of relational operators used in the event indicators for the initialization system. There should be the same number of initial relations as there are event indicators */
     427    jmi_int_t* initial_relations;        /**< \brief Kind of relational operators used in the event indicators for the initialization system: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ */
     428    jmi_int_t n_relations;               /**< \brief Number of relational operators used in the event indicators for the DAE system */
     429    jmi_int_t* relations;                /**< \brief Kind of relational operators used in the event indicators for the DAE system: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ */
     430
     431    jmi_real_t atEvent;                  /**< \brief A boolean variable indicating if the model equations are evaluated at an event.*/
     432    jmi_real_t atInitial;                /**< \brief A boolean variable indicating if the model equations are evaluated at the initial time */
     433    jmi_real_t atTimeEvent;              /**< \brief A boolean variable indicating if the model equations are evaluated at an time event time */
     434    int eventPhase;                      /**< \brief Zero if in first phase of event iteration, non zero if in second phase */
     435    int save_restore_solver_state_mode;  /**< \brief A boolean variable indicating if in a mode where solver state should be saved and restored */
     436   
     437    jmi_time_event_t nextTimeEvent;
     438
     439    jmi_int_t is_initialized;            /**< Flag to keep track of if the initial equations have been solved. */
     440
     441    int nbr_event_iter;                  /**< Counter for the nummber of global event iterations performed. */
     442    int nbr_consec_time_events;          /**< Counter for the nummber of consecutive time events handled (max should always be 2). */
     443
     444    jmi_log_t* log;                      /**< \brief Struct containing the structured logger. */
     445
     446    jmi_options_t options;               /**< \brief Runtime options */
     447    jmi_real_t events_epsilon;           /**< \brief Value used to adjust the event indicator functions */
     448    jmi_real_t tmp_events_epsilon;       /**< \brief Temporary holder for the event epsilon during initialization */
     449    jmi_real_t newton_tolerance;         /**< \brief Tolerance that is used in the newton iteration */
     450    jmi_int_t recomputeVariables;        /**< \brief Dirty flag indicating when equations should be resolved. */
     451    jmi_int_t updated_states;            /**< \brief Flag indicating if the dynamic set of states has been updated. */
     452
     453    jmi_real_t* real_x_work;             /**< \brief Work array for the real x variables */
     454    jmi_real_t* real_u_work;             /**< \brief Work array for the real u variables */
     455   
     456    jmp_buf try_location[JMI_MAX_EXCEPTION_DEPTH+1];                /**< \brief Buffer for setjmp/longjmp, for exception handling. */
     457    jmi_int_t current_try_depth;
     458
     459    jmi_int_t model_terminate;           /**< \brief Flag to trigger termination of the simulation. */
     460    jmi_int_t user_terminate;            /**< \brief Flag that the user has terminated the model. */
     461
     462    jmi_int_t reinit_triggered;          /**< \brief Flag to signal that a reinit triggered in the current event iteration. */
     463   
     464    jmi_string_t resource_location;      /**< \brief Absolute file path to resource directory. No trailing separator. May be null. */
     465
     466    jmi_modules_t modules;               /**< \brief Interchangable modules struct */
     467    jmi_chattering_t* chattering;        /**< \brief Contains chattering information, used for logging */
     468
     469    jmi_dynamic_list dyn_mem_head;   /**< \brief List of pointers to memory allocated during function evaluations. */
     470    jmi_dynamic_list* dyn_mem_last;  /**< \brief List of pointers to memory allocated during function evaluations. */
     471    jmi_dyn_mem_t dyn_mem;
     472};
     473
     474/**
     475 * \brief Struct describing the model equations.
     476 *
     477 * Contains function pointers for evaluating the generated code of the model.
     478 */
     479struct jmi_model_t {
     480    jmi_residual_func_t ode_event_indicators;       /**< \brief A function for evaluating the ODE event indicators. */
     481    jmi_generic_func_t ode_derivatives;              /**< \brief A function for evaluating the ODE derivatives. */
     482    jmi_generic_func_t ode_derivatives_dir_der;      /**< \brief A function for evaluating the ODE directional derivative. */
     483    jmi_generic_func_t ode_initialize;               /**< \brief A function for initializing the ODE. */
     484    jmi_generic_func_t init_eval_parameters;         /**< \brief A function for initial evaluation of calculated parameters. */
     485    jmi_next_time_event_func_t ode_next_time_event;  /**< \brief A function for computing the next time event instant. */
     486};
    348487
    349488/**
     
    369508
    370509/**
    371  * Deallocates memory and deletes a jmi_t struct.
    372  *
    373  * @param jmi A pointer to the jmi_t struc to be deleted.
    374  */
    375 int jmi_delete(jmi_t* jmi);
    376 
    377 /* @} */
    378 
    379 /**
    380  * \defgroup Access Setters and getters for the fields in jmi_t
    381  *
    382  * \brief The fields of jmi_t are conveniently accessed using the setter and getter
    383  * functions provided in the JMI Model interface.
    384  *
    385  * Notice that it is not recommended to access the fields directely, since the internal
    386  * implementation of jmi_t may change, wheras the setters and getters are less likely to
    387  * do so.
    388  *
    389  */
    390 
    391 /* @{ */
    392 
    393 /**
    394  * \brief Copy variable values to the pre vector.
    395  *
    396  * @param jmi The jmi_t struct.
    397  * @return Error code.
    398  */
    399 int jmi_copy_pre_values(jmi_t *jmi);
    400 
    401 #if 0
    402 /**
    403  * \brief Reset the z vector to the last successful state.
    404  *
    405  * @param jmi The jmi_t struct.
    406  * @return Error code.
    407  */
    408 int jmi_reset_last_successful_values(jmi_t *jmi);
    409 
    410 /**
    411  * \brief Reset the z vector (except constants and parameters)
    412  *        to the last successful state.
    413  *
    414  * @param jmi The jmi_t struct.
    415  * @return Error code.
    416  */
    417 int jmi_reset_last_internal_successful_values(jmi_t *jmi);
    418 
    419 /**
    420  * \brief Save the complete z vector.
    421  *
    422  * @param jmi The jmi_t struct.
    423  * @return Error code.
    424  */
    425 int jmi_save_last_successful_values(jmi_t *jmi);
    426 #endif
    427 
    428 /**
    429 
    430  * \brief Get a pointer to the z vector containing all variables.
    431  *
    432  * @param jmi The jmi_t struct.
    433  * @return A pointer to the \f$z\f$ vector.
    434  *
    435  */
    436 jmi_real_t* jmi_get_z(jmi_t* jmi);
    437 
    438 /**
    439 
    440  * \brief Get the size of the z vector containing all variables.
    441  *
    442  * @param jmi The jmi_t struct.
    443  * @return The size of the \f$z\f$ vector.
    444  *
    445  */
    446 int jmi_get_z_size(jmi_t* jmi);
    447 
    448 jmi_string_t* jmi_get_string_z(jmi_t* jmi);
    449 
    450 /**
    451  * \brief Get a pointer to the last successful z vector containing all variables.
    452  *
    453  * @param jmi The jmi_t struct.
    454  * @return A pointer to the \f$z\f$ vector.
    455  *
    456  */
    457 jmi_real_t* jmi_get_z_last(jmi_t* jmi);
    458 
    459 /**
    460  * \brief Get a pointer to the real independent constants vector.
    461  *
    462  * @param jmi The jmi_t struct.
    463  * @return A pointer to the \f$c_i^r\f$ vector.
    464  *
    465  */
    466 jmi_real_t* jmi_get_real_ci(jmi_t* jmi);
    467 
    468 /**
    469  * \brief Get a pointer to the real dependent constants vector.
    470  *
    471  * @param jmi The jmi_t struct.
    472  * @return A pointer to the \f$c_d^r\f$ vector.
    473  *
    474  */
    475 jmi_real_t* jmi_get_real_cd(jmi_t* jmi);
    476 
    477 /**
    478  * \brief Get a pointer to the real independent parameter vector.
    479  *
    480  * @param jmi The jmi_t struct.
    481  * @return A pointer to the \f$p_i^r\f$ vector.
    482  *
    483  */
    484 jmi_real_t* jmi_get_real_pi(jmi_t* jmi);
    485 
    486 /**
    487  * \brief Get a pointer to the real dependent parameters vector.
    488  *
    489  * @param jmi The jmi_t struct.
    490  * @return A pointer to the \f$p_d^r\f$ vector.
    491  *
    492  */
    493 jmi_real_t* jmi_get_real_pd(jmi_t* jmi);
    494 
    495 /**
    496  * \brief Get a pointer to the integer independent constants vector.
    497  *
    498  * @param jmi The jmi_t struct.
    499  * @return A pointer to the \f$c_i^r\f$ vector.
    500  *
    501  */
    502 jmi_real_t* jmi_get_integer_ci(jmi_t* jmi);
    503 
    504 /**
    505  * \brief Get a pointer to the integer dependent constants vector.
    506  *
    507  * @param jmi The jmi_t struct.
    508  * @return A pointer to the \f$c_d^i\f$ vector.
    509  *
    510  */
    511 jmi_real_t* jmi_get_integer_cd(jmi_t* jmi);
    512 
    513 /**
    514  * \brief Get a pointer to the integer independent parameter vector.
    515  *
    516  * @param jmi The jmi_t struct.
    517  * @return A pointer to the \f$p_i^i\f$ vector.
    518  *
    519  */
    520 jmi_real_t* jmi_get_integer_pi(jmi_t* jmi);
    521 
    522 /**
    523  * \brief Get a pointer to the integer dependent parameters vector.
    524  *
    525  * @param jmi The jmi_t struct.
    526  * @return A pointer to the \f$p_d^i\f$ vector.
    527  *
    528  */
    529 jmi_real_t* jmi_get_integer_pd(jmi_t* jmi);
    530 
    531 /**
    532  * \brief Get a pointer to the boolean independent constants vector.
    533  *
    534  * @param jmi The jmi_t struct.
    535  * @return A pointer to the \f$c_i^r\f$ vector.
    536  *
    537  */
    538 jmi_real_t* jmi_get_boolean_ci(jmi_t* jmi);
    539 
    540 /**
    541  * \brief Get a pointer to the boolean dependent constants vector.
    542  *
    543  * @param jmi The jmi_t struct.
    544  * @return A pointer to the \f$c_d^i\f$ vector.
    545  *
    546  */
    547 jmi_real_t* jmi_get_boolean_cd(jmi_t* jmi);
    548 
    549 /**
    550  * \brief Get a pointer to the boolean independent parameter vector.
    551  *
    552  * @param jmi The jmi_t struct.
    553  * @return A pointer to the \f$p_i^i\f$ vector.
    554  *
    555  */
    556 jmi_real_t* jmi_get_boolean_pi(jmi_t* jmi);
    557 
    558 /**
    559  * \brief Get a pointer to the boolean dependent parameters vector.
    560  *
    561  * @param jmi The jmi_t struct.
    562  * @return A pointer to the \f$p_d^i\f$ vector.
    563  *
    564  */
    565 jmi_real_t* jmi_get_boolean_pd(jmi_t* jmi);
    566 
    567 /**
    568  * \brief Get a pointer to the real derivatives vector.
    569  *
    570  * @param jmi The jmi_t struct.
    571  * @return A pointer to the \f$dx\f$ vector.
    572  *
    573  */
    574 jmi_real_t* jmi_get_real_dx(jmi_t* jmi);
    575 
    576 /**
    577  * \brief Get a pointer to the differentiated variables vector.
    578  *
    579  * @param jmi The jmi_t struct.
    580  * @return A pointer to the \f$x\f$ vector.
    581  *
    582  */
    583 jmi_real_t* jmi_get_real_x(jmi_t* jmi);
    584 
    585 /**
    586  * \brief Get a pointer to the inputs vector.
    587  *
    588  * @param jmi The jmi_t struct.
    589  * @return A pointer to the \f$u\f$ vector.
    590  *
    591  */
    592 jmi_real_t* jmi_get_real_u(jmi_t* jmi);
    593 
    594 /**
    595  * \brief Get a pointer to the algebraic variables vector.
    596  *
    597  * @param jmi The jmi_t struct.
    598  * @return A pointer to the \f$w\f$ vector.
    599  *
    600  */
    601 jmi_real_t* jmi_get_real_w(jmi_t* jmi);
    602 
    603 /**
    604  * \brief Get a pointer to the time value.
    605  *
    606  * @param jmi The jmi_t struct.
    607  * @return A pointer to \f$t\f$.
    608  *
    609  */
    610 jmi_real_t* jmi_get_t(jmi_t* jmi);
    611 
    612 /**
    613  * \brief Get a pointer to the derivatives corresponding to the i:th time point.
    614  *
    615  * @param jmi The jmi_t struct.
    616  * @param i Index of the time point: 0 corresponds to first time point.
    617  * @return A pointer to the \f$dx_{p,i}\f$ vector.
    618  *
    619  */
    620 jmi_real_t* jmi_get_real_dx_p(jmi_t* jmi,int i);
    621 
    622 /**
    623  * \brief Get a pointer to the differentiated variables corresponding to the i:th time point.
    624  *
    625  * @param jmi The jmi_t struct.
    626  * @param i Index of the time point: 0 corresponds to first time point.
    627  * @return A pointer to the \f$x_{p,i}\f$ vector.
    628  *
    629  */
    630 jmi_real_t* jmi_get_real_x_p(jmi_t* jmi, int i);
    631 
    632 /**
    633  * \brief Get a pointer to the inputs corresponding to the i:th time point.
    634  *
    635  * @param jmi The jmi_t struct.
    636  * @param i Index of the time point: 0 corresponds to first time point.
    637  * @return A pointer to the \f$u_{p,i}\f$ vector.
    638  *
    639  */
    640 jmi_real_t* jmi_get_real_u_p(jmi_t* jmi, int i);
    641 
    642 /**
    643  * \brief Get a pointer to the algebraic variables corresponding to the i:th time point.
    644  *
    645  * @param jmi The jmi_t struct.
    646  * @param i Index of the time point: 0 corresponds to first time point.
    647  * @return A pointer to the \f$w_{p,i}\f$ vector.
    648  *
    649  */
    650 jmi_real_t* jmi_get_real_w_p(jmi_t* jmi, int i);
    651 
    652 /**
    653  * \brief Get a pointer to the real discrete variables vector.
    654  *
    655  * @param jmi The jmi_t struct.
    656  * @return A pointer to the \f$d^r\f$ vector.
    657  *
    658  */
    659 jmi_real_t* jmi_get_real_d(jmi_t* jmi);
    660 
    661 /**
    662  * \brief Get a pointer to the integer discrete variables vector.
    663  *
    664  * @param jmi The jmi_t struct.
    665  * @return A pointer to the \f$d^i\f$ vector.
    666  *
    667  */
    668 jmi_real_t* jmi_get_integer_d(jmi_t* jmi);
    669 
    670 /**
    671  * \brief Get a pointer to the integer input variables vector.
    672  *
    673  * @param jmi The jmi_t struct.
    674  * @return A pointer to the \f$u^i\f$ vector.
    675  *
    676  */
    677 jmi_real_t* jmi_get_integer_u(jmi_t* jmi);
    678 
    679 /**
    680  * \brief Get a pointer to the boolean discrete variables vector.
    681  *
    682  * @param jmi The jmi_t struct.
    683  * @return A pointer to the \f$d^i\f$ vector.
    684  *
    685  */
    686 jmi_real_t* jmi_get_boolean_d(jmi_t* jmi);
    687 
    688 /**
    689  * \brief Get a pointer to the boolean input variables vector.
    690  *
    691  * @param jmi The jmi_t struct.
    692  * @return A pointer to the \f$u^i\f$ vector.
    693  *
    694  */
    695 jmi_real_t* jmi_get_boolean_u(jmi_t* jmi);
    696 
    697 /**
    698  * \brief Get the value references of the outputs.
    699  *
    700  * @param jmi A jmi_t struct.
    701  * @param output_vrefs (Output) An array containing the value references
    702  *                              of the outputs.
    703  * @return Error code.
    704  *
    705  */
    706 int jmi_get_output_vrefs(jmi_t *jmi, int *output_vrefs);
    707 
    708 /**
    709  * \brief Get a pointer to the first switching function in the DAE \$fF\$f.
    710  * A switch value of 1 corresponds to true and 0 corresponds to false.
    711  *
    712  * @param jmi The jmi_t struct.
    713  * @return A pointer to the vector of switching functions.
    714  *
    715  */
    716 jmi_real_t* jmi_get_sw(jmi_t* jmi);
    717 
    718 /**
    719  * \brief Get a pointer to the first switching function (state) in the DAE \$fF\$f.
    720  * A switch value of 1 corresponds to true and 0 corresponds to false.
    721  *
    722  * @param jmi The jmi_t struct.
    723  * @return A pointer to the vector of switching functions.
    724  *
    725  */
    726 jmi_real_t* jmi_get_state_sw(jmi_t* jmi);
    727 
    728 /**
    729  * \brief Get a pointer to the first switching function (time) in the DAE \$fF\$f.
    730  * A switch value of 1 corresponds to true and 0 corresponds to false.
    731  *
    732  * @param jmi The jmi_t struct.
    733  * @return A pointer to the vector of switching functions.
    734  *
    735  */
    736 jmi_real_t* jmi_get_time_sw(jmi_t* jmi);
    737 
    738 /**
    739  * \brief Get a pointer to the first switching function in the initialization system \$fF_0\$f.
    740  * A switch value of 1 corresponds to true and 0 corresponds to false.
    741  * @param jmi The jmi_t struct.
    742  * @return A pointer to the vector of switching functions.
    743  *
    744  */
    745 jmi_real_t* jmi_get_sw_init(jmi_t* jmi);
    746 
    747 /**
    748  * \brief Get a pointer to the scaling factor vector.
    749  * @param jmi The jmi_t struct.
    750  * @return A pointer to the scaling factor vector.
    751  *
    752  */
    753 jmi_real_t* jmi_get_variable_scaling_factors(jmi_t* jmi);
    754 
    755 /**
    756  * \brief Get the scaling method. Alternatives are JMI_SCALING_NONE and
    757  * JMI_SCALING_VARIABLES.
    758  * @param jmi The jmi_t struct.
    759  * @return An integer representing the scaling method used.
    760  *
    761  */
    762 int jmi_get_scaling_method(jmi_t* jmi);
    763 
    764 
    765 /**
    766510 * \brief Get the name of the model that produced this FMU/JMU.
    767511 */
    768512const char *jmi_get_model_identifier();
    769513
    770 
    771 /* @} */
    772 
    773 
    774 /*********************************************
    775  *
    776  * ODE interface
    777  *
    778  ********************************************/
    779 
    780 /**
    781  * \defgroup ODE ODE interface
    782  * \brief Access to the ODE representation.
    783  *
    784  * WARNING: The current version of the ODE interface is very limited and
    785  * requires that the Modelica model is explicitly given on ODE form.
    786  * Accordingly, algebraic variables are not supported.
    787  */
    788 /* @{ */
    789 
    790 
    791 /**
    792  * \brief Evaluate the right hand side of the ODE.
    793  *
    794  * The user sets the input variables by writing to
    795  * the vectors obtained from the functions ::jmi_get_x, ::jmi_get_u etc. The
    796  * output (the values of the derivatives) is available after a call to
    797  * ::jmi_ode_f in the vector obtained by calling ::jmi_get_dx.
    798  *
    799  * @param jmi A jmi_t struct.
    800  * @return Error code.
    801  *
    802  */
    803 int jmi_ode_f(jmi_t* jmi);
    804 
    805 /**
    806  * \brief Evaluate the Jacobian of the right hand side of the ODE.
    807  *
    808  * The user sets the input variables by writing to
    809  * the vectors obtained from the functions ::jmi_get_x, ::jmi_get_u etc.
    810  *
    811  * @param jmi A jmi_t struct.
    812  * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
    813  *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
    814  * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
    815  *                to indicate the output format of the Jacobian.
    816  * @param independent_vars Used to indicate which columns of the full Jacobian should
    817  *                         be evaluated. The constants JMI_DER_X, JMI_DER_DX etc are used
    818  *                         to set this argument. Setting independent_vars to
    819  *                         JMI_DER_DX has no effect.
    820  * @param mask This argument is a vector containing ones for the Jacobian columns that
    821  *             should be included in the Jacobian and zeros for those which should not.
    822  *             The size of this vector is the same as the z vector.
    823  * @param jac (Output) The Jacobian.
    824  * @return Error code.
    825  *
    826  */
    827 int jmi_ode_df(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);
    828 
    829 /**
    830  * \brief Returns the number of non-zeros in the Jacobian of the right hand
    831  * side of the ODE.
    832  *
    833  * @param jmi A jmi_t struct.
    834  * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
    835  *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
    836  * @param n_nz (Output) The number of non-zero Jacobian entries.
    837  * @return Error code.
    838  */
    839 int jmi_ode_df_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);
    840 
    841 /**
    842  * \brief Returns the row and column indices of the non-zero elements in the
    843  * Jacobian of the right hand side.
    844  *
    845  * Notice that Fortran style indexing is used: the first row (and column) has index 1.
    846  *
    847  * @param jmi A jmi_t struct.
    848  * @param eval_alg See ::jmi_dae_dF.
    849  * @param independent_vars See ::jmi_dae_dF.
    850  * @param mask See ::jmi_dae_dF.
    851  * @param row (Output) The row indices of the non-zeros in the Jacobian.
    852  * @param col (Output) The column indices of the non-zeros in the Jacobian.
    853  * @return Error code.
    854  *
    855  */
    856 int jmi_ode_df_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    857                           int *mask, int* row, int* col);
    858 
    859 /**
    860  * \brief This helper function computes the number of columns and the number of non zero
    861  * elements in the Jacobian of the right hand side of the ODE given a sparsity configuration.
    862  *
    863  * @param jmi A jmi_t struct.
    864  * @param eval_alg See ::jmi_dae_dF.
    865  * @param sparsity See ::jmi_dae_dF.
    866  * @param independent_vars See ::jmi_dae_dF.
    867  * @param mask See ::jmi_dae_dF.
    868  * @param df_n_cols (Output) The number of columns of the resulting Jacobian.
    869  * @param df_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    870  *
    871  */
    872 int jmi_ode_df_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    873         int *df_n_cols, int *df_n_nz);
     514/**
     515 * \brief Call a jmi_generic_func_t, and handle exceptions and setting the current jmi_t pointer.
     516 */
     517int jmi_generic_func(jmi_t *jmi, jmi_generic_func_t func);
    874518
    875519/**
     
    888532 * @return Error code.
    889533 */
    890 int jmi_ode_derivatives_dir_der(jmi_t* jmi, jmi_real_t* dv);
    891 
    892 /**
    893  * \brief Evaluate the ODE outputs.
    894  *
    895  * @param jmi A jmi_t struct.
    896  * @return Error code.
    897  */
    898 int jmi_ode_outputs(jmi_t* jmi);
     534int jmi_ode_derivatives_dir_der(jmi_t* jmi);
    899535
    900536/**
     
    907543
    908544/**
    909  * \brief Evaluate the DAE guard expressions
    910  *
    911  * @param jmi A jmi_t struct.
    912  * @return Error code.
    913  */
    914 int jmi_ode_guards(jmi_t* jmi);
    915 
    916 /**
    917  * \brief Evaluate the initial equation guard expressions
    918  *
    919  * @param jmi A jmi_t struct.
    920  * @return Error code.
    921  */
    922 int jmi_ode_guards_init(jmi_t* jmi);
    923 
    924 /**
    925545 * \brief Computes the next time event.
    926546 *
     
    930550 */
    931551int jmi_ode_next_time_event(jmi_t* jmi, jmi_time_event_t* event);
    932 
    933 
    934 /* @} */
    935 
    936 /*********************************************
    937  *
    938  * DAE interface
    939  *
    940  ********************************************/
    941 
    942 /**
    943  * \defgroup DAE DAE interface
    944  * \brief Access to the DAE residual function.
    945  *
    946  */
    947 /* @{ */
    948 
    949 
    950 /**
    951  * \brief Get the number of equations of the DAE and the number of event
    952  * indicator residuals.
    953  *
    954  * @param jmi A jmi_t struct.
    955  * @param n_eq_F (Output) The number of DAE equations is stored in this
    956  * argument.
    957  * @param n_eq_R (Output) The number of DAE event indicator residuals is
    958  * stored in this argument.
    959  * @return Error code.
    960  */
    961 int jmi_dae_get_sizes(jmi_t* jmi, int* n_eq_F, int* n_eq_R);
    962 
    963 
    964 /**
    965  * \brief Evaluate DAE residual.
    966  *
    967  * The user sets the input variables by writing to
    968  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    969  *
    970  * @param jmi A jmi_t struct.
    971  * @param res (Output) The DAE residual vector.
    972  * @return Error code.
    973  *
    974  */
    975 int jmi_dae_F(jmi_t* jmi, jmi_real_t* res);
    976 
    977 /**
    978  * \brief Evaluate the Jacobian of the DAE residual function.
    979  *
    980  * The user sets the input variables by writing to
    981  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    982  *
    983  * @param jmi A jmi_t struct.
    984  * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
    985  *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
    986  * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
    987  *                to indicate the output format of the Jacobian.
    988  * @param independent_vars Used to indicate which columns of the full Jacobian should
    989  *                         be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used
    990  *                         to set this argument.
    991  * @param mask This argument is a vector containing ones for the Jacobian columns that
    992  *             should be included in the Jacobian and zeros for those which should not.
    993  *             The size of this vector is the same as the z vector.
    994  * @param jac (Output) The Jacobian.
    995  * @return Error code.
    996  *
    997  */
    998 int jmi_dae_dF(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);
    999 
    1000 /**
    1001  * \brief Returns the number of non-zeros in the full DAE residual Jacobian.
    1002  *
    1003  * @param jmi A jmi_t struct.
    1004  * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
    1005  *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
    1006  * @param n_nz (Output) The number of non-zero Jacobian entries.
    1007  * @return Error code.
    1008  */
    1009 int jmi_dae_dF_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);
    1010 
    1011 /**
    1012  * \brief Returns the row and column indices of the non-zero elements in the DAE
    1013  * residual Jacobian.
    1014  *
    1015  * Notice that Fortran style indexing is used: the first row (and column) has index 1.
    1016  *
    1017  * @param jmi A jmi_t struct.
    1018  * @param eval_alg See ::jmi_dae_dF.
    1019  * @param independent_vars See ::jmi_dae_dF.
    1020  * @param mask See ::jmi_dae_dF.
    1021  * @param row (Output) The row indices of the non-zeros in the DAE residual Jacobian.
    1022  * @param col (Output) The column indices of the non-zeros in the DAE residual Jacobian.
    1023  * @return Error code.
    1024  *
    1025  */
    1026 int jmi_dae_dF_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    1027                           int *mask, int* row, int* col);
    1028 
    1029 /**
    1030  * \brief This helper function computes the number of columns and the number of non zero
    1031  * elements in the Jacobian of the DAE residual given a sparsity configuration.
    1032  *
    1033  * @param jmi A jmi_t struct.
    1034  * @param eval_alg See ::jmi_dae_dF.
    1035  * @param sparsity See ::jmi_dae_dF.
    1036  * @param independent_vars See ::jmi_dae_dF.
    1037  * @param mask See ::jmi_dae_dF.
    1038  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    1039  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    1040  *
    1041  */
    1042 int jmi_dae_dF_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    1043         int *dF_n_cols, int *dF_n_nz);
    1044 
    1045 /**
    1046  * \brief Evaluate the directional derivative of the DAE residual function.
    1047  *
    1048  * The directional derivative is defined as
    1049  *
    1050  *   dF = dF/dz * dz
    1051  *
    1052  * where dF/dz is the Jacobian of the residual function F, dF
    1053  * is the directional derivative and dz is the seed vector.
    1054  *
    1055  * The user sets the input variables by writing to
    1056  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    1057  *
    1058  * @param jmi A jmi_t struct.
    1059  * @param eval_alg int
    1060  * @param res (Output) The DAE residual vector.
    1061  * @param dF (Output) The directional derivative.
    1062  * @param dz Seed vector of size n_x + n_x + n_u + n_w.
    1063  * @return Error code.
    1064  *
    1065  */
    1066 int jmi_dae_directional_dF(jmi_t* jmi, int eval_alg, jmi_real_t* res, jmi_real_t* dF, jmi_real_t* dz);
    1067552
    1068553/**
     
    1094579
    1095580/**
    1096  * \brief Compare the evaluated CAD derivative with the FD evaluation
    1097  *
    1098  * @param jmi A jmi_t struct.
    1099  * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
    1100  *                to indicate the output format of the Jacobian.
    1101  * @param independent_vars Used to indicate which columns of the full Jacobian should
    1102  *                         be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used
    1103  *                         to set this argument.
    1104  * @param screen_use Set the flag to JMI_DER_CHECK_SCREEN_ON to print the result of the comparasion on the screen
    1105  *             or JMI_DER_CHECK_SCREEN_OFF to return -1 if the comparasion failes.
    1106  * @param mask This argument is a vector containing ones for the Jacobian columns that
    1107  *             should be included in the Jacobian and zeros for those which should not.
    1108  *             The size of this vector is the same as the z vector.
    1109  * @return Error code.
    1110  *
    1111  */
    1112 int jmi_dae_derivative_checker(jmi_t* jmi, int sparsity, int independent_vars, int screen_use, int *mask);
    1113 
    1114 /* @} */
    1115 
    1116 /*********************************************
    1117  *
    1118  * Initialization interface
    1119  *
    1120  ********************************************/
    1121 
    1122 /**
    1123  * \defgroup Initialization DAE Initialization Interface
    1124  * \brief Access to the DAE initialization functions.
    1125  */
    1126 /* @{ */
    1127 
    1128 /**
    1129  * \brief Get the number of equations in the DAE initialization functions.
    1130  *
    1131  * @param jmi A jmi_t struct.
    1132  * @param n_eq_F0 (Output) The number of equations in \f$F_0\f$ is stored in this argument.
    1133  * @param n_eq_F1 (Output) The number of equations in \f$F_1\f$ is stored in this argument.
    1134  * @param n_eq_Fp (Output) The number of equations in \f$F_p\f$ is stored in this argument.
    1135  * @param n_eq_R0 (Output) The number of equations in \f$R_0\f$ is stored in this argument.
    1136  * @return Error code.
    1137  *
    1138  */
    1139 int jmi_init_get_sizes(jmi_t* jmi, int* n_eq_F0, int* n_eq_F1, int* n_eq_Fp,
    1140         int* n_eq_R0);
    1141 
    1142 /**
    1143  * \brief Evaluate the \f$F_0\f$ residual function of the initialization system.
    1144  *
    1145  * @param jmi A jmi_t struct.
    1146  * @param res The residual of \f$F_0\f$.
    1147  * @return Error code.
    1148  */
    1149 int jmi_init_F0(jmi_t* jmi, jmi_real_t* res);
    1150 
    1151 /**
    1152  * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_0\f$.
    1153  *
    1154  * The user sets the input variables by writing to
    1155  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    1156  *
    1157  * @param jmi A jmi_t struct.
    1158  * @param eval_alg See ::jmi_dae_dF.
    1159  * @param sparsity See ::jmi_dae_dF.
    1160  * @param independent_vars See ::jmi_dae_dF.
    1161  * @param mask See ::jmi_dae_dF.
    1162  * @param jac (Output) The Jacobian.
    1163  * @return Error code.
    1164  *
    1165  */
    1166 int jmi_init_dF0(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);
    1167 
    1168 /**
    1169  * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_0\f$.
    1170  *
    1171  * @param jmi A jmi_t struct.
    1172  * @param eval_alg See ::jmi_dae_dF_n_nz.
    1173  * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
    1174  * @return Error code.
    1175  */
    1176 int jmi_init_dF0_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);
    1177 
    1178 /**
    1179  * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
    1180  * initialization residual function \f$F_0\f$.
    1181  *
    1182  * Notice that Fortran style indexing is used: the first row (and column) has index 1.
    1183  *
    1184  * @param jmi A jmi_t struct.
    1185  * @param eval_alg See ::jmi_dae_dF.
    1186  * @param independent_vars See ::jmi_dae_dF.
    1187  * @param mask See ::jmi_dae_dF.
    1188  * @param row (Output) The row indices of the non-zeros in the Jacobian.
    1189  * @param col (Output) The column indices of the non-zeros in the Jacobian.
    1190  * @return Error code.
    1191  *
    1192  */
    1193 int jmi_init_dF0_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    1194         int *mask, int* row, int* col);
    1195 
    1196 /**
    1197  * \brief This helper function computes the number of columns and the number of non-zero
    1198  * elements in the Jacobian of the DAE initialization residual function \f$F_0\f$ given
    1199  * a sparsity configuration.
    1200  *
    1201  * @param jmi A jmi_t struct.
    1202  * @param eval_alg See ::jmi_dae_dF.
    1203  * @param sparsity See ::jmi_dae_dF.
    1204  * @param independent_vars See ::jmi_dae_dF.
    1205  * @param mask See ::jmi_dae_dF.
    1206  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    1207  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    1208  *
    1209  */
    1210 int jmi_init_dF0_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    1211         int *dF_n_cols, int *dF_n_nz);
    1212 
    1213 /**
    1214  * \brief Evaluate the \f$F_1\f$ residual function of the initialization system.
    1215  *
    1216  * @param jmi A jmi_t struct.
    1217  * @param res The residual of \f$F_1\f$.
    1218  * @return Error code.
    1219  */
    1220 int jmi_init_F1(jmi_t* jmi, jmi_real_t* res);
    1221 
    1222 /**
    1223  * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_1\f$.
    1224  *
    1225  * The user sets the input variables by writing to
    1226  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    1227  *
    1228  * @param jmi A jmi_t struct.
    1229  * @param eval_alg See ::jmi_dae_dF.
    1230  * @param sparsity See ::jmi_dae_dF.
    1231  * @param independent_vars See ::jmi_dae_dF.
    1232  * @param mask See ::jmi_dae_dF.
    1233  * @param jac (Output) The Jacobian.
    1234  * @return Error code.
    1235  *
    1236  */
    1237 int jmi_init_dF1(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);
    1238 
    1239 /**
    1240  * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_1\f$.
    1241  *
    1242  * @param jmi A jmi_t struct.
    1243  * @param eval_alg See ::jmi_dae_dF_n_nz.
    1244  * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
    1245  * @return Error code.
    1246  */
    1247 int jmi_init_dF1_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);
    1248 
    1249 /**
    1250  * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
    1251  * initialization residual function \f$F_1\f$.
    1252  *
    1253  * Notice that Fortran style indexing is used: the first row (and column) has index 1.
    1254  *
    1255  * @param jmi A jmi_t struct.
    1256  * @param eval_alg See ::jmi_dae_dF.
    1257  * @param independent_vars See ::jmi_dae_dF.
    1258  * @param mask See ::jmi_dae_dF.
    1259  * @param row (Output) The row indices of the non-zeros in the Jacobian.
    1260  * @param col (Output) The column indices of the non-zeros in the Jacobian.
    1261  * @return Error code.
    1262  *
    1263  */
    1264 int jmi_init_dF1_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    1265         int *mask, int* row, int* col);
    1266 
    1267 /**
    1268  * \brief This helper function computes the number of columns and the number of non-zero
    1269  * elements in the Jacobian of the DAE initialization residual function \f$F_1\f$ given
    1270  * a sparsity configuration.
    1271  *
    1272  * @param jmi A jmi_t struct.
    1273  * @param eval_alg See ::jmi_dae_dF.
    1274  * @param sparsity See ::jmi_dae_dF.
    1275  * @param independent_vars See ::jmi_dae_dF.
    1276  * @param mask See ::jmi_dae_dF.
    1277  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    1278  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    1279  *
    1280  */
    1281 int jmi_init_dF1_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    1282         int *dF_n_cols, int *dF_n_nz);
    1283 
    1284 /**
    1285  * \brief Evaluate the \f$F_p\f$ residual function of the initialization system.
    1286  *
    1287  * @param jmi A jmi_t struct.
    1288  * @param res The residual of \f$F_p\f$.
    1289  * @return Error code.
    1290  */
    1291 int jmi_init_Fp(jmi_t* jmi, jmi_real_t* res);
    1292 
    1293 /**
    1294  * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_p\f$.
    1295  *
    1296  * The user sets the input variables by writing to
    1297  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    1298  *
    1299  * @param jmi A jmi_t struct.
    1300  * @param eval_alg See ::jmi_dae_dF.
    1301  * @param sparsity See ::jmi_dae_dF.
    1302  * @param independent_vars See ::jmi_dae_dF.
    1303  * @param mask See ::jmi_dae_dF.
    1304  * @param jac (Output) The Jacobian.
    1305  * @return Error code.
    1306  *
    1307  */
    1308 int jmi_init_dFp(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);
    1309 
    1310 /**
    1311  * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_p\f$.
    1312  *
    1313  * @param jmi A jmi_t struct.
    1314  * @param eval_alg See ::jmi_dae_dF_n_nz.
    1315  * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
    1316  * @return Error code.
    1317  */
    1318 int jmi_init_dFp_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);
    1319 
    1320 /**
    1321  * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
    1322  * initialization residual function \f$F_p\f$.
    1323  *
    1324  * Notice that Fortran style indexing is used: the first row (and column) has index 1.
    1325  *
    1326  * @param jmi A jmi_t struct.
    1327  * @param eval_alg See ::jmi_dae_dF.
    1328  * @param independent_vars See ::jmi_dae_dF.
    1329  * @param mask See ::jmi_dae_dF.
    1330  * @param row (Output) The row indices of the non-zeros in the Jacobian.
    1331  * @param col (Output) The column indices of the non-zeros in the Jacobian.
    1332  * @return Error code.
    1333  *
    1334  */
    1335 int jmi_init_dFp_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
    1336         int *mask, int* row, int* col);
    1337 
    1338 /**
    1339  * \brief This helper function computes the number of columns and the number of non-zero
    1340  * elements in the Jacobian of the DAE initialization residual function \f$F_p\f$ given
    1341  * a sparsity configuration.
    1342  *
    1343  * @param jmi A jmi_t struct.
    1344  * @param eval_alg See ::jmi_dae_dF.
    1345  * @param sparsity See ::jmi_dae_dF.
    1346  * @param independent_vars See ::jmi_dae_dF.
    1347  * @param mask See ::jmi_dae_dF.
    1348  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    1349  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    1350  *
    1351  */
    1352 int jmi_init_dFp_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
    1353         int *dF_n_cols, int *dF_n_nz);
    1354 
    1355 /**
    1356581 * \brief Evaluate the dependent parameters.
    1357582 *
     
    1360585 */
    1361586int jmi_init_eval_parameters(jmi_t* jmi);
    1362 
    1363 /**
    1364  * \brief Evaluate DAE event indicator residuals for the initialization system.
    1365  *
    1366  * The user sets the input variables by writing to
    1367  * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
    1368  *
    1369  * @param jmi A jmi_t struct.
    1370  * @param res (Output) The event indicator residuals.
    1371  * @return Error code.
    1372  *
    1373  */
    1374 int jmi_init_R0(jmi_t* jmi, jmi_real_t* res);
    1375587
    1376588/* @} */
     
    1381593 */
    1382594/* @{ */
    1383 
    1384 /**
    1385  * \brief Print a summary of the content of the jmi_t struct.
    1386  *
    1387  * @param jmi A jmi_t struct.
    1388  */
    1389 void jmi_print_summary(jmi_t *jmi);
    1390 
    1391 /**
    1392  * \brief Linear interpolation in table.
    1393  *
    1394  * Linear interpolation is performed in a table consisting of an abscissa and
    1395  * one or more ordinates. If the interpolation point resides outside of the
    1396  * interval of the provided abscissa, then the initial or final ordinate
    1397  * values, respectively, are returned.
    1398  *
    1399  * @param x The interpolation point.
    1400  * @param z A matrix stored in column major format containing the abscissa,
    1401  * stored in the first column, and the ordinates, stored in the following
    1402  * columns.
    1403  * @param n Number of points in the abscissa vector.
    1404  * @param m Number of columns of z, i.e., the number of ordinate vectors plus
    1405  * one for the abscissa.
    1406  * @param y (Output) A vector of size m-1 containing the interpolated ordinate
    1407  * values.
    1408  */
    1409 void jmi_lin_interpolate(jmi_real_t x, jmi_real_t *z , int n ,int m,
    1410         jmi_real_t *y);
    1411 
    1412 /**
    1413  * \brief Check if there is support for CAD derivatives or not.
    1414  *
    1415  * If the return value is 1 then there is support for CAD derivatives,
    1416  * if return value is 0 there is no CAD support.
    1417  *
    1418  * @param jmi A jmi_t struct.
    1419  *
    1420  * @return 1 for CAD support, 0 if no CAD support.
    1421  */
    1422 int jmi_with_cad_derivatives(jmi_t* jmi);
    1423595
    1424596/**
  • trunk/RuntimeLibrary/src/jmi/jmi_block_residual.c

    r8873 r8993  
    544544            block->nr_vref[i] =  (jmi_int_t)nr_vref_tmp[i];
    545545            /* Get index for non-reals from their valuereference */
    546             block->nr_index[i] = get_index_from_value_ref(block->nr_vref[i]);
     546            block->nr_index[i] = jmi_get_index_from_value_ref(block->nr_vref[i]);
    547547           
    548548            type = jmi_get_type_from_value_ref(block->nr_vref[i]);
     
    558558        for (i = 0; i < block->n_dr; i++) {
    559559            block->dr_vref[i] = (jmi_int_t)dr_vref_tmp[i];
    560             block->dr_index[i] = get_index_from_value_ref(block->dr_vref[i]);
     560            block->dr_index[i] = jmi_get_index_from_value_ref(block->dr_vref[i]);
    561561            /* Initialize discrete real nominal vector */
    562562            block->discrete_nominals[i] = 1;
     
    572572         for (i = 0; i < block->n_direct_nr; i++) {
    573573             /* Get index for non-reals from their valuereference */
    574              block->nr_direct_index[i] = get_index_from_value_ref(nr_vref_tmp[i]);
     574             block->nr_direct_index[i] = jmi_get_index_from_value_ref(nr_vref_tmp[i]);
    575575             
    576              if (get_type_from_value_ref(nr_vref_tmp[i]) == JMI_BOOLEAN) {
    577                  block->bool_direct_index[j] = get_index_from_value_ref(nr_vref_tmp[i]);
     576             if (jmi_get_type_from_value_ref(nr_vref_tmp[i]) == JMI_BOOLEAN) {
     577                 block->bool_direct_index[j] = jmi_get_index_from_value_ref(nr_vref_tmp[i]);
    578578                 block->n_direct_bool++;
    579579                 j++;
  • trunk/RuntimeLibrary/src/jmi/jmi_cs.c

    r8984 r8993  
    2828    int is_integer_input, is_boolean_input;
    2929   
    30     z_index = get_index_from_value_ref(valueref[i]);
     30    z_index = jmi_get_index_from_value_ref(valueref[i]);
    3131    is_integer_input = (z_index >= jmi->offs_integer_u && z_index < jmi->offs_boolean_d);
    3232    is_boolean_input = (z_index >= jmi->offs_boolean_u && z_index < jmi->offs_sw);
  • trunk/RuntimeLibrary/src/jmi/jmi_global.c

    r8825 r8993  
    2828#include "jmi_global.h"
    2929#include "jmi_log.h"
    30 #include "jmi_util.h"
     30#include "jmi.h"
    3131
    3232
  • trunk/RuntimeLibrary/src/jmi/jmi_global.h

    r8825 r8993  
    2929#include <setjmp.h>
    3030
    31 #include "jmi_util.h"
     31#include "jmi.h"
    3232
    3333
  • trunk/RuntimeLibrary/src/jmi/jmi_me.c

    r8979 r8993  
    2424#include "module_include/jmi_get_set.h"
    2525
    26 #define indexmask  0x07FFFFFF
    27 #define negatemask 0x08000000
    28 #define typemask   0xF0000000
    29 
    30 jmi_value_reference get_index_from_value_ref(jmi_value_reference valueref) {
    31     /* Translate a ValueReference into variable index in z-vector. */
    32     jmi_value_reference index = valueref & indexmask;
    33    
    34     return index;
    35 }
    36 
    37 jmi_value_reference get_type_from_value_ref(jmi_value_reference valueref) {
    38     /* Translate a ValueReference into variable type in z-vector. */
    39     jmi_value_reference type = valueref & typemask;
    40    
    41     return type;
    42 }
    43 
    44 jmi_value_reference is_negated(jmi_value_reference valueref) {
    45     /* Checks for a valueReference if it is negated. */
    46     jmi_value_reference negated = valueref & negatemask;
    47    
    48     return negated;
    49 }
     26
    5027
    5128int jmi_me_init(jmi_callbacks_t* jmi_callbacks, jmi_t* jmi, jmi_string GUID, jmi_string_t resource_location) {
     
    9875    /* Write start values to the pre vector*/
    9976    jmi_copy_pre_values(jmi);
    100    
    101     /* Print some info about Jacobians, if available. */
    102     if (jmi_->color_info_A != NULL) {
    103         jmi_log_node_t node = jmi_log_enter(jmi_->log, logInfo, "color_info_A");
    104         jmi_log_fmt(jmi_->log, node, logInfo, "<num_nonzeros: %d> in Jacobian A", jmi_->color_info_A->n_nz);
    105         jmi_log_fmt(jmi_->log, node, logInfo, "<num_colors: %d> in Jacobian A", jmi_->color_info_A->n_groups);
    106         jmi_log_leave(jmi_->log, node);
    107     }
    108 
    109     if (jmi_->color_info_B != NULL) {
    110         jmi_log_node_t node = jmi_log_enter(jmi_->log, logInfo, "color_info_B");
    111         jmi_log_fmt(jmi_->log, node, logInfo, "<num_nonzeros: %d> in Jacobian B", jmi_->color_info_B->n_nz);
    112         jmi_log_fmt(jmi_->log, node, logInfo, "<num_colors: %d> in Jacobian B", jmi_->color_info_B->n_groups);
    113         jmi_log_leave(jmi_->log, node);
    114     }
    115 
    116     if (jmi_->color_info_C != NULL) {
    117         jmi_log_node_t node = jmi_log_enter(jmi_->log, logInfo, "color_info_C");
    118         jmi_log_fmt(jmi_->log, node, logInfo, "<num_nonzeros: %d> in Jacobian C", jmi_->color_info_C->n_nz);
    119         jmi_log_fmt(jmi_->log, node, logInfo, "<num_colors: %d> in Jacobian C", jmi_->color_info_C->n_groups);
    120         jmi_log_leave(jmi_->log, node);
    121     }
    122 
    123     if (jmi_->color_info_D != NULL) {
    124         jmi_log_node_t node = jmi_log_enter(jmi_->log, logInfo, "color_info_D");
    125         jmi_log_fmt(jmi_->log, node, logInfo, "<num_nonzeros: %d> in Jacobian D", jmi_->color_info_D->n_nz);
    126         jmi_log_fmt(jmi_->log, node, logInfo, "<num_colors: %d> in Jacobian D", jmi_->color_info_D->n_groups);
    127         jmi_log_leave(jmi_->log, node);
    128     }
    12977   
    13078    return 0;
     
    258206    for (i = 0; i < nvr; i = i + 1) {
    259207        /* Get index in z vector from value reference. */
    260         index = get_index_from_value_ref(vr[i]);
     208        index = jmi_get_index_from_value_ref(vr[i]);
    261209        if (index >= start && index < end) {
    262210            jmi_log_node(jmi->log, logError, "CannotSetVariable",
     
    406354
    407355    for (i = 0; i < nKnown; i++) {
    408         jmi->dz_active_variables[0][get_index_from_value_ref(vKnown_ref[i])-jmi->offs_real_dx] = dvKnown[i];
    409     }
    410 
    411     ef = jmi_generic_func(jmi, jmi->dae->ode_derivatives_dir_der);
     356        jmi->dz_active_variables[0][jmi_get_index_from_value_ref(vKnown_ref[i])-jmi->offs_real_dx] = dvKnown[i];
     357    }
     358
     359    ef = jmi_ode_derivatives_dir_der(jmi);
    412360    for (i = 0; i < nUnknown; i++) {
    413         dvUnknown[i] = jmi->dz_active_variables[0][get_index_from_value_ref(vUnknown_ref[i])-jmi->offs_real_dx];
     361        dvUnknown[i] = jmi->dz_active_variables[0][jmi_get_index_from_value_ref(vUnknown_ref[i])-jmi->offs_real_dx];
    414362    }
    415363
     
    704652        jmi->atEvent = JMI_FALSE;
    705653
    706         /* Deprecated, does nothing. */
    707         retval = jmi_ode_guards(jmi);
    708         if (retval != 0) { /* Error check */
    709             jmi_log_comment(jmi->log, logError, "Computation of guard expressions failed.");
    710             jmi_log_unwind(jmi->log, top_node);
    711             return -1;
    712         }
    713 
    714654        /* Final evaluation of the model with event flag set to false. It can
    715655         * for example change values of booleans that should only be true during
     
    857797}
    858798
    859 static int get_option_index(char* option) {
     799static unsigned int get_option_index(char* option) {
    860800    const char** found=(const char**)bsearch(&option,
    861801                                             fmi_runtime_options_map_names,
     
    868808    if(index >= fmi_runtime_options_map_length ) return 0;
    869809    vr = fmi_runtime_options_map_vrefs[index];
    870     return get_index_from_value_ref(vr);
     810    return jmi_get_index_from_value_ref(vr);
    871811}
    872812
  • trunk/RuntimeLibrary/src/jmi/jmi_me.h

    r8979 r8993  
    2727#include "jmi_math.h"
    2828#include "jmi_types.h"
    29 
    30 typedef unsigned int jmi_value_reference;
    3129
    3230typedef struct jmi_event_info_t jmi_event_info_t;
     
    6563 */
    6664extern const int fmi_runtime_options_map_length;
    67 
    68 jmi_value_reference get_index_from_value_ref(jmi_value_reference valueref); /* TODO: should be static later on if possible */
    69    
    70 jmi_value_reference get_type_from_value_ref(jmi_value_reference valueref); /* TODO: should be static later on if possible */
    71 
    72 jmi_value_reference is_negated(jmi_value_reference valueref);
    7365
    7466int jmi_me_init(jmi_callbacks_t* cb, jmi_t* jmi, jmi_string GUID, jmi_string_t resource_location);
  • trunk/RuntimeLibrary/src/jmi/jmi_ode_solver.h

    r8177 r8993  
    4747typedef void (*jmi_ode_delete_func_t)(jmi_ode_solver_t* block);
    4848
    49 
     49typedef enum {
     50    JMI_ODE_CVODE,
     51    JMI_ODE_EULER
     52} jmi_ode_method_t;
    5053
    5154struct jmi_ode_solver_t {
  • trunk/RuntimeLibrary/src/jmi/jmi_types.h

    r8972 r8993  
    4343/* Forward declaration of jmi structs */
    4444typedef struct jmi_t jmi_t;                                         /**< \brief Forward declaration of struct. */
    45 typedef struct jmi_dae_t jmi_dae_t;                                 /**< \brief Forward declaration of struct. */
    46 typedef struct jmi_init_t jmi_init_t;                               /**< \brief Forward declaration of struct. */
     45typedef struct jmi_model_t jmi_model_t;                             /**< \brief Forward declaration of struct. */
    4746typedef struct jmi_func_t jmi_func_t;                               /**< \brief Forward declaration of struct. */
    4847typedef struct jmi_block_residual_t jmi_block_residual_t;           /**< \brief Forward declaration of struct. */
     
    180179#define FALSE 0
    181180
    182 #define JMI_REAL    0x00000000
    183 #define JMI_INTEGER 0x10000000
    184 #define JMI_BOOLEAN 0x20000000
     181typedef enum {
     182    JMI_REAL,
     183    JMI_INTEGER,
     184    JMI_BOOLEAN,
     185    JMI_STRING
     186} jmi_type_t;
    185187
    186188typedef char jmi_boolean;
    187189typedef const char* jmi_string;
     190typedef unsigned int jmi_value_reference;
    188191
    189192#endif
  • trunk/RuntimeLibrary/src/jmi/jmi_util.c

    r8679 r8993  
    5151}
    5252
    53 
    54 int jmi_func_new(jmi_func_t** jmi_func, jmi_residual_func_t F, int n_eq_F, jmi_jacobian_func_t sym_dF,
    55         int sym_dF_n_nz, int* sym_dF_row, int* sym_dF_col,jmi_directional_der_residual_func_t cad_dir_dF,
    56         int cad_dF_n_nz, int* cad_dF_row, int* cad_dF_col) {
    57 
    58     int i;
    59     /*jmi_color_info* c_i_temp;*/
    60    
    61     jmi_func_t* func = (jmi_func_t*)calloc(1,sizeof(jmi_func_t));
    62     *jmi_func = func;
    63 
    64     func->n_eq_F = n_eq_F;
    65     func->F = F;
    66     func->sym_dF = sym_dF;
    67     func->cad_dir_dF = cad_dir_dF;
    68 
    69     func->sym_dF_n_nz = sym_dF_n_nz;
    70     func->sym_dF_row = (int*)calloc(sym_dF_n_nz,sizeof(int));
    71     func->sym_dF_col = (int*)calloc(sym_dF_n_nz,sizeof(int));
    72 
    73     for (i=0;i<sym_dF_n_nz;i++) {
    74         func->sym_dF_row[i] = sym_dF_row[i];
    75         func->sym_dF_col[i] = sym_dF_col[i];
    76     }
    77 
    78     func->cad_dF_n_nz = cad_dF_n_nz;
    79     func->cad_dF_row = (int*)calloc(cad_dF_n_nz,sizeof(int));
    80     func->cad_dF_col = (int*)calloc(cad_dF_n_nz,sizeof(int));
    81 
    82     for (i=0;i<cad_dF_n_nz;i++) {
    83         func->cad_dF_row[i] = cad_dF_row[i];
    84         func->cad_dF_col[i] = cad_dF_col[i];
    85         /* printf("* %d %d \n",func->cad_dF_row[i], func->cad_dF_col[i]);*/
    86     }
    87    
    88     func->coloring_counter = 0;
    89     func->coloring_done = (int*)calloc(64, sizeof(int));
    90     func->c_info = (jmi_color_info**)calloc(64, sizeof(jmi_color_info*));
    91    
    92     for(i = 0; i < 64; i++){
    93         func->coloring_done[i] = 0;
    94         func->c_info[i] = (jmi_color_info*)malloc(sizeof(jmi_color_info));
    95     }
    96 
    97     return 0;
    98 }
    99 
    100 int jmi_func_delete(jmi_func_t *func) {
    101     int i;
    102     int flag = 0;
    103 
    104     free(func->sym_dF_row);
    105     free(func->sym_dF_col);
    106     free(func->cad_dF_row);
    107     free(func->cad_dF_col);
    108     for(i = 0; i < 64; i++){
    109         if(func->coloring_done[i] == 1){
    110             flag = jmi_delete_color_info(func->c_info[i]);
    111         }
    112         free(func->c_info[i]);
    113     }
    114     free(func->c_info);
    115     free(func->coloring_done);
    116     free(func);
    117     return flag;
    118 }
    119 
    120 /* Convenience function to evaluate the Jacobian of the function contained in a
    121  jmi_func_t. */
    122 int jmi_func_sym_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    123         int independent_vars, int* mask, jmi_real_t* jac) {
    124     int return_status;
    125     int depth;
    126 
    127     if (func->sym_dF==NULL) {
    128         return -1;
    129     }
    130     depth = jmi_prepare_try(jmi);
    131     if (jmi_try(jmi,depth))
    132         return_status = -1;
    133     else
    134         return_status = func->sym_dF(jmi, sparsity, independent_vars, mask, jac);
    135     jmi_finalize_try(jmi, depth);
    136     return return_status;
    137 
    138 }
    139 
    140 /* Convenience function for accessing the number of non-zeros in the (symbolic)
    141  Jacobian. */
    142 int jmi_func_sym_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz) {
    143     if (func->sym_dF==NULL) {
    144         *n_nz = 0;
    145         return -1;
    146     }
    147     *n_nz = func->sym_dF_n_nz;
    148     return 0;
    149 }
    150 
    151 /* Convenience function of accessing the non-zeros in the Jacobian */
    152 int jmi_func_sym_dF_nz_indices(jmi_t *jmi, jmi_func_t *func, int independent_vars,
    153                            int *mask,int *row, int *col) {
    154     int i;
    155     int index;
    156    
    157     if (func->sym_dF==NULL) {
    158         return -1;
    159     }
    160 
    161 /*  int col_index = 0;*/           /* Column index of the new Jacobian*/
    162 /*  int col_index_old = 0;*/       /* Temporary variable to keep track of when to increase col_index*/
    163     index = 0;                 /* Index in the row/col vectors of the new Jacobian */
    164 
    165     /* Iterate over all non-zero indices */
    166     for (i=0;i<func->sym_dF_n_nz;i++) {
    167 /*      printf("%d %d\n",i,jmi_check_Jacobian_column_index(jmi, independent_vars, mask, func->dF_col[i]-1)); */
    168         /* Check if this particular entry should be included */
    169         if (jmi_check_Jacobian_column_index(jmi, independent_vars, mask, func->sym_dF_col[i]-1) == 1 ) {
    170                 /* Copy indices */
    171                 row[index] = func->sym_dF_row[i];
    172                 col[index] = jmi_map_Jacobian_column_index(jmi,independent_vars,mask,func->sym_dF_col[i]-1) + 1;
    173                 index++;
    174         }
    175     }
    176 
    177     return 0;
    178 
    179 }
    180 
    181 /* Convenience function for computing the dimensions of the Jacobian. */
    182 int jmi_func_sym_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity, int independent_vars, int *mask,
    183         int *dF_n_cols, int *dF_n_nz) {
    184     int i;
    185    
    186     *dF_n_cols = 0;
    187     *dF_n_nz = 0;
    188 
    189     if (func->sym_dF==NULL) {
    190         return -1;
    191     }
    192 
    193     for (i=0;i<jmi->n_z;i++) {
    194         if (jmi_check_Jacobian_column_index(jmi, independent_vars, mask, i) == 1 ) {
    195             (*dF_n_cols)++;
    196         }
    197     }
    198 
    199     if (sparsity == JMI_DER_SPARSE) {
    200         for (i=0;i<func->sym_dF_n_nz;i++) {
    201 /*          printf(">>>>>>>>>>>>>>>>>>\n"); */
    202             /* Check if this particular entry should be included */
    203             if (jmi_check_Jacobian_column_index(jmi, independent_vars, mask, func->sym_dF_col[i]-1) == 1 ) {
    204                 (*dF_n_nz)++;
    205             }
    206         }
    207     } else {
    208         *dF_n_nz = *dF_n_cols*func->n_eq_F;
    209     }
    210 
    211     return 0;
    212 
    213 }
    214 
    215 int jmi_func_sym_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    216              jmi_real_t *dF, jmi_real_t* dv) {
    217         return -1; 
    218 }
    219 
    220 int jmi_func_cad_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    221         int independent_vars, int* mask, jmi_real_t* jac) {
    222    
    223     int i;
    224     int j;
    225     int k;
    226     int l;
    227     int flag = 0;
    228     int c_index;
    229    
    230     int dF_n_cols;
    231     int dF_n_nz;
    232     int n_colors;
    233     int dF_n_eq = 0;
    234    
    235     int max_columns;
    236     int *row_offs;
    237     int *dF_row;
    238     int *dF_col;
    239     int *dF_col_independent_ind;
    240     int *offs;
    241     int *sparse_repr;
    242     int *map_info;
    243     int *map_off;
    244     jmi_real_t *res;
    245     jmi_real_t *dF;
    246     jmi_real_t *dv;
    247     jmi_color_info* c_i;
    248 
    249 
    250     max_columns  = func->cad_dF_col[func->cad_dF_n_nz-1]+1;
    251 
    252     /*Get number of columns and number of non-zeros, for the specific value of the independent_vars flag*/ 
    253     jmi_func_cad_dF_dim(jmi, func, sparsity, independent_vars, mask, &dF_n_cols, &dF_n_nz);
    254 
    255     row_offs = (int*)calloc(dF_n_cols, sizeof(int));
    256     dF_row = (int*)calloc(dF_n_nz, sizeof(int));
    257     dF_col = (int*)calloc(dF_n_nz, sizeof(int));
    258     dF_col_independent_ind = (int*)calloc(dF_n_nz,sizeof(int));
    259 
    260     /*Get vectors with new row and column indices, depending on independent_vars*/ 
    261     jmi_func_cad_dF_nz_indices(jmi, func, independent_vars, mask, dF_row, dF_col);
    262    
    263     /*The difference between dF_col_independent_ind and dF_col is that in dF_col_independent_ind,
    264     the old indices are given, for those variables that are present (In dF_col the indices are shifted)*/
    265     jmi_func_cad_dF_get_independent_ind(jmi, func, independent_vars, dF_col_independent_ind);
    266    
    267     /*Set offset vector, which contains information about on which index a new column starts*/
    268     j = 0;
    269     for(i = 0; i < dF_n_nz; i++){
    270         if(dF_col[i] == j){
    271             row_offs[j] = i;
    272             j++;
    273         }
    274     }
    275    
    276     /*Here is a hack to handle JMI_DER_P_OPT as 32 instead of the orgingal value 8192. Then the
    277     bitmask value can be used as storage index of the graph coloring result*/   
    278     c_index = 0;
    279     if(independent_vars & JMI_DER_P_OPT){
    280         c_index+=32;
    281     }
    282     c_index+=independent_vars>>4;
    283    
    284     /*If no graph coloring result is stored for the value of independent_vars, the run graph coloring algorithm and
    285     store the result, coloring done contains information if the result is stored or not. func->c_info contains the
    286     graph coloring result. c_i is a struct that contains one specific graph coloring result*/
    287     if(func->coloring_done[c_index] != 1){
    288         func->coloring_done[c_index] = 1;
    289         flag = jmi_new_color_info(&c_i, dF_n_cols, dF_n_nz);
    290         jmi_dae_cad_color_graph(jmi, func, dF_n_cols, dF_n_nz, &dF_row[0], &dF_col[0], c_i->sparse_repr, c_i->offs, &n_colors, c_i->map_info, c_i->map_off);
    291         c_i->n_colors = n_colors;
    292         func->c_info[c_index] = c_i;
    293     } else{
    294         c_i = func->c_info[c_index];
    295     }
    296 
    297     /*Extract graph coloring information:
    298     sparse_repr is a vector containg a several numbers of sub vectors, for which every
    299     vector contains the indices that corresponds to one color.
    300     offs is an offset vector used to know where each subvector in sparse_repr starts.
    301     map_info contains several vectors (One vector for each color), every vector contains the row indices which
    302     corresponds to none zeros.
    303     map_off is an offset vector that corresponds to map_info.
    304     n_colors is the number of colors used.*/
    305      
    306     sparse_repr = c_i->sparse_repr;
    307     offs = c_i->offs;
    308     map_info = c_i->map_info;
    309     map_off = c_i->map_off;
    310     n_colors = c_i->n_colors;
    311 
    312     /*Extract number of equations*/
    313     for(i = 0; i < func->cad_dF_n_nz;i++){
    314         if(func->cad_dF_row[i] > dF_n_eq){
    315             dF_n_eq = func->cad_dF_row[i];
    316         }
    317     }
    318     dF_n_eq++;
    319    
    320     res = (jmi_real_t*)calloc(dF_n_eq, sizeof(jmi_real_t));
    321     dF = (jmi_real_t*)calloc(dF_n_eq, sizeof(jmi_real_t));
    322     dv = (jmi_real_t*)calloc(max_columns, sizeof(jmi_real_t));
    323     for(i = 0; i < max_columns;i++){
    324         dv[i] = 0;
    325     }
    326     for(i = 0; i < dF_n_eq;i++){
    327         dF[i] = 0;
    328         res[i] = 0;
    329     }
    330    
    331     if(sparsity & JMI_DER_SPARSE){
    332         for(i = 0; i < dF_n_nz; i++){
    333             jac[i] = 0;
    334         }
    335     } else if(sparsity & JMI_DER_DENSE_COL_MAJOR){
    336         for(i = 0; i < dF_n_eq*dF_n_cols; i++){
    337             jac[i] = 0;
    338         }
    339     } else if(sparsity & JMI_DER_DENSE_ROW_MAJOR){
    340         for(i = 0; i < dF_n_eq*dF_n_cols; i++){
    341             jac[i] = 0;
    342         }
    343     } else{
    344         return -1;
    345     }
    346    
    347     /*For every color...*/
    348     for(i = 0; i < n_colors; i++){
    349        
    350         /*max_1: how many columns corresponds to the color?*/
    351         int max_1 = 0;
    352        
    353         if(i != n_colors-1){
    354             max_1 = offs[i+1];
    355         }else{
    356             max_1 = dF_n_cols;
    357         }
    358        
    359         /*The seed vector dv is set to 1 on indices that corresponds to the color*/
    360         for(j = offs[i]; j < max_1;j++){
    361             dv[dF_col_independent_ind[row_offs[sparse_repr[j]]]] = 1;
    362         }
    363        
    364         /*Evaluate directional derivative*/
    365         jmi_func_cad_directional_dF(jmi, jmi->dae->F, res, dF, dv);
    366        
    367         /*For every column that corresponds to one color...*/
    368         for(j = offs[i]; j < max_1;j++){
    369            
    370             /*max_2: End index of the column*/
    371             int max_2 = 0; 
    372             if(j != dF_n_cols - 1){
    373                 max_2 = map_off[j+1];
    374             } else{
    375                 max_2 = dF_n_nz;
    376             }
    377            
    378             /*For every non zero element in the column...*/
    379             for(k = map_off[j]; k < max_2; k++){
    380                 /*Extract column and row index for this jacobian element this_value*/
    381                 int this_column = sparse_repr[j];
    382                 int this_row = map_info[k];
    383                 jmi_real_t this_value = dF[map_info[k]];
    384                
    385                 /*insert Jacobian value on correct index depending on sparsity representation*/
    386                 if(sparsity & JMI_DER_SPARSE){
    387                     l = row_offs[this_column];
    388                     while(dF_row[l] != this_row){
    389                         l++;
    390                     }
    391                     jac[l] = this_value;
    392                 } else if(sparsity & JMI_DER_DENSE_COL_MAJOR){
    393                     jac[dF_n_eq*this_column+this_row] = this_value;
    394                 } else if(sparsity & JMI_DER_DENSE_ROW_MAJOR){
    395                     jac[dF_n_cols*this_row+this_column] = this_value;
    396                 } else{
    397                     return -1;
    398                 }
    399             }
    400         }
    401         /*Reset seed vector*/
    402         for(j = offs[i]; j < max_1;j++){
    403             dv[dF_col_independent_ind[row_offs[sparse_repr[j]]]] = 0;
    404         }
    405     }
    406    
    407     free(res);
    408     free(dF);
    409     free(dv);
    410     free(row_offs);
    411     free(dF_row);
    412     free(dF_col);
    413     free(dF_col_independent_ind);
    414     return flag;
    415 }
    416 
    417 
    418 int jmi_func_cad_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz) {
    419     *n_nz = func->cad_dF_n_nz;
    420     return 0;
    421 }
    422 
    423 /*Returns the row (row) and column (col) indices, the infrastructure of p_opt
    424 variables is not complete so this implemention might not work correctly for those*/
    425 int jmi_func_cad_dF_nz_indices(jmi_t *jmi, jmi_func_t *func, int independent_vars,
    426                            int *mask,int *row, int *col) {
    427    
    428     int n_dx = jmi->n_real_dx;
    429     int n_x = jmi->n_real_x;
    430     int n_u = jmi->n_real_u;
    431     int n_w = jmi->n_real_w;
    432     int n_t = 0;
    433     int max_n_nz = func->cad_dF_n_nz;
    434    
    435     int aim = 0;
    436     int offs = 0;
    437     int i = 0;
    438     int j = 0;
    439    
    440 
    441     if(JMI_DER_T & independent_vars){
    442         n_t = 1;
    443     }
    444 
    445     aim+=n_dx;
    446     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    447         if(JMI_DER_DX & independent_vars){ 
    448             col[j] = func->cad_dF_col[i]-offs;
    449             row[j] = func->cad_dF_row[i];
    450             j++;
    451             if(i != max_n_nz-1){
    452                 if(func->cad_dF_col[i]+1<func->cad_dF_col[i+1]){
    453                     offs+=func->cad_dF_col[i+1]-(func->cad_dF_col[i]+1);
    454                 }
    455             }
    456         }
    457         i++;
    458     }
    459     if(!(JMI_DER_DX & independent_vars)){   
    460         offs+=n_dx;
    461     }
    462     aim+=n_x;
    463     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    464         if(JMI_DER_X & independent_vars){
    465             col[j] = func->cad_dF_col[i]-offs;
    466             row[j] = func->cad_dF_row[i];
    467             j++;
    468             if(i != max_n_nz-1){
    469                 if(func->cad_dF_col[i]+1<func->cad_dF_col[i+1]){
    470                     offs+=func->cad_dF_col[i+1]-(func->cad_dF_col[i]+1);
    471                 }
    472             }
    473         }
    474         i++;
    475     }
    476     if(!(JMI_DER_X & independent_vars)){   
    477         offs+=n_x;
    478     }
    479    
    480     aim+=n_u;
    481     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    482         if(JMI_DER_U & independent_vars){
    483             col[j] = func->cad_dF_col[i]-offs;
    484             row[j] = func->cad_dF_row[i];
    485             j++;
    486             if(i != max_n_nz-1){
    487                 if(func->cad_dF_col[i]+1<func->cad_dF_col[i+1]){
    488                     offs+=func->cad_dF_col[i+1]-(func->cad_dF_col[i]+1);
    489                 }
    490             }
    491         }
    492         i++;
    493     }
    494     if(!(JMI_DER_U & independent_vars)){   
    495         offs+=n_u;
    496     }
    497     aim+=n_w;
    498    
    499     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    500         if(JMI_DER_W & independent_vars){   
    501             col[j] = func->cad_dF_col[i]-offs;
    502             row[j] = func->cad_dF_row[i];
    503             j++;
    504             if(i != max_n_nz-1){
    505                 if(func->cad_dF_col[i]+1<func->cad_dF_col[i+1]){
    506                     offs+=func->cad_dF_col[i+1]-(func->cad_dF_col[i]+1);
    507                 }
    508             }
    509         }
    510         i++;
    511     }
    512     if(!(JMI_DER_W & independent_vars)){   
    513         offs+=n_w;
    514     }
    515     aim+=n_t;
    516     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    517         if(JMI_DER_T & independent_vars){   
    518             col[j] = func->cad_dF_col[i]-offs;
    519             row[j] = func->cad_dF_row[i];
    520             j++;       
    521         }
    522         i++;
    523     }
    524     return 0;
    525 }
    526 
    527 /*Returns the number of non-zeros dF_n_nz and the number of columns dF_n_cols,
    528 the infrastructure of p_opt variables is not complete so this implemention might
    529 not work correctly for those*/
    530 int jmi_func_cad_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity, int independent_vars, int *mask,
    531         int *dF_n_cols, int *dF_n_nz) {
    532    
    533     int n_dx = jmi->n_real_dx;
    534     int n_x = jmi->n_real_x;
    535     int n_u = jmi->n_real_u;
    536     int n_w = jmi->n_real_w;
    537     int n_t = 0;
    538 
    539     int n_cols = 0;
    540    
    541     int max_n_nz = func->cad_dF_n_nz;
    542    
    543     int aim = 0;
    544     int i = 0;
    545     int j = 0;
    546 
    547     if(JMI_DER_T & independent_vars){
    548         n_t = 1;
    549     }
    550    
    551     aim+=n_dx;
    552     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    553         if(JMI_DER_DX & independent_vars){ 
    554             j++;
    555             if(i != max_n_nz-1){
    556                 if(func->cad_dF_col[i]<func->cad_dF_col[i+1]){
    557                     n_cols++;
    558                 }
    559             } else{
    560                 n_cols++;
    561             }
    562         }
    563         i++;
    564     }
    565     aim+=n_x;
    566     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    567         if(JMI_DER_X & independent_vars){
    568             j++;
    569             if(i != max_n_nz-1){
    570                 if(func->cad_dF_col[i]<func->cad_dF_col[i+1]){
    571                     n_cols++;
    572                 }
    573             } else{
    574                 n_cols++;
    575             }
    576         }
    577         i++;
    578     }
    579     aim+=n_u;
    580     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    581         if(JMI_DER_U & independent_vars){
    582             j++;
    583             if(i != max_n_nz-1){
    584                 if(func->cad_dF_col[i]<func->cad_dF_col[i+1]){
    585                     n_cols++;
    586                 }
    587             } else{
    588                 n_cols++;
    589             }
    590         }
    591         i++;
    592     }
    593     aim+=n_w;
    594     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    595         if(JMI_DER_W & independent_vars){   
    596             j++;
    597             if(i != max_n_nz-1){
    598                 if(func->cad_dF_col[i]<func->cad_dF_col[i+1]){
    599                     n_cols++;
    600                 }
    601             } else{
    602                 n_cols++;
    603             }   
    604         }
    605         i++;
    606     }
    607     aim+=n_t;
    608     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    609         if(JMI_DER_T & independent_vars){   
    610             j++;
    611             if(i != max_n_nz-1){
    612                 if(func->cad_dF_col[i]<func->cad_dF_col[i+1]){
    613                     n_cols++;
    614                 }
    615             } else{
    616                 n_cols++;
    617             }       
    618         }
    619         i++;
    620     }
    621    
    622     *dF_n_cols = n_cols;
    623     *dF_n_nz = j;
    624     return 0;
    625 }
    626 
    627 /*Evaluates the Jacobian using finite differences, this code is not secured and has only been used
    628 for debugging purposes*/
    629 int jmi_func_fd_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    630         int independent_vars, int* mask, jmi_real_t* jac) {
    631     int i;
    632     int j;
    633     int k;
    634    
    635     int dF_n_cols;
    636     int dF_n_nz;
    637     int dF_n_eq;
    638     int max_columns;
    639    
    640     int *row_offs;
    641     int *dF_row;
    642     int *dF_col;
    643     int *dF_col_independent_ind;
    644 
    645     jmi_real_t *res;
    646     jmi_real_t *dF;
    647     jmi_real_t *dv;
    648 
    649 
    650     dF_n_eq = 0;
    651     max_columns = func->cad_dF_col[func->cad_dF_n_nz-1]+1;
    652    
    653     jmi_func_cad_dF_dim(jmi, func, sparsity, independent_vars, mask, &dF_n_cols, &dF_n_nz);
    654    
    655     row_offs = (int*)calloc(dF_n_cols, sizeof(int));
    656     dF_row = (int*)calloc(dF_n_nz, sizeof(int));
    657     dF_col = (int*)calloc(dF_n_nz, sizeof(int));
    658     dF_col_independent_ind = (int*)calloc(dF_n_nz,sizeof(int));
    659 
    660     jmi_func_cad_dF_nz_indices(jmi, func, independent_vars, mask, dF_row, dF_col);
    661     jmi_func_cad_dF_get_independent_ind(jmi, func, independent_vars, dF_col_independent_ind);
    662    
    663     j = 0;
    664     for(i = 0; i < dF_n_nz; i++){
    665         if(dF_col[i] == j){
    666             row_offs[j] = i;
    667             j++;
    668         }
    669     }
    670     for(i = 0; i < func->cad_dF_n_nz;i++){
    671         if(func->cad_dF_row[i] > dF_n_eq){
    672             dF_n_eq = func->cad_dF_row[i];
    673         }
    674     }
    675     dF_n_eq++;
    676    
    677     res = (jmi_real_t*)calloc(dF_n_eq, sizeof(jmi_real_t));
    678     dF = (jmi_real_t*)calloc(dF_n_eq, sizeof(jmi_real_t));
    679     dv = (jmi_real_t*)calloc(max_columns, sizeof(jmi_real_t));
    680     for(i = 0; i < max_columns;i++){
    681         dv[i] = 0;
    682     }
    683    
    684     if(sparsity & JMI_DER_SPARSE){
    685         for(i = 0; i < dF_n_nz; i++){
    686             jac[i] = 0;
    687         }
    688     } else if(sparsity & JMI_DER_DENSE_COL_MAJOR){
    689         for(i = 0; i < dF_n_eq*dF_n_cols; i++){
    690             jac[i] = 0;
    691         }
    692     } else if(sparsity & JMI_DER_DENSE_ROW_MAJOR){
    693         for(i = 0; i < dF_n_eq*dF_n_cols; i++){
    694             jac[i] = 0;
    695         }
    696     } else{
    697         return -1;
    698     }
    699    
    700    
    701     for(i = 0; i < dF_n_cols; i++){
    702         dv[dF_col_independent_ind[row_offs[i]]] = 1.0;
    703         jmi_func_fd_directional_dF(jmi, func, res, dF, dv);
    704         for(j = 0; j < dF_n_eq; j++){
    705             int this_column = i;
    706             int this_row = j;
    707             jmi_real_t this_value = dF[j];
    708                
    709             if(sparsity & JMI_DER_SPARSE){
    710                 if(this_value != 0){
    711                     k = row_offs[this_column];
    712                     while(dF_row[k] != this_row){
    713                         k++;
    714                     }
    715                     jac[k] = this_value;
    716                 }
    717             } else if(sparsity & JMI_DER_DENSE_COL_MAJOR){
    718                 jac[dF_n_eq*this_column+this_row] = this_value;
    719             } else if(sparsity & JMI_DER_DENSE_ROW_MAJOR){
    720                 jac[dF_n_cols*this_row+this_column] = this_value;
    721             } else{
    722                 return -1;
    723             }
    724         }   
    725         dv[dF_col_independent_ind[row_offs[i]]] = 0;
    726     }
    727     free(res);
    728     free(dF);
    729     free(dv);
    730     free(row_offs);
    731     free(dF_row);
    732     free(dF_col);
    733     free(dF_col_independent_ind);
    734     return 0;
    735 }
    736 
    737 int jmi_func_fd_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz) {
    738     *n_nz = func->cad_dF_n_nz;
    739     return 0;
    740 }
    741 
    742 int jmi_func_fd_dF_nz_indices(jmi_t *jmi, jmi_func_t *func, int independent_vars,
    743                            int *mask,int *row, int *col) {
    744     jmi_func_cad_dF_nz_indices(jmi, func, independent_vars, mask, row, col);
    745     return 0;
    746 }
    747 
    748 int jmi_func_fd_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity, int independent_vars, int *mask,
    749         int *dF_n_cols, int *dF_n_nz) {
    750     jmi_func_cad_dF_dim(jmi, func, sparsity, independent_vars, mask, dF_n_cols, dF_n_nz);
    751     return 0;
    752 }
    753 
    754 /*This implementation is not secured, it has only been used for debugging purposes*/
    755 int jmi_func_fd_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    756              jmi_real_t *dF, jmi_real_t* dv) {
    757     jmi_dae_directional_FD_dF(jmi, func, res, dF, dv);
    758     return 0;
    759 }
    760 
    76153int jmi_copy_pre_values(jmi_t *jmi) {
    76254    int i;
     
    77264}
    77365
    774 int jmi_dae_init(jmi_t* jmi,
    775         jmi_residual_func_t F, int n_eq_F, jmi_jacobian_func_t sym_dF,
    776         int sym_dF_n_nz, int* sym_dF_row, int* sym_dF_col,
    777         jmi_directional_der_residual_func_t cad_dir_dF,
    778         int cad_dF_n_nz, int* cad_dF_row, int* cad_dF_col,
    779         int cad_A_n_nz, int* cad_A_row, int* cad_A_col,
    780         int cad_B_n_nz, int* cad_B_row, int* cad_B_col,
    781         int cad_C_n_nz, int* cad_C_row, int* cad_C_col,
    782         int cad_D_n_nz, int* cad_D_row, int* cad_D_col,
    783         jmi_residual_func_t R, int n_eq_R, jmi_jacobian_func_t dR,
    784         int dR_n_nz, int* dR_row, int* dR_col,
    785         jmi_generic_func_t ode_derivatives,
    786         jmi_generic_func_t ode_derivatives_dir_der,
    787         jmi_generic_func_t ode_outputs,
    788         jmi_generic_func_t ode_initialize,
    789         jmi_generic_func_t ode_guards,
    790         jmi_generic_func_t ode_guards_init,
    791         jmi_next_time_event_func_t ode_next_time_event) {
    792    
    793     jmi_func_t* jf_F;
    794     jmi_func_t* jf_R;
    795    
    796     /* Create jmi_dae struct */
    797     jmi_dae_t* dae = (jmi_dae_t*) calloc(1, sizeof(jmi_dae_t));
    798     jmi->dae = dae;
    799    
    800     jmi_func_new(&jf_F, F, n_eq_F, sym_dF, sym_dF_n_nz, sym_dF_row, sym_dF_col, cad_dir_dF,
    801             cad_dF_n_nz, cad_dF_row, cad_dF_col);
    802 
    803     jmi->dae->F = jf_F;
    804 
    805     jmi_func_new(&jf_R,R,n_eq_R,dR,dR_n_nz,dR_row, dR_col,NULL, 0, NULL, NULL);
    806     jmi->dae->R = jf_R;
    807    
    808     jmi->dae->ode_derivatives = ode_derivatives;
    809     jmi->dae->ode_derivatives_dir_der = ode_derivatives_dir_der;
    810     jmi->dae->ode_outputs = ode_outputs;
    811     jmi->dae->ode_initialize = ode_initialize;
    812     jmi->dae->ode_guards = ode_guards;
    813     jmi->dae->ode_guards_init = ode_guards_init;
    814     jmi->dae->ode_next_time_event = ode_next_time_event;
    815 
    816     if (cad_A_n_nz>0 && (cad_A_n_nz < ((double)jmi->n_real_dx)*jmi->n_real_dx*0.8)) {
    817         jmi_new_simple_color_info(&(jmi->color_info_A),
    818             jmi->n_real_dx, jmi->n_real_dx, cad_A_n_nz,
    819             cad_A_row, cad_A_col, 0, 0);
    820         compute_cpr_groups(jmi->color_info_A);
    821     } else {
    822         jmi->color_info_A = NULL;
    823     }
    824 
    825     if (cad_B_n_nz>0) {
    826         jmi_new_simple_color_info(&(jmi->color_info_B),
    827             jmi->n_real_dx, jmi->n_real_dx, cad_B_n_nz,
    828             cad_A_row, cad_B_col, 0, 0);
    829         compute_cpr_groups(jmi->color_info_B);
    830     } else {
    831         jmi->color_info_B = NULL;
    832     }
    833 
    834     if (cad_C_n_nz>0) {
    835         jmi_new_simple_color_info(&(jmi->color_info_C),
    836             jmi->n_real_dx, jmi->n_real_dx, cad_A_n_nz,
    837             cad_C_row, cad_C_col, 0, 0);
    838         compute_cpr_groups(jmi->color_info_C);
    839     } else {
    840         jmi->color_info_C = NULL;
    841     }
    842 
    843     if (cad_D_n_nz>0) {
    844         jmi_new_simple_color_info(&(jmi->color_info_D),
    845             jmi->n_real_dx, jmi->n_real_dx, cad_D_n_nz,
    846             cad_D_row, cad_D_col, 0, 0);
    847         compute_cpr_groups(jmi->color_info_D);
    848     } else {
    849         jmi->color_info_D = NULL;
    850     }
    851 
    852     return 0;
    853 }
    854 
    855 int jmi_new_simple_color_info(jmi_simple_color_info_t** c_info, int n_cols, int n_cols_in_grouping, int n_nz,
    856         int* rows, int* cols, int col_offset, int one_indexing) {
    857     int i,j;
    858     int ind;
    859     int n_col_el;
    860     jmi_simple_color_info_t* c_i_temp = (jmi_simple_color_info_t*)calloc(1,sizeof(jmi_simple_color_info_t));
    861     (*c_info) = c_i_temp;
    862     c_i_temp->col_offset = col_offset;
    863     c_i_temp->n_nz = n_nz;
    864     c_i_temp->n_cols = n_cols;
    865     c_i_temp->n_cols_in_grouping = n_cols_in_grouping;
    866     c_i_temp->col_n_nz = (int*)calloc(n_cols,sizeof(int));
    867     c_i_temp->rows = (int*)calloc(n_nz,sizeof(int));
    868     c_i_temp->cols = (int*)calloc(n_nz,sizeof(int));
    869     c_i_temp->col_start_index = (int*)calloc(n_cols,sizeof(int));
    870 
    871     /* Make sure indices are stored in column major format */
    872     ind = 0;
    873     c_i_temp->col_start_index[0] = 0;
    874     for (i=0;i<n_cols;i++) {
    875         n_col_el = 0;
    876         for (j=0;j<n_nz;j++) {
    877             if (cols[j]-one_indexing == i) {
    878                 c_i_temp->rows[ind] = rows[j];
    879                 c_i_temp->cols[ind] = cols[j];
    880                 ind++;
    881                 n_col_el++;
    882             }
    883         }
    884         c_i_temp->col_n_nz[i] = n_col_el;
    885         if (i<n_cols-1) {
    886             c_i_temp->col_start_index[i+1] = ind;
    887         }
    888     }
    889 /*
    890     printf("**** New color struct ****\n");
    891     printf("n_cols: %d\n", n_cols);
    892     printf("n_cols_in_grouping: %d\n", n_cols_in_grouping);
    893     printf("n_nz: %d\n", n_nz);
    894     printf("col_offset: %d\n", col_offset);
    895     printf("one_indexing: %d\n", one_indexing);
    896     printf("*** Sorted incidence\n");
    897 
    898     for (i=0;i<n_nz;i++) {
    899         printf("%d, %d\n", c_i_temp->rows[i], c_i_temp->cols[i]);
    900     }
    901 
    902     printf("* Original incidence\n");
    903     for (i=0;i<n_nz;i++) {
    904         printf("%d, %d\n", rows[i], cols[i]);
    905     }
    906 
    907     printf("* Column starts\n");
    908     for (i=0;i<n_cols;i++) {
    909         printf("%d\n", c_i_temp->col_start_index[i]);
    910     }
    911 */
    912     c_i_temp->group_cols = (int*)calloc(n_cols,sizeof(int));
    913     c_i_temp->n_cols_in_group = (int*)calloc(n_cols,sizeof(int));
    914     c_i_temp->group_start_index = (int*)calloc(n_nz+1,sizeof(int));
    915     c_i_temp->n_groups = 0;
    916     return 0;
    917 }
    918 
    919 void jmi_delete_simple_color_info(jmi_simple_color_info_t **c_info_ptr) {
    920     jmi_simple_color_info_t *c_info = *c_info_ptr;
    921     if(!c_info) return;
    922    
    923     free(c_info->cols);
    924     free(c_info->rows);
    925     free(c_info->col_n_nz);
    926     free(c_info->group_cols);
    927     free(c_info->col_start_index);
    928     free(c_info->n_cols_in_group);
    929     free(c_info->group_start_index);
    930     free(c_info);
    931     *c_info_ptr = 0;
    932 }
    933 
    934 /*Initiate struct containing graph coloring results*/
    935 int jmi_new_color_info(jmi_color_info** c_info, int dF_n_cols, int dF_n_nz){
    936     jmi_color_info* c_i_temp = (jmi_color_info*)calloc(1,sizeof(jmi_color_info));
    937     (*c_info) = c_i_temp;
    938     c_i_temp->offs = (int*)calloc(dF_n_cols, sizeof(int));
    939     c_i_temp->sparse_repr = (int*)calloc(dF_n_cols, sizeof(int));
    940     c_i_temp->map_info = (int*)calloc(dF_n_nz, sizeof(int));
    941     c_i_temp->map_off = (int*)calloc(dF_n_cols, sizeof(int));
    942     return 0;
    943 }
    944 
    945 int jmi_delete_color_info(jmi_color_info *c_i){
    946     free(c_i->offs);
    947     free(c_i->sparse_repr);
    948     free(c_i->map_info);
    949     free(c_i->map_off);
    950     return 0;
    951 }
    952 
    953 int jmi_init_init(jmi_t* jmi, jmi_residual_func_t F0, int n_eq_F0,
    954         jmi_jacobian_func_t dF0,
    955         int dF0_n_nz, int* dF0_row, int* dF0_col,
    956         jmi_residual_func_t F1, int n_eq_F1,
    957         jmi_jacobian_func_t dF1,
    958         int dF1_n_nz, int* dF1_row, int* dF1_col,
    959         jmi_residual_func_t Fp, int n_eq_Fp,
    960         jmi_jacobian_func_t dFp,
    961         int dFp_n_nz, int* dFp_row, int* dFp_col,
    962         jmi_generic_func_t eval_parameters,
    963         jmi_residual_func_t R0, int n_eq_R0,
    964         jmi_jacobian_func_t dR0,
    965         int dR0_n_nz, int* dR0_row, int* dR0_col) {
    966     jmi_func_t* jf_F0;
    967     jmi_func_t* jf_F1;
    968     jmi_func_t* jf_Fp;
    969     jmi_func_t* jf_R0;
    970    
    971     /* Create jmi_init struct */
    972     jmi_init_t* init = (jmi_init_t*)calloc(1,sizeof(jmi_init_t));
    973     jmi->init = init;
    974 
    975     jmi_func_new(&jf_F0,F0,n_eq_F0,dF0,dF0_n_nz,dF0_row, dF0_col, NULL, 0, NULL, NULL);
    976     jmi->init->F0 = jf_F0;
    977 
    978     jmi_func_new(&jf_F1,F1,n_eq_F1,dF1,dF1_n_nz,dF1_row, dF1_col, NULL, 0, NULL, NULL);
    979     jmi->init->F1 = jf_F1;
    980 
    981     jmi_func_new(&jf_Fp,Fp,n_eq_Fp,dFp,dFp_n_nz,dFp_row, dFp_col, NULL, 0, NULL, NULL);
    982     jmi->init->Fp = jf_Fp;
    983 
    984     jmi->init->eval_parameters = eval_parameters;
    985 
    986     jmi_func_new(&jf_R0,R0,n_eq_R0,dFp,dR0_n_nz,dR0_row, dR0_col, NULL, 0, NULL, NULL);
    987     jmi->init->R0 = jf_R0;
    988 
    989     return 0;
    990 }
    991 
    992 void jmi_delete_init(jmi_init_t** pinit) {
    993         jmi_init_t* init = *pinit;
    994 
    995         jmi_func_delete(init->F0);
    996 
    997         jmi_func_delete(init->F1);
    998 
    999         jmi_func_delete(init->Fp);
    1000 
    1001         jmi_func_delete(init->R0);
    1002 
    1003         free(init);
    1004 
    1005         *pinit = 0;
    1006 }
    1007 
    1008 int jmi_variable_type(jmi_t *jmi, int col_index) {
    1009    
    1010     if (col_index>=jmi->offs_real_ci && col_index<jmi->offs_real_cd) {
    1011         return JMI_DER_CI;
    1012     } else if (col_index >= jmi->offs_real_cd && col_index < jmi->offs_real_pi) {
    1013         return JMI_DER_CD;
    1014     } else if (col_index>=jmi->offs_real_pi && col_index<jmi->offs_real_pd) {
    1015         return JMI_DER_PI;
    1016     } else if (col_index>=jmi->offs_real_pd && col_index<jmi->offs_real_dx) {
    1017         return JMI_DER_PD;
    1018     } else if (col_index>=jmi->offs_real_dx && col_index<jmi->offs_real_x) {
    1019         return JMI_DER_DX;
    1020     } else if (col_index>=jmi->offs_real_x && col_index<jmi->offs_real_u) {
    1021         return JMI_DER_X;
    1022     } else if (col_index>=jmi->offs_real_u && col_index<jmi->offs_real_w) {
    1023         return JMI_DER_U;
    1024     } else if (col_index>=jmi->offs_real_w && col_index<jmi->offs_t) {
    1025         return JMI_DER_W;
    1026     } else if (col_index==jmi->offs_t) {
    1027         return JMI_DER_T;
    1028     }
    1029 
    1030     return -1;
    1031 }
    1032 
    1033 int jmi_check_Jacobian_column_index(jmi_t *jmi, int independent_vars, int *mask, int col_index) {
    1034 
    1035     /*printf("%d\n",jmi->n_z);*/
    1036     /*printf("<<< %d %d\n", col_index, mask[col_index]);*/
    1037     /*printf("<< %d %d\n", independent_vars, jmi_variable_type(jmi, col_index));*/
    1038     int vt = 0;
    1039     if (mask[col_index] == 0) {
    1040         return 0;
    1041     } else {
    1042         vt = jmi_variable_type(jmi,col_index);
    1043         if (vt!=-1 && (independent_vars & vt)) {
    1044             return 1;
    1045         } else {
    1046             return 0;
    1047         }
    1048     }
    1049 }
    1050 
    1051 int jmi_map_Jacobian_column_index(jmi_t *jmi, int independent_vars, int *mask, int col_index) {
    1052 
    1053 /*  printf("jmi_map_Jacobian_column_index start: %d\n",col_index);*/
    1054     int new_col_index = 0;
    1055     int i = 0;
    1056 
    1057     for (i=0; i<col_index; i++) {
    1058 /*      printf("****************** 1 \n");*/
    1059         if (jmi_check_Jacobian_column_index(jmi, independent_vars, mask, i)==1) {
    1060             new_col_index++;
    1061         }
    1062 /*      printf("****************** 2 \n");*/
    1063     }
    1064 
    1065 /*  printf("jmi_map_Jacobian_column_index end: %d\n",new_col_index);*/
    1066 
    1067     return new_col_index;
    1068 }
    1069 
    1070 int jmi_variable_type_spec(jmi_t *jmi, int independent_vars,
    1071                int *mask, int col_index) {
    1072 
    1073   int spec_jac_index = 0;
    1074   int i = 0;
    1075   for(i=0;i<jmi->n_z;i++) {
    1076     if (jmi_check_Jacobian_column_index(jmi,independent_vars,mask,i)==1) {
    1077       spec_jac_index++;
    1078     }
    1079     if (col_index==spec_jac_index) {
    1080       return jmi_variable_type(jmi,i);
    1081     }
    1082   }
    1083   return -1;
    1084 }
    1085 
    1086 int jmi_dae_get_sizes(jmi_t* jmi, int* n_eq_F, int* n_eq_R) {
    1087     if (jmi->dae == NULL) {
    1088         return -1;
    1089     }
    1090     *n_eq_F = jmi->dae->F->n_eq_F;
    1091     *n_eq_R = jmi->dae->R->n_eq_F;
    1092     return 0;
    1093 }
    1094 
    1095 int jmi_init_get_sizes(jmi_t* jmi, int* n_eq_F0, int* n_eq_F1, int* n_eq_Fp,
    1096         int* n_eq_R0) {
    1097     if (jmi->init == NULL) {
    1098         return -1;
    1099     }
    1100     *n_eq_F0 = jmi->init->F0->n_eq_F;
    1101     *n_eq_F1 = jmi->init->F1->n_eq_F;
    1102     *n_eq_Fp = jmi->init->Fp->n_eq_F;
    1103     *n_eq_R0 = jmi->init->R0->n_eq_F;
    1104     return 0;
    1105 }
    1106 
    110766jmi_real_t* jmi_get_z(jmi_t* jmi) {
    110867    return *(jmi->z);
     
    1209168}
    1210169
    1211 int jmi_get_output_vrefs(jmi_t *jmi, int *output_vrefs) {
    1212     int i;
    1213     for (i=0;i<jmi->n_outputs;i++) {
    1214         output_vrefs[i] = jmi->output_vrefs[i];
    1215     }
    1216     return 0;
    1217 }
    1218 
    1219170jmi_real_t* jmi_get_sw(jmi_t* jmi) {
    1220171    return *(jmi->z) + jmi->offs_sw;
     
    1233184}
    1234185
    1235 jmi_real_t* jmi_get_variable_scaling_factors(jmi_t* jmi) {
    1236     return jmi->variable_scaling_factors;
    1237 }
    1238 
    1239 int jmi_get_scaling_method(jmi_t* jmi) {
    1240     return jmi->scaling_method;
    1241 }
    1242 
    1243 void jmi_print_summary(jmi_t *jmi) {
    1244     printf("Number of interactive constants:               %d\n",jmi->n_real_ci);
    1245     printf("Number of dependent constants:                 %d\n",jmi->n_real_cd);
    1246     printf("Number of interactive parameters:              %d\n",jmi->n_real_pi);
    1247     printf("Number of dependent parameters:                %d\n",jmi->n_real_pd);
    1248     printf("Number of derivatives:                         %d\n",jmi->n_real_dx);
    1249     printf("Number of states:                              %d\n",jmi->n_real_x);
    1250     printf("Number of inputs:                              %d\n",jmi->n_real_u);
    1251     printf("Number of algebraics:                          %d\n",jmi->n_real_w);
    1252     printf("Number of switching functions in DAE:          %d\n",jmi->n_sw);
    1253     printf("Number of switching functions in DAE init:     %d\n",jmi->n_sw_init);
    1254     if (jmi->dae != NULL) {
    1255         printf("DAE interface:\n");
    1256         printf("  Number of DAE equations:                     %d\n",jmi->dae->F->n_eq_F);
    1257     } else {
    1258         printf("No DAE functions available");
    1259     }
    1260     if (jmi->init != NULL) {
    1261         printf("Initialization interface:\n");
    1262         printf("  Number of F0 equations:                      %d\n",jmi->init->F0->n_eq_F);
    1263         printf("  Number of F1 equations:                      %d\n",jmi->init->F1->n_eq_F);
    1264     } else {
    1265         printf("No Initialization functions available");
    1266     }
    1267 }
    1268 
    1269 void jmi_lin_interpolate(jmi_real_t x, jmi_real_t *z , int n ,int m,
    1270         jmi_real_t *y) {
    1271 
    1272     int i;
    1273     int el = 0;
    1274 
    1275     /* Check if before interval */
    1276     if (x <= z[0]) {
    1277         for (i=0;i<m-1;i++) {
    1278 /*          printf("%d: %f\n",i+1,z[n*(i+1)]);*/
    1279             y[i] = z[n*(i+1)];
    1280         }
    1281         return;
    1282     }
    1283     /* Check after interval */
    1284     if (x >= z[n-1]) {
    1285         for (i=0;i<m-1;i++) {
    1286             y[i] = z[n*(i+2)-1];
    1287         }
    1288         return;
    1289     }
    1290 
    1291     /* Find correct element */
    1292     while(x >= z[el]) {
    1293         el++;
    1294     }
    1295     el--;
    1296 
    1297 /*  printf(">> %d\n",el);*/
    1298 
    1299     /* Compute interpolated values. */
    1300     for (i=0;i<m-1;i++) {
    1301         y[i] = (x-z[el])*(z[n*(i+1) + el + 1] - z[n*(i+1) + el])/(z[el+1]-z[el]) +
    1302            z[n*(i+1) + el];
    1303     }
    1304 
    1305 }
    1306 
    1307 int jmi_dae_derivative_checker(jmi_t* jmi, int sparsity, int independent_vars, int screen_use, int *mask){
    1308     return jmi_util_dae_derivative_checker(jmi, jmi->dae->F, sparsity, independent_vars, screen_use, mask);
    1309 }
    1310 
    1311 int jmi_with_cad_derivatives(jmi_t* jmi)
    1312 {
    1313   return (jmi->dae->F->cad_dF_row[0]==-1)? 0: 1;
    1314 }
    1315 
    1316186void jmi_init_runtime_options(jmi_t *jmi, jmi_options_t* op) {
    1317187    jmi_block_solver_init_default_options(&op->block_solver_options);
    1318188
    1319     op->nle_solver_default_tol = 1e-10;      /**< \brief Default tolerance for the equation block solver */
     189    op->nle_solver_default_tol = 1e-10;   /**< \brief Default tolerance for the equation block solver */
    1320190    op->nle_solver_tol_factor = 0.0001;   /**< \brief Tolerance safety factor for the non-linear equation block solver. */
    1321191    op->events_default_tol = 1e-10;       /**< \brief Default tolerance for the event iterations. */       
    1322192    op->events_tol_factor = 0.0001;       /**< \brief Tolerance safety factor for the event iterations. */
    1323     op->cs_solver = JMI_ODE_CVODE;        /** < \brief Option for changing the internal CS solver. */
    1324     op->cs_rel_tol = 1e-6;                /** < \brief Default tolerance for the adaptive solvers in the CS case. */
    1325     op->cs_step_size = 1e-3;              /** < \brief Default step-size for the non-adaptive solvers in the CS case. */   
     193    op->cs_solver = JMI_ODE_CVODE;        /**< \brief Option for changing the internal CS solver. */
     194    op->cs_rel_tol = 1e-6;                /**< \brief Default tolerance for the adaptive solvers in the CS case. */
     195    op->cs_step_size = 1e-3;              /**< \brief Default step-size for the non-adaptive solvers in the CS case. */   
    1326196    op->cs_experimental_mode = 0;
    1327197
     
    1329199}
    1330200
    1331 int jmi_get_index_from_value_ref(int vref) {
     201jmi_value_reference jmi_get_index_from_value_ref(jmi_value_reference vref) {
    1332202    /* Translate a ValueReference into variable index in z-vector. */
    1333203    return vref & VREF_INDEX_MASK;
    1334204}
    1335205
    1336 int jmi_get_type_from_value_ref(int vref) {
    1337     /* Translate a ValueReference into variable type in z-vector. */
    1338     return vref & VREF_TYPE_MASK;
    1339 }
    1340 
    1341 int jmi_get_value_ref_from_index(int index, jmi_int_t type) {
     206jmi_type_t jmi_get_type_from_value_ref(jmi_value_reference vref) {
     207    /* Translate a ValueReference into variable type in z-vector. */   
     208    switch (vref & VREF_TYPE_MASK) {
     209        case REAL_TYPE_MASK: return JMI_REAL;
     210        case INT_TYPE_MASK:  return JMI_INTEGER;
     211        case BOOL_TYPE_MASK: return JMI_BOOLEAN;
     212        case STR_TYPE_MASK:  return JMI_STRING;
     213        default:
     214            return -1;
     215    }
     216}
     217
     218jmi_value_reference jmi_value_ref_is_negated(jmi_value_reference vref) {
     219    /* Checks for a valueReference if it is negated. */
     220    return vref & VREF_NEGATE_MASK;
     221}
     222
     223jmi_value_reference jmi_get_value_ref_from_index(int index, jmi_type_t type) {
    1342224    /* Translates an index together with a type to a value reference */
    1343     int valueref = -1;
    1344    
    1345     if (type == JMI_REAL) {
    1346         valueref = REAL_TYPE_MASK+index;
    1347     }else if (type == JMI_INTEGER) {
    1348         valueref = INT_TYPE_MASK+index;
    1349     }else if (type == JMI_BOOLEAN) {
    1350         valueref = BOOL_TYPE_MASK+index;
    1351     }
    1352    
    1353     return valueref;
    1354 }
    1355 
    1356 /*This function has been used during debugging*/
    1357 int jmi_dae_directional_FD_dF(jmi_t* jmi, jmi_func_t *func, jmi_real_t *res, jmi_real_t* dF, jmi_real_t* dv) {
    1358     jmi_real_t h = 0.0001;
    1359    
    1360     int n_eq = 0;
    1361     int n_eq_R = 0;
    1362     int i;
    1363     int offs;
    1364 
    1365     jmi_real_t* dx;
    1366     jmi_real_t* x;
    1367     jmi_real_t* u;
    1368     jmi_real_t* w;
    1369     jmi_real_t* t;
    1370 
    1371     jmi_real_t* res1;
    1372     jmi_real_t* res2;
    1373 
    1374    
    1375     dx = jmi_get_real_dx(jmi);
    1376     x = jmi_get_real_x(jmi);
    1377     u = jmi_get_real_u(jmi);
    1378     w = jmi_get_real_w(jmi);
    1379     t = jmi_get_t(jmi);
    1380    
    1381 
    1382     jmi_dae_get_sizes(jmi, &n_eq, &n_eq_R);
    1383    
    1384     res1 = (jmi_real_t*)calloc(n_eq,sizeof(jmi_real_t));
    1385     res2 = (jmi_real_t*)calloc(n_eq,sizeof(jmi_real_t));
    1386    
    1387    
    1388    
    1389     offs = 0;
    1390     for (i=0;i<jmi->n_real_dx;i++) {
    1391         dx[i] = dx[i] + dv[i+offs]*h;       
    1392     }
    1393     offs += jmi->n_real_dx;
    1394     for (i=0;i<jmi->n_real_x;i++) {
    1395         x[i] = x[i] + dv[i+offs]*h;
    1396     }
    1397     offs+=jmi->n_real_x;
    1398     for (i=0;i<jmi->n_real_u;i++) {
    1399         u[i] = u[i] + dv[i+offs]*h;
    1400     }
    1401     offs+=jmi->n_real_u;
    1402     for (i=0;i<jmi->n_real_w;i++) {
    1403         w[i] = w[i] + dv[i+offs]*h;
    1404     }
    1405     offs+=jmi->n_real_w;
    1406     *t = *t + dv[offs]*h;
    1407    
    1408     jmi_func_F(jmi,jmi->dae->F, res1);
    1409    
    1410     for (i=0;i<jmi->n_real_dx;i++) {
    1411         dx[i] = dx[i] - 2*dv[i]*h;
    1412     }
    1413     offs = jmi->n_real_dx;
    1414     for (i=0;i<jmi->n_real_x;i++) {
    1415         x[i] = x[i] - 2*dv[i+offs]*h;
    1416     }
    1417     offs+=jmi->n_real_x;
    1418     for (i=0;i<jmi->n_real_u;i++) {
    1419         u[i] = u[i] - 2*dv[i+offs]*h;
    1420     }
    1421     offs+=jmi->n_real_u;
    1422     for (i=0;i<jmi->n_real_w;i++) {
    1423         w[i] = w[i] - 2*dv[i+offs]*h;
    1424     }
    1425     offs+=jmi->n_real_w;
    1426     *t = *t - 2*dv[offs]*h;
    1427    
    1428     jmi_func_F(jmi, jmi->dae->F, res2);
    1429    
    1430     for (i=0;i<jmi->n_real_dx;i++) {
    1431         dx[i] = dx[i] + dv[i]*h;
    1432     }
    1433     offs = jmi->n_real_dx;
    1434     for (i=0;i<jmi->n_real_x;i++) {
    1435         x[i] = x[i] + dv[i+offs]*h;
    1436     }
    1437     offs+=jmi->n_real_x;
    1438     for (i=0;i<jmi->n_real_u;i++) {
    1439         u[i] = u[i] + dv[i+offs]*h;
    1440     }
    1441     offs+=jmi->n_real_u;
    1442     for (i=0;i<jmi->n_real_w;i++) {
    1443         w[i] = w[i] + dv[i+offs]*h;
    1444     }
    1445     offs+=jmi->n_real_w;
    1446     *t = *t + dv[offs]*h;
    1447    
    1448     for(i=0;i< n_eq;i++){
    1449         dF[i] = (res1[i] -  res2[i])/(2*h);
    1450     }
    1451    
    1452     free(res1);
    1453     free(res2);
    1454    
    1455     return 0;
    1456 }
    1457 
    1458 /*Performs graph coloring, sse documentation in function jmi_func_cad_df
    1459 for a description of the output parameter*/
    1460 int jmi_dae_cad_color_graph(jmi_t *jmi, jmi_func_t *func, int n_col, int n_nz, int *row, int *col, int *sparse_repr, int *offs, int *n_colors, int *map_info, int *map_off){
    1461     int i;
    1462     int j;
    1463     int n_color = 0;
    1464    
    1465     int *inc_length =   (int*)calloc(n_col, sizeof(int));
    1466     int *color      =   (int*)calloc(n_col, sizeof(int));
    1467     int *numb_col   =   (int*)calloc(n_col, sizeof(int));
    1468     int *row_off    =   (int*)calloc(n_col, sizeof(int));
    1469     int **incidence_v;
    1470    
    1471     /*inc_length number of connections for every node (One column corresponds to one node)*/
    1472     jmi_dae_cad_get_connection_length(n_col ,n_nz,row,col, inc_length);
    1473    
    1474     func->coloring_counter++;
    1475    
    1476     incidence_v = (int**)calloc(n_col, sizeof(int*));
    1477     for(i = 0; i<n_col; i++){
    1478         incidence_v[i] = (int*)calloc(inc_length[i], sizeof(int));
    1479     }
    1480    
    1481     /*Creates a matrix that contains all connections for every node*/
    1482     jmi_dae_cad_get_connections(n_col, n_nz,row,col, incidence_v, inc_length );
    1483    
    1484     /*Performs the graph coloring*/
    1485     jmi_dae_cad_first_fit( n_col, incidence_v, inc_length, color, numb_col);
    1486 
    1487     /*Total number of colors*/
    1488     for(i = 0; i < n_col;i++){
    1489         if(n_color < color[i]){
    1490             n_color = color[i];
    1491         }
    1492     }
    1493     n_color++;
    1494      
    1495     j = 0;
    1496     for(i = 0; i < n_nz; i++){
    1497         if(col[i] == j){
    1498             row_off[j] = i;
    1499             j++;
    1500         }
    1501     }
    1502    
    1503     offs[0] = 0;
    1504     for(i = 1; i < n_color; i++){
    1505         offs[i] = numb_col[i-1] + offs[i-1];
    1506     }
    1507     for(i = 0; i< n_col; i++){
    1508         sparse_repr[i] = -1;
    1509     }
    1510    
    1511     /*Sets up the sparse_repr, map_info and map_off vectors*/
    1512     jmi_dae_cad_get_compression_info(n_nz, row, row_off, n_col, color, sparse_repr, offs, numb_col, map_info, map_off);
    1513    
    1514     for(i = 0; i < n_col; i++){
    1515         free(incidence_v[i]);
    1516     }
    1517     free(incidence_v);
    1518     free(color);
    1519     free(inc_length);
    1520     free(numb_col);
    1521     free(row_off);
    1522     *n_colors = n_color;
    1523     return 0;
    1524 }
    1525 
    1526 int jmi_dae_cad_get_compression_info(int n_nz, int *row, int *row_off, int n_col, int *color, int *sparse_repr, int *offs, int *numb_color, int *map_info, int *map_off){
    1527     int i;
    1528     int j;
    1529     int c;
    1530     for(i = 0; i<n_col; i++){
    1531         c = color[i];
    1532         j = 0;
    1533         while(j<numb_color[c]&&sparse_repr[offs[c]+j] != -1){
    1534             j++;
    1535         }
    1536         sparse_repr[offs[c]+j] = i;
    1537         if(i !=n_col-1){
    1538             map_off[offs[c] + j] = row_off[i+1]-row_off[i];
    1539         } else{
    1540             map_off[offs[c] + j] = n_nz-row_off[i];
    1541         }
    1542     }
    1543    
    1544     map_off[n_col-1] = n_nz - map_off[n_col-1];
    1545    
    1546     for(i = n_col-2; i >= 0; i--){
    1547         map_off[i] = map_off[i+1]-map_off[i];
    1548     }
    1549    
    1550     for(i = 0; i < n_col-1; i++){
    1551         for(j = map_off[i]; j < map_off[i+1]; j++){
    1552             map_info[j] = row[row_off[sparse_repr[i]]+j - map_off[i]];                 
    1553         }
    1554     }
    1555    
    1556     for(j = map_off[n_col-1]; j < n_nz; j++){
    1557         map_info[j] = row[row_off[sparse_repr[n_col-1]]+j - map_off[n_col-1]];
    1558     }
    1559     return 0;
    1560 }
    1561    
    1562 int jmi_dae_cad_first_fit( int n_col, int **inc_vec, int *inc_length, int *color, int *numb_col){
    1563     int i;
    1564     int j;
    1565     int max_col = 0;
    1566     int *col_set  = (int*)calloc(n_col, sizeof(int));
    1567    
    1568     for(i = 0; i < n_col; i++){
    1569         color[i] = 0;
    1570         col_set[i] = 0;
    1571         numb_col[i] = 0;
    1572     }
    1573    
    1574     for(i = 0; i < n_col; i++){
    1575         for(j = 0; j < inc_length[i]; j++){
    1576             if(color[inc_vec[i][j]] != 0){
    1577                 col_set[color[inc_vec[i][j]]-1] = 1;
    1578             }
    1579         }
    1580         j = 0;
    1581         while(col_set[j] == 1 && j < n_col){
    1582             j++;
    1583         }
    1584         color[i] = j+1;
    1585         numb_col[j]++;
    1586         if(max_col < j+1){
    1587             max_col = j+1;
    1588         }
    1589         for(j = 0; j < max_col; j++){
    1590             col_set[j] = 0;
    1591         }
    1592     }
    1593     for(i = 0; i < n_col; i++){
    1594         color[i]--;
    1595     }
    1596     free(col_set);
    1597     return 0;
    1598 }
    1599        
    1600 int jmi_dae_cad_get_connection_length( int n_col, int n_nz, int *row, int *col, int *inc_length){
    1601     int i;
    1602     int j;
    1603     int k;
    1604     int c;
    1605    
    1606     int *offs = (int*)calloc(n_col+1, sizeof(int));
    1607    
    1608     j=0;
    1609     for(i = 0; i<n_nz;i++){
    1610         if(j == col[i]){
    1611             offs[j] = i;
    1612             j++;
    1613         }
    1614     }
    1615     offs[j] = n_nz;
    1616     for(i = 0; i<n_col; i++){
    1617         c=0;
    1618         for(j = 0; j < n_nz; j++){
    1619             for(k = offs[i]; k < offs[i+1]; k++){
    1620                 if(row[j]== row[k]){
    1621                     c++;
    1622                     k = offs[i+1];
    1623                     j =offs[col[j]+1]-1;
    1624                 }
    1625             }
    1626         }
    1627         inc_length[i] = c;
    1628     }
    1629     free(offs);
    1630     return 0;
    1631 }
    1632 
    1633 int jmi_dae_cad_get_connections( int n_col, int n_nz, int *row, int *col, int **inc_vec, int *inc_length){
    1634     int i;
    1635     int j;
    1636     int k;
    1637     int c;
    1638 
    1639     int *offs = (int*)calloc(n_col+1, sizeof(int));
    1640    
    1641     j=0;
    1642     for(i = 0; i<n_nz;i++){
    1643         if(j == col[i]){
    1644             offs[j] = i;
    1645             j++;
    1646         }
    1647     }
    1648     offs[j] = n_nz;
    1649    
    1650     for(i = 0; i<n_col; i++){
    1651         c = 0;
    1652         for(j = 0; j < n_nz; j++){
    1653             for(k = offs[i]; k < offs[i+1]; k++){
    1654                 if(row[j]== row[k]){
    1655                     inc_vec[i][c] = col[j];
    1656                     c++;
    1657                     k = offs[i+1];
    1658                     j =offs[col[j]+1]-1;
    1659                 }
    1660             }   
    1661         }
    1662     }
    1663     free(offs);
    1664     return 0;
    1665 }
    1666 
    1667 void compute_cpr_groups(jmi_simple_color_info_t *color_info) {
    1668     int n_cols_in_group; /* Counter for the number of columns in a group */
    1669     int n_selected_cols; /* Total number of columns added to groups */
    1670 
    1671     int i,j,k,l,compatible;
    1672 
    1673     int n_c_g = color_info->n_cols_in_grouping;
    1674     int offs_c_g = color_info->col_offset;
    1675 
    1676     int* selected_groups = (int*)calloc(n_c_g,sizeof(int));
    1677     for (i=0;i<n_c_g;i++) {
    1678         selected_groups[i] = 0;
    1679     }
    1680 
    1681     /*clock_t start = clock();*/
    1682 
    1683     /*
    1684     printf("**********\n");
    1685     for (i=0;i<n_c_g;i++) {
    1686         for (j=0;j<func->ad->dF_z_col_n_nz[i+offs_c_g];j++) {
    1687             printf(" - %d %d\n", i+offs_c_g,func->ad->dF_z_row[func->ad->dF_z_col_start_index[i+offs_c_g]+j]);
    1688         }
    1689     }
    1690 
    1691 
    1692     printf("n_cols_in_grouping=%d\n",n_c_g);
    1693 */
    1694 
    1695     color_info->n_groups = 0;
    1696     color_info->group_start_index[0] = 0;
    1697     n_cols_in_group = 0;
    1698     n_selected_cols = 0;
    1699     /* Loop until all column have been added to a graph */
    1700     while(n_selected_cols<n_c_g) {
    1701         /*printf("Starting sweep, n_groups = %d\n",color_info->n_groups);*/
    1702         /* Reset group column counter */
    1703         n_cols_in_group = 0;
    1704         /* Loop over all colums and add the ones that are i) compatible
    1705          and ii) have not been selected */
    1706         for(i=0;i<n_c_g;i++) {
    1707             /*printf("About to check, col = %d\n",i+offs_c_g);*/
    1708             /* If the column has not been added to a group... */
    1709             if (selected_groups[i]!=1) {
    1710                 /*printf("Col %d has not been selected\n",i+offs_c_g);*/
    1711                 /* ...make compatibility check */
    1712                 compatible = 1;
    1713                 /* Loop over all columns that have been added to group */
    1714                 for (j=color_info->group_start_index[color_info->n_groups];
    1715                         j<color_info->group_start_index[color_info->n_groups] +
    1716                         n_cols_in_group;j++) {
    1717 
    1718                     /*printf("a row index: %d\n", color_info->col_start_index[color_info->group_cols[j]]);
    1719                     printf("b row index: %d\n", color_info->col_start_index[i + offs_c_g]);
    1720                     printf("qew: %d, %d\n", i, offs_c_g);*/
    1721                     int* col_a_row_ind = &color_info->rows[color_info->col_start_index[color_info->group_cols[j]]];
    1722                     int* col_b_row_ind = &color_info->rows[color_info->col_start_index[i + offs_c_g]];
    1723                     int col_a_n_nz = color_info->col_n_nz[color_info->group_cols[j]];
    1724                     int col_b_n_nz = color_info->col_n_nz[i+offs_c_g];
    1725 
    1726                     /*printf("Checking col %d, n_nz=%d, against %d, n_n_z=%d (in group)\n",
    1727                             i+offs_c_g,col_b_n_nz,color_info->group_cols[j],col_a_n_nz);*/
    1728 
    1729                     for (k=0;k<col_a_n_nz;k++) {
    1730                         for (l=0;l<col_b_n_nz;l++) {
    1731                             /*printf(" ** %d %d\n",col_a_row_ind[k],col_b_row_ind[l]);*/
    1732                             if (col_a_row_ind[k] == col_b_row_ind[l]) {
    1733                                 compatible = 0;
    1734                                 break;
    1735                             }
    1736                         }
    1737                     }
    1738                 }
    1739                 if (compatible==1) {
    1740                     /*printf("Col %d added to group\n",i+offs_c_g);*/
    1741                     selected_groups[i] = 1;
    1742                     color_info->group_cols[n_selected_cols] = i + offs_c_g;
    1743                     n_selected_cols++;
    1744                     n_cols_in_group++;
    1745                 } else {
    1746                     /*printf("Col %d incompatible\n",i+offs_c_g);*/
    1747                 }
    1748             } else {
    1749                    /* printf("Col %d has already been selected\n",i+offs_c_g);*/
    1750             }
    1751         }
    1752         color_info->n_groups++;
    1753         color_info->group_start_index[color_info->n_groups] =
    1754                 color_info->group_start_index[color_info->n_groups - 1] + n_cols_in_group;
    1755         color_info->n_cols_in_group[color_info->n_groups - 1] = n_cols_in_group;
    1756         /*printf("End iteration over cols, col = %d, n_cols_in_group = %d\n",i,n_cols_in_group);*/
    1757     }
    1758 
    1759     free(selected_groups);
    1760     /*
    1761     printf("Computed CPR groups: %d groups computed from %d columns\n",color_info->n_groups,color_info->n_cols_in_grouping);
    1762     for (i=0;i<color_info->n_groups;i++) {
    1763         for (j=0;j<color_info->n_cols_in_group[i];j++) {
    1764             printf(" >> %d %d\n",i,color_info->group_cols[color_info->group_start_index[i]+j]);
    1765         }
    1766     }*/
    1767 
    1768 }
    1769 
    1770 int jmi_util_dae_derivative_checker(jmi_t *jmi,jmi_func_t *func, int sparsity,
    1771         int independent_vars, int screen_use, int *mask){
    1772    
    1773         int i = 0;
    1774 
    1775         jmi_real_t tol = 0.001;
    1776        
    1777         int dF_n_cols;
    1778         int dF_n_nz;
    1779         int dF_n_eq = 0;
    1780         int* dF_row;
    1781         int* dF_col;
    1782         int passed;
    1783         int failed;
    1784        
    1785 
    1786         jmi_func_cad_dF_dim(jmi, jmi->dae->F, i, independent_vars, mask, &dF_n_cols, &dF_n_nz);
    1787        
    1788         dF_row = (int*)calloc(dF_n_nz, sizeof(int));
    1789         dF_col = (int*)calloc(dF_n_nz, sizeof(int));
    1790         jmi_func_cad_dF_nz_indices(jmi, jmi->dae->F, independent_vars, mask, dF_row, dF_col);
    1791        
    1792         for(i = 0; i < dF_n_nz;i++){
    1793             if(dF_row[i] > dF_n_eq){
    1794                 dF_n_eq = dF_row[i];
    1795             }
    1796         }
    1797         dF_n_eq++;
    1798        
    1799         passed = 0;
    1800         failed = 0;
    1801        
    1802         if(sparsity & JMI_DER_SPARSE){
    1803             jmi_real_t *jac_cad = (jmi_real_t*)calloc(dF_n_nz, sizeof(jmi_real_t));
    1804             jmi_real_t *jac_fd;
    1805             jmi_func_cad_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_cad);       
    1806             jac_fd = (jmi_real_t*)calloc(dF_n_nz, sizeof(jmi_real_t));
    1807             jmi_func_fd_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_fd);
    1808             for(i = 0; i < dF_n_nz; i++){
    1809                 if(jac_fd[i] != 0 && jac_cad[i] != 0){
    1810                     jmi_real_t rel_tol;
    1811                     rel_tol = 1.0 - jac_fd[i]/jac_cad[i];
    1812                     if((rel_tol < tol) && (rel_tol > -tol)){
    1813                         passed++;
    1814                     } else{
    1815                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1816                             printf("\nFAILED\trow: %d,\t col: %d,\n", dF_row[i], dF_col[i]);
    1817                             printf("cad: %.4f,\t fd: %.4f,\t rel_tol: %.7f\t\n ", jac_cad[i], jac_fd[i], rel_tol);
    1818                             failed++;
    1819                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1820                             printf("\nEvaluation error found, derivative check failed\n");
    1821                             return -1;
    1822                         } else{
    1823                             printf("\nNo such flag\n");
    1824                             return -1;
    1825                         }
    1826                     }
    1827                 }else{
    1828                     jmi_real_t abs_tol;
    1829                     abs_tol = jac_cad[i]-jac_fd[i];
    1830                     if((abs_tol < tol) && (abs_tol > -tol)){
    1831                         passed++;
    1832                     } else{
    1833                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1834                             printf("\nFAILED\trow: %d,\t col: %d,\n", dF_row[i], dF_col[i]);
    1835                             printf("cad: %.4f,\t fd: %.4f,\t abs_tol: %.7f\t\n", jac_cad[i], jac_fd[i], abs_tol);
    1836                             failed++;
    1837                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1838                             printf("\nEvaluation error found, derivative check failed\n");
    1839                             return -1;
    1840                         } else{
    1841                             printf("\nNo such flag\n");
    1842                             return -1;
    1843                         }
    1844                     }
    1845                 }
    1846             }
    1847             free(jac_cad);
    1848             free(jac_fd);
    1849            
    1850         } else if(sparsity & JMI_DER_DENSE_COL_MAJOR){
    1851             jmi_real_t *jac_cad = (jmi_real_t*)calloc(dF_n_cols*dF_n_eq, sizeof(jmi_real_t));
    1852             jmi_real_t *jac_fd;
    1853             jmi_func_cad_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_cad);   
    1854             jac_fd = (jmi_real_t*)calloc(dF_n_cols*dF_n_eq, sizeof(jmi_real_t));
    1855             jmi_func_fd_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_fd);
    1856             for(i = 0; i < dF_n_cols*dF_n_eq; i++){
    1857                 if(jac_fd[i] != 0 && jac_cad[i] != 0){
    1858                     jmi_real_t rel_tol;
    1859                     rel_tol = 1.0 - jac_fd[i]/jac_cad[i];           
    1860                     if((rel_tol < tol) && (rel_tol > -tol)){
    1861                         passed++;
    1862                     } else{
    1863                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1864                             printf("\nFAILED\trow: %d,\t col: %d,\n", i % dF_n_eq, (i - (i % dF_n_eq))/dF_n_eq);
    1865                             printf("cad: %.4f,\t fd: %.4f,\t rel_tol: %.7f\n", jac_cad[i], jac_fd[i], rel_tol);
    1866                             failed++;
    1867                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1868                             printf("\nEvaluation error found, derivative check failed\n");
    1869                             return -1;
    1870                         } else{
    1871                             printf("\nNo such flag\n");
    1872                             return -1;
    1873                         }
    1874                     }
    1875                 }else{
    1876                     jmi_real_t abs_tol;
    1877                     abs_tol = jac_cad[i]-jac_fd[i];
    1878                     if((abs_tol < tol) && (abs_tol > -tol)){
    1879                         passed++;
    1880                     } else{
    1881                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1882                             printf("\nFAILED\trow: %d,\t col: %d,\n", i % dF_n_eq, (i - (i % dF_n_eq))/dF_n_eq);
    1883                             printf("cad: %.4f,\t fd: %.4f,\t abs_tol: %.7f\n", jac_cad[i], jac_fd[i], abs_tol);
    1884                             failed++;
    1885                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1886                             printf("\nEvaluation error found, derivative check failed\n");
    1887                             return -1;
    1888                         } else{
    1889                             printf("\nNo such flag\n");
    1890                             return -1;
    1891                         }
    1892                     }
    1893                 }
    1894             }
    1895             free(jac_cad);
    1896             free(jac_fd);
    1897            
    1898         } else if(sparsity & JMI_DER_DENSE_ROW_MAJOR){
    1899             jmi_real_t *jac_cad = (jmi_real_t*)calloc(dF_n_cols*dF_n_eq, sizeof(jmi_real_t));
    1900             jmi_real_t *jac_fd;
    1901             jmi_func_cad_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_cad);   
    1902             jac_fd = (jmi_real_t*)calloc(dF_n_cols*dF_n_eq, sizeof(jmi_real_t));
    1903             jmi_func_fd_dF(jmi,jmi->dae->F, sparsity, independent_vars, mask, jac_fd);
    1904             for(i = 0; i < dF_n_cols*dF_n_eq; i++){
    1905                 if(jac_fd[i] != 0 || jac_cad[i] != 0){
    1906                     jmi_real_t rel_tol;
    1907                     rel_tol = 1.0 - jac_fd[i]/jac_cad[i];   
    1908                     if((rel_tol < tol) && (rel_tol > -tol)){
    1909                         passed++;
    1910                     } else{
    1911                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1912                             printf("\nFAILED\trow: %d,\t col: %d,\n", (i - (i % dF_n_cols))/dF_n_cols, i % dF_n_cols);
    1913                             printf("cad: %.4f,\t fd: %.4f,\t rel_tol: %.7f\n", jac_cad[i], jac_fd[i], rel_tol);
    1914                             failed++;
    1915                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1916                             printf("\nEvaluation error found, derivative check failed\n");
    1917                             return -1;
    1918                         } else{
    1919                             printf("\nNo such flag\n");
    1920                             return -1;
    1921                         }
    1922                     }
    1923                 }
    1924                 else{
    1925                     jmi_real_t abs_tol;
    1926                     abs_tol = jac_cad[i]-jac_fd[i];
    1927                     if((abs_tol < tol) && (abs_tol > -tol)){
    1928                         passed++;
    1929                     } else{
    1930                         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1931                             printf("\nFAILED\trow: %d,\t col: %d,\n", (i - (i % dF_n_cols))/dF_n_cols, i % dF_n_cols);
    1932                             printf("cad: %.4f,\t fd: %.4f,\t abs_tol: %.7f\n", jac_cad[i], jac_fd[i], abs_tol);
    1933                             failed++;
    1934                         } else if(screen_use & JMI_DER_CHECK_SCREEN_OFF){
    1935                             printf("\nEvaluation error found, derivative check failed\n");
    1936                             return -1;
    1937                         } else{
    1938                             printf("\nNo such flag\n");
    1939                             return -1;
    1940                         }
    1941                     }
    1942                 }
    1943             }
    1944             free(jac_cad);
    1945             free(jac_fd);
    1946         } else{
     225    switch (type) {
     226        case JMI_REAL:    return index + REAL_TYPE_MASK;
     227        case JMI_INTEGER: return index + INT_TYPE_MASK;
     228        case JMI_BOOLEAN: return index + BOOL_TYPE_MASK;
     229        case JMI_STRING:  return index + STR_TYPE_MASK;
     230        default:
    1947231            return -1;
    1948         }
    1949         if(screen_use & JMI_DER_CHECK_SCREEN_ON){
    1950             printf("\nPASSED: %d\tFAILED: %d\n\n", passed, failed);
    1951         }
    1952         free(dF_row);
    1953         free(dF_col);
    1954         return 0;
    1955 }
    1956 
    1957 int jmi_func_cad_dF_get_independent_ind(jmi_t *jmi, jmi_func_t *func, int independent_vars, int *col_independent_ind) {
    1958    
    1959     int n_dx = jmi->n_real_dx;
    1960     int n_x = jmi->n_real_x;
    1961     int n_u = jmi->n_real_u;
    1962     int n_w = jmi->n_real_w;
    1963     int n_t = 0;
    1964 
    1965     int max_n_nz = func->cad_dF_n_nz;
    1966    
    1967     int aim = 0;
    1968     int i = 0;
    1969     int j = 0;
    1970 
    1971     if(JMI_DER_T & independent_vars){
    1972         n_t = 1;
    1973     }
    1974    
    1975     aim+=n_dx;
    1976     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    1977         if(JMI_DER_DX & independent_vars){ 
    1978             col_independent_ind[j] = func->cad_dF_col[i];
    1979             j++;
    1980         }
    1981         i++;
    1982     }
    1983     aim+=n_x;
    1984     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    1985         if(JMI_DER_X & independent_vars){
    1986             col_independent_ind[j] = func->cad_dF_col[i];
    1987             j++;
    1988         }
    1989         i++;
    1990     }
    1991     aim+=n_u;
    1992     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    1993         if(JMI_DER_U & independent_vars){
    1994             col_independent_ind[j] = func->cad_dF_col[i];
    1995             j++;
    1996         }
    1997         i++;
    1998     }
    1999     aim+=n_w;
    2000     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    2001         if(JMI_DER_W & independent_vars){   
    2002             col_independent_ind[j] = func->cad_dF_col[i];
    2003             j++;       
    2004         }
    2005         i++;
    2006     }   
    2007     aim+=n_t;
    2008     while(func->cad_dF_col[i]<aim && aim != 0 && i < max_n_nz){
    2009         if(JMI_DER_T & independent_vars){   
    2010             col_independent_ind[j] = func->cad_dF_col[i];
    2011             j++;       
    2012         }
    2013         i++;
    2014     }
    2015     return 0;
     232    }
    2016233}
    2017234
     
    2048265
    2049266    if (eps == 0.0) {
    2050         if (sw == 1.0){
    2051             if ((ev_ind < 0.0 && rel == JMI_REL_GEQ) || (ev_ind <= 0.0 && rel == JMI_REL_GT) || (ev_ind > 0.0 && rel == JMI_REL_LEQ) || (ev_ind >= 0.0 && rel == JMI_REL_LT)){
     267        if (sw == 1.0) {
     268            if ((ev_ind <  0.0 && rel == JMI_REL_GEQ)   ||
     269                (ev_ind <= 0.0 && rel == JMI_REL_GT)    ||
     270                (ev_ind >  0.0 && rel == JMI_REL_LEQ)   ||
     271                (ev_ind >= 0.0 && rel == JMI_REL_LT))
     272            {
    2052273                sw = 0.0;
    2053274            }
    2054         }else{
    2055             if ((ev_ind >= 0.0 && rel == JMI_REL_GEQ) || (ev_ind > 0.0 && rel == JMI_REL_GT) || (ev_ind <= 0.0 && rel == JMI_REL_LEQ) || (ev_ind < 0.0 && rel == JMI_REL_LT)){
     275        } else {
     276            if ((ev_ind >= 0.0 && rel == JMI_REL_GEQ)   ||
     277                (ev_ind >  0.0 && rel == JMI_REL_GT)    ||
     278                (ev_ind <= 0.0 && rel == JMI_REL_LEQ)   ||
     279                (ev_ind <  0.0 && rel == JMI_REL_LT))
     280            {
    2056281                sw = 1.0;
    2057282            }
    2058283        }
    2059284    } else {
    2060         if (sw == 1.0){
    2061             if ((ev_ind <= -1*eps && rel == JMI_REL_GEQ) || (ev_ind <= 0.0 && rel == JMI_REL_GT) || (ev_ind >= eps && rel == JMI_REL_LEQ) || (ev_ind >= 0.0 && rel == JMI_REL_LT)){
     285        if (sw == 1.0) {
     286            if ((ev_ind <= -eps && rel == JMI_REL_GEQ)  ||
     287                (ev_ind <= 0.0  && rel == JMI_REL_GT)   ||
     288                (ev_ind >= eps  && rel == JMI_REL_LEQ)  ||
     289                (ev_ind >= 0.0  && rel == JMI_REL_LT))
     290            {
    2062291                sw = 0.0;
    2063292            }
    2064         }else{
    2065             if ((ev_ind >= 0.0 && rel == JMI_REL_GEQ) || (ev_ind >= eps && rel == JMI_REL_GT) || (ev_ind <= 0.0 && rel == JMI_REL_LEQ) || (ev_ind <= -1*eps && rel == JMI_REL_LT)){
     293        } else {
     294            if ((ev_ind >= 0.0  && rel == JMI_REL_GEQ)   ||
     295                (ev_ind >= eps  && rel == JMI_REL_GT)    ||
     296                (ev_ind <= 0.0  && rel == JMI_REL_LEQ)   ||
     297                (ev_ind <= -eps && rel == JMI_REL_LT))
     298            {
    2066299                sw = 1.0;
    2067300            }
     
    2077310     * x <  0
    2078311     */
    2079     if (sw == 1.0){
    2080         if ((ev_ind < -eps && rel == JMI_REL_GEQ) || (ev_ind <= eps && rel == JMI_REL_GT)
    2081                 || (ev_ind > eps && rel == JMI_REL_LEQ) || (ev_ind >= -eps && rel == JMI_REL_LT)) {
     312    if (sw == 1.0) {
     313        if ((ev_ind <  -eps && rel == JMI_REL_GEQ)  ||
     314            (ev_ind <=  eps && rel == JMI_REL_GT)   ||
     315            (ev_ind >   eps && rel == JMI_REL_LEQ)  ||
     316            (ev_ind >= -eps && rel == JMI_REL_LT))
     317        {
    2082318            sw = 0.0;
    2083319        }
    2084320    } else {
    2085         if ((ev_ind >= -eps && rel == JMI_REL_GEQ) || (ev_ind > eps && rel == JMI_REL_GT)
    2086                 || (ev_ind <= eps && rel == JMI_REL_LEQ) || (ev_ind < -eps && rel == JMI_REL_LT)) {
     321        if ((ev_ind >= -eps && rel == JMI_REL_GEQ)  ||
     322            (ev_ind >   eps && rel == JMI_REL_GT)   ||
     323            (ev_ind <=  eps && rel == JMI_REL_LEQ)  ||
     324            (ev_ind <  -eps && rel == JMI_REL_LT))
     325        {
    2087326            sw = 1.0;
    2088327        }
    2089328    }
    2090329    return sw;
    2091 }
    2092 
    2093 int jmi_generic_func(jmi_t *jmi, jmi_generic_func_t func) {
    2094     int return_status;
    2095     int depth = jmi_prepare_try(jmi);
    2096     if (jmi_try(jmi, depth))
    2097         return_status = -1;
    2098     else
    2099         return_status = func(jmi);
    2100     jmi_finalize_try(jmi, depth);
    2101     return return_status;
    2102330}
    2103331
  • trunk/RuntimeLibrary/src/jmi/jmi_util.h

    r8736 r8993  
    6767 * the JMI model interface and can be viewed as an object
    6868 * corresponding to a particular model. jmi_t contains dimension
    69  * information of the model and one or several of the structs
    70  * - jmi_dae_t which contains the DAE residual function.
    71  * - jmi_init_t which contains the DAE initialization functions.
    72  * If one of the structs are not present in jmi_t, the corresponding
    73  * pointer is set to NULL.
    74  *
    75  * \section jmi_internal_init Initialization of interal JMI Model \
    76  * interface structs
     69 * information of the model and a struct with function pointer for
     70 * the model equations.
    7771 *
    7872 * Instances of jmi_t are created by a call to ::jmi_new, which is a
     
    8478 *   but no substructs are initialized.
    8579 *   - Then the jmi_dae_t and jmi_init_t structs are
    86  *   initialized by the functions ::jmi_dae_init and ::jmi_init_init
    87  *   respectively. In these function calls, the
    88  *   corresponding function pointers are set and new jmi_func_t
    89  *   structs are created.
    90  *
    91  * Typically, ::jmi_init, ::jmi_dae_init and ::jmi_init_init
    92  * are called from within the ::jmi_new function.
     80 *   initialized by the function ::jmi_model_init. In these function
     81 *   calls, the corresponding function pointers are set and new
     82 *   jmi_func_t structs are created.
     83 *
     84 * Typically, ::jmi_init and ::jmi_model_init are called from within
     85 * the ::jmi_new function.
    9386 *
    9487 */
     
    10295
    10396/* @{ */
    104 
    105 /*
    106  *  TODO: Error codes...
    107  *  Introduce #defines to denote different error codes
    108  */
    109 
    11097
    11198typedef struct _jmi_time_event_t {
     
    121108void jmi_min_time_event(jmi_time_event_t* event, int def, int phase, double time);
    122109
    123 /* Masks for maping vref to indices. */               
    124 #define VREF_INDEX_MASK  0x0FFFFFFF
    125 #define VREF_TYPE_MASK   0xF0000000
    126 #define REAL_TYPE_MASK   0x00000000
    127 #define INT_TYPE_MASK    0x10000000
    128 #define BOOL_TYPE_MASK   0x20000000
    129 #define STR_TYPE_MASK    0x30000000
    130 
    131 /* These are a temporary remnants of CppAD*/           
     110/* This is a temporary remnant of CppAD*/           
    132111#define AD_WRAP_LITERAL(x) ((jmi_real_t) (x))
    133112
     
    173152void jmi_flag_termination(jmi_t *jmi, const char* msg);
    174153
    175 /* @} */
    176 
    177 /**
    178  * \defgroup jmi_function_typedefs Function typedefs
    179  *
    180  * \brief Function signatures to be used in the generated code
    181  */
    182 
    183 /* @{ */
    184 
    185 /**
    186  * \brief A generic function signature that only takes a jmi_t struct as input.
    187  *
    188  * @param jmi A jmi_t struct.
    189  * @return Error code.
    190  */
    191 typedef int (*jmi_generic_func_t)(jmi_t* jmi);
    192 
    193 /**
    194  * \brief A function signature for computation of the next time event.
    195  *
    196  * @param jmi A jmi_t struct.
    197  * @param event (Output) Information about the next time event.
    198  * @return Error code.
    199  */
    200 typedef int (*jmi_next_time_event_func_t)(jmi_t* jmi, jmi_time_event_t* event);
    201 
    202 /**
    203  * \brief Function signature for evaluation of a residual function in
    204  * the generated code.
    205  *
    206  * Notice that this function signature is used for all functions in
    207  * the DAE and DAE initialization interfaces.
    208  *
    209  * @param jmi A jmi_t struct.
    210  * @param res (Output) The residual value.
    211  * @return Error code.
    212  *
    213  */
    214 typedef int (*jmi_residual_func_t)(jmi_t* jmi, jmi_real_t** res);
    215 
    216 /**
    217  * \brief Function signature for evaluation of a directional derivative function
    218  * in the generated code.
    219  *
    220  * Notice that this function signature is used for all functions in
    221  * the DAE and DAE initialization.
    222  *
    223  * @param jmi A jmi_t struct.
    224  * @param res (Output) The residual value vector.
    225  * @param dF (Output) The directional derivative of the residual function.
    226  * @param dz the Seed vector of size n_x + n_x + n_u + n_w.
    227  * @return Error code.
    228  *
    229  */
    230 typedef int (*jmi_directional_der_residual_func_t)(jmi_t* jmi, jmi_real_t** res,
    231         jmi_real_t** dF, jmi_real_t** dz);
    232 
    233 
    234 /**
    235  * \brief Evaluation of symbolic jacobian of a residual function in
    236  * generated code.
    237  *
    238  * Notice that this function signature is used for all functions in
    239  * the DAE and DAE initialization.
    240  *
    241  * @param jmi A jmi_t struct.
    242  * @param sparsity See ::jmi_dae_dF.
    243  * @param independent_vars See ::jmi_dae_dF.
    244  * @param mask See ::jmi_dae_dF.
    245  * @param res (Output) The residual value.
    246  * @return Error code.
    247  */
    248 typedef int (*jmi_jacobian_func_t)(jmi_t* jmi, int sparsity,
    249              int independent_vars, int* mask, jmi_real_t* jac);
    250 
    251 /* @} */
    252 
    253 /**
    254  * \defgroup jmi_func_t The jmi_func_t struct
    255  *
    256  * \brief Functions for creating, deleting and evaluating jmi_func_t
    257  * functions.
    258  *
    259  */
    260 
    261 /* @{ */
    262 
    263 
    264 /**
    265  * \brief Create a new jmi_func_t.
    266  *
    267  * @param jmi_func (Output) A double pointer to a jmi_func_t struct.
    268  * @param F A function pointer to the residual function.
    269  * @param n_eq_F The number of equations in the residual.
    270  * @param sym_dF Function pointer to the symbolic Jacobian function.
    271  * @param sym_dF_n_nz The number of non-zeros in the symbolic Jacobian.
    272  * @param sym_dF_row Row indices of the non-zero elements in the symbolic Jacobian.
    273  * @param sym_dF_col Column indices of the non-zero elements in the symbolic
    274  *        Jacobian.
    275  * @param dir_dF A function pointer to the directional derivative function.
    276  * @param dF_n_nz The number of non-zeros in the AD Jacobian.
    277  * @param dF_row Row indices of the non-zero elements in the AD Jacobian.
    278  * @param dF_col Column indices of the non-zero elements in the AD
    279  *        Jacobian.
    280  * @return Error code.
    281  *
    282  */
    283 int jmi_func_new(jmi_func_t** jmi_func, jmi_residual_func_t F,
    284                  int n_eq_F, jmi_jacobian_func_t sym_dF,
    285                  int sym_dF_n_nz, int* sym_dF_row, int* sym_dF_col,
    286                  jmi_directional_der_residual_func_t cad_dir_dF,
    287                  int cad_dF_n_nz, int* cad_dF_row, int* cad_dF_col);
    288 
    289 /**
    290  * \brief Delete a jmi_func_t.
    291  *
    292  * @param func The jmi_func_t struct to delete.
    293  * @return Error code.
    294  */
    295 int jmi_func_delete(jmi_func_t *func);
    296 
    297 /**
    298  * \brief Evaluate the residual function of a jmi_func_t struct.
    299  *
    300  * @param jmi The jmi_t struct.
    301  * @param func The jmi_func_t struct.
    302  * @param res (Output) The residual values.
    303  * @return Error code.
    304  *
    305  */
    306 int jmi_func_F(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res);
    307 
    308 /**
    309  * \brief Evaluation of the symbolic Jacobian of the
    310  * residual function contained in a jmi_func_t.
    311  *
    312  * @param jmi The jmi_t struct.
    313  * @param func The jmi_func_t struct.
    314  * @param sparsity See ::jmi_dae_dF.
    315  * @param independent_vars See ::jmi_dae_dF.
    316  * @param mask See ::jmi_dae_dF.
    317  * @param jac (Output) The Jacobian
    318  *
    319  */
    320 int jmi_func_sym_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    321         int independent_vars, int* mask, jmi_real_t* jac) ;
    322 
    323 /**
    324  * \brief Returns the number of non-zeros in the symbolic Jacobian.
    325  *
    326  * @param jmi A jmi_t struct.
    327  * @param func The jmi_func_t struct.
    328  * @param n_nz (Output) The number of non-zero Jacobian entries.
    329  * @return Error code.
    330  */
    331 int jmi_func_sym_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz);
    332 
    333 /**
    334  * \brief Returns the row and column indices of the non-zero elements in the
    335  * symbolic residual Jacobian.
    336  *
    337  * @param jmi A jmi_t struct.
    338  * @param func The jmi_func_t struct.
    339  * @param independent_vars See ::jmi_dae_dF.
    340  * @param mask See ::jmi_dae_dF.
    341  * @param row (Output) The row indices of the non-zeros in the DAE residual
    342  *            Jacobian.
    343  * @param col (Output) The column indices of the non-zeros in the DAE residual
    344  *            Jacobian.
    345  * @return Error code.
    346  *
    347  */
    348 int jmi_func_sym_dF_nz_indices(jmi_t *jmi, jmi_func_t *func,
    349                            int independent_vars,
    350                            int *mask, int *row, int *col);
    351 
    352 /**
    353  * \brief Computes the number of columns and the number of non-zero
    354  * elements in the symbolic Jacobian of a jmi_func_t given a sparsity
    355  * configuration.
    356  *
    357  * @param jmi A jmi_t struct.
    358  * @param func The jmi_func_t struct.
    359  * @param sparsity See ::jmi_dae_dF.
    360  * @param independent_vars See ::jmi_dae_dF.
    361  * @param mask See ::jmi_dae_dF.
    362  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    363  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    364  *
    365  */
    366 int jmi_func_sym_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity,
    367                     int independent_vars, int *mask,
    368             int *dF_n_cols, int *dF_n_nz);
    369            
    370 /**
    371  * \brief Evaluate the directional AD derivative of the residual function of
    372  * a jmi_func_t struct, using symbolic differentiation.
    373  *
    374  * @param jmi A jmi_t struct.
    375  * @param func The jmi_func_t struct.
    376  * @param res (Output) The DAE residual vector.
    377  * @param dF (Output) The directional derivative.
    378  * @param dv Seed vector of size n_x + n_x + n_u + n_w.
    379  * @return Error code.
    380  */
    381 
    382 int jmi_func_sym_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    383              jmi_real_t *dF, jmi_real_t* dv);
    384 
    385 /**
    386  * \brief Evaluate the directional AD derivative of the residual function of
    387  * a jmi_func_t struct, using the CAD technique.
    388  *
    389  * @param jmi A jmi_t struct.
    390  * @param func The jmi_func_t struct.
    391  * @param res (Output) The DAE residual vector.
    392  * @param dF (Output) The directional derivative.
    393  * @param dv Seed vector of size n_x + n_x + n_u + n_w.
    394  * @return Error code.
    395  */
    396 int jmi_func_cad_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    397              jmi_real_t *dF, jmi_real_t* dv);
    398 
    399 /**
    400  * \brief Evaluation of the AD Jacobian of the
    401  * residual function contained in a jmi_func_t.
    402  *
    403  * @param jmi The jmi_t struct.
    404  * @param func The jmi_func_t struct.
    405  * @param sparsity See ::jmi_dae_dF.
    406  * @param independent_vars See ::jmi_dae_dF.
    407  * @param mask See ::jmi_dae_dF.
    408  * @param jac (Output) The Jacobian
    409  *
    410  */
    411 
    412 int jmi_func_cad_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    413         int independent_vars, int* mask, jmi_real_t* jac) ;
    414 
    415 /**
    416  * \brief Returns the number of non-zeros in the AD Jacobian.
    417  *
    418  * @param jmi A jmi_t struct.
    419  * @param func The jmi_func_t struct.
    420  * @param n_nz (Output) The number of non-zero Jacobian entries.
    421  * @return Error code.
    422  */
    423 
    424 int jmi_func_cad_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz);
    425 
    426 /**
    427  * \brief Returns the row and column indices of the non-zero elements in the
    428  * AD residual Jacobian.
    429  *
    430  * @param jmi A jmi_t struct.
    431  * @param func The jmi_func_t struct.
    432  * @param independent_vars See ::jmi_dae_dF.
    433  * @param mask See ::jmi_dae_dF.
    434  * @param row (Output) The row indices of the non-zeros in the DAE residual
    435  *            Jacobian.
    436  * @param col (Output) The column indices of the non-zeros in the DAE residual
    437  *            Jacobian.
    438  * @return Error code.
    439  *
    440  */
    441  
    442 int jmi_func_cad_dF_nz_indices(jmi_t *jmi, jmi_func_t *func,
    443                            int independent_vars,
    444                            int *mask, int *row, int *col);
    445                          
    446 
    447 /**
    448  * \brief Computes the number of columns and the number of non-zero
    449  * elements in the AD Jacobian of a jmi_func_t given a sparsity
    450  * configuration.
    451  *
    452  * @param jmi A jmi_t struct.
    453  * @param func The jmi_func_t struct.
    454  * @param sparsity See ::jmi_dae_dF.
    455  * @param independent_vars See ::jmi_dae_dF.
    456  * @param mask See ::jmi_dae_dF.
    457  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    458  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    459  *
    460  */
    461 
    462 int jmi_func_cad_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity,
    463                     int independent_vars, int *mask,
    464             int *dF_n_cols, int *dF_n_nz);
    465 
    466 /**
    467  * \brief Evaluate the directional finite difference derivative of the residual function of
    468  * a jmi_func_t struct.
    469  *
    470  * @param jmi A jmi_t struct.
    471  * @param func The jmi_func_t struct.
    472  * @param res (Output) The DAE residual vector.
    473  * @param dF (Output) The directional derivative.
    474  * @param dv Seed vector of size n_x + n_x + n_u + n_w.
    475  * @return Error code.
    476  */
    477 
    478 int jmi_func_fd_directional_dF(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res,
    479              jmi_real_t *dF, jmi_real_t* dv);
    480 
    481 /**
    482  * \brief Evaluation of the finite difference Jacobian of the
    483  * residual function contained in a jmi_func_t.
    484  *
    485  * @param jmi The jmi_t struct.
    486  * @param func The jmi_func_t struct.
    487  * @param sparsity See ::jmi_dae_dF.
    488  * @param independent_vars See ::jmi_dae_dF.
    489  * @param mask See ::jmi_dae_dF.
    490  * @param jac (Output) The Jacobian
    491  *
    492  */
    493 
    494 int jmi_func_fd_dF(jmi_t *jmi,jmi_func_t *func, int sparsity,
    495         int independent_vars, int* mask, jmi_real_t* jac) ;
    496 
    497 /**
    498  * \brief Returns the number of non-zeros in the finite difference Jacobian.
    499  *
    500  * @param jmi A jmi_t struct.
    501  * @param func The jmi_func_t struct.
    502  * @param n_nz (Output) The number of non-zero Jacobian entries.
    503  * @return Error code.
    504  */
    505 
    506 int jmi_func_fd_dF_n_nz(jmi_t *jmi, jmi_func_t *func, int* n_nz);
    507 
    508 /**
    509  * \brief Returns the row and column indices of the non-zero elements in the
    510  * finite difference residual Jacobian.
    511  *
    512  * @param jmi A jmi_t struct.
    513  * @param func The jmi_func_t struct.
    514  * @param independent_vars See ::jmi_dae_dF.
    515  * @param mask See ::jmi_dae_dF.
    516  * @param row (Output) The row indices of the non-zeros in the DAE residual
    517  *            Jacobian.
    518  * @param col (Output) The column indices of the non-zeros in the DAE residual
    519  *            Jacobian.
    520  * @return Error code.
    521  *
    522  */
    523 
    524 int jmi_func_fd_dF_nz_indices(jmi_t *jmi, jmi_func_t *func,
    525                            int independent_vars,
    526                            int *mask, int *row, int *col);
    527 
    528 /**
    529  * \brief Computes the number of columns and the number of non-zero
    530  * elements in the finite difference Jacobian of a jmi_func_t given a sparsity
    531  * configuration.
    532  *
    533  * @param jmi A jmi_t struct.
    534  * @param func The jmi_func_t struct.
    535  * @param sparsity See ::jmi_dae_dF.
    536  * @param independent_vars See ::jmi_dae_dF.
    537  * @param mask See ::jmi_dae_dF.
    538  * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
    539  * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
    540  *
    541  */
    542 
    543 int jmi_func_fd_dF_dim(jmi_t *jmi, jmi_func_t *func, int sparsity,
    544                     int independent_vars, int *mask,
    545             int *dF_n_cols, int *dF_n_nz);
    546 
    547154/**< \brief Run-time options. */
    548155typedef struct jmi_options_t {
     
    597204    else init_with_ubound(x, xmax, message)
    598205
    599 /**
    600  * \brief Data structure for representing a single function
    601  * \f$F(z)\f$.
    602  *
    603  * jmi_func_t is a struct that contains function pointers and
    604  * dimension information corresponding to a mathematical vector valued
    605  * function, \f$F(z)\f$. The struct also contains function pointers to
    606  * symbolic Jacobians and associated sparsity information.
    607  */
    608 struct jmi_func_t {
    609     jmi_residual_func_t F;        /**< \brief Pointer to a function for evaluation of \f$F(z)\f$. */
    610     jmi_jacobian_func_t sym_dF;   /**< \brief Pointer to a function for evaluation of the symbolic Jacobian of \f$F(z)\f$. */
    611     jmi_directional_der_residual_func_t cad_dir_dF; /**< \brief Pointer to a function for evaluation of the directional AD derivative of the function */
    612     int n_eq_F;                   /**< \brief Size of the function. */
    613     int sym_dF_n_nz;              /**< \brief Number of non-zeros in the symbolic Jacobian of \f$F(z)\f$ (if available). */
    614     int* sym_dF_row;              /**< \brief Row indices of the non-zero elements in the symbolic Jacobian of \f$F(z)\f$ (if available). */
    615     int* sym_dF_col;              /**< \brief Column indices of the non-zero elements in the symbolic Jacobian of \f$F(z)\f$ (if available). */
    616     int cad_dF_n_nz;              /**< \brief Number of non-zeros in the AD Jacobian of \f$F(z)\f$ (if available). */
    617     int* cad_dF_row;              /**< \brief Row indices of the non-zero elements in the AD Jacobian of \f$F(z)\f$ (if available). */
    618     int* cad_dF_col;              /**< \brief Column indices of the non-zero elements in the AD Jacobian of \f$F(z)\f$ (if available). */
    619     int coloring_counter;         /**< \brief Number of times that the graph coloring algorithm  has been performed. */
    620     int* coloring_done;           /**< \brief Contains info of which independent_vars that the graph_coloring algorithm has been done. */
    621     jmi_color_info** c_info;      /**< \brief Vector of jmi_graph_coloring struct, contains graph coloring results for every independent_vars that has been performed  */
    622    
    623 };
    624 
    625 /**
    626  * \brief Contains result of a graph coloring.
    627  */
    628 struct jmi_color_info {
    629     int* sparse_repr;
    630     int* offs;
    631     int n_colors;
    632     int* map_info;
    633     int* map_off;
    634 };
    635 
    636 struct jmi_simple_color_info_t {
    637     int n_nz;                       /**< \brief Number of non-zeros. */
    638     int n_cols;                     /**< \brief Number of columns */
    639     int* col_n_nz;                  /**< \brief Number of non-zeros in each column */
    640     int col_offset;                 /**< \brief Column offset (in some cases, column indexing does not start at zero)*/
    641     int* rows;                      /**< \brief Row indices. */
    642     int* cols;                      /**< \brief Column indices. */
    643     int* col_start_index;           /**< \brief Column start indices (incidence patterns are stored column major)*/
    644     int n_groups;                   /**< \brief Number of groups in the CPR seeding. */
    645     int n_cols_in_grouping;         /**< \brief Total number of columns used in CPR seeding computation. */
    646     int* n_cols_in_group;           /**< \brief The number of column in each CPR group. */
    647     int* group_cols;                /**< \brief An ordered array of column indices corresponding to CPR groups. */
    648     int* group_start_index;         /**< \brief An array containing the start indices for each group in the array group_cols. */
    649 };
    650206
    651207/* @} */
    652208
    653209/**
    654  * \defgroup jmi_structs_init The jmi_t, jmi_dae_t and jmi_init_t
    655  *
    656  * \brief Functions for initialization of the jmi_t, jmi_dae_t and
    657  * jmi_init_t.
     210 * \defgroup Access Setters and getters for the fields in jmi_t
     211 *
     212 * \brief The fields of jmi_t are conveniently accessed using the setter and getter
     213 * functions provided in the JMI Model interface.
     214 *
     215 * Notice that it is not recommended to access the fields directely, since the internal
     216 * implementation of jmi_t may change, wheras the setters and getters are less likely to
     217 * do so.
    658218 *
    659219 */
     
    662222
    663223/**
    664  * \brief Allocates memory and sets up the jmi_t struct.
    665  *
    666  * This function is typically called from within jmi_new in the generated code.
    667  * The reason for introducing this function is that the allocation of the
    668  * jmi_t struct should not be repeated in the generated code.
    669  *
    670  * @param jmi (Output) A pointer to a jmi_t pointer.
    671  * @param n_real_ci Number of real independent constants.
    672  * @param n_real_cd Number of real dependent constants.
    673  * @param n_real_pi Number of real independent parameters.
    674  * @param n_real_pd Number of real dependent parameters.
    675  * @param n_integer_ci Number of integer independent constants.
    676  * @param n_integer_cd Number of integer dependent constants.
    677  * @param n_integer_pi Number of integer independent parameters.
    678  * @param n_integer_pd Number of integer dependent parameters.
    679  * @param n_boolean_ci Number of boolean independent constants.
    680  * @param n_boolean_cd Number of boolean dependent constants.
    681  * @param n_boolean_pi Number of boolean independent parameters.
    682  * @param n_boolean_pd Number of boolean dependent parameters.
    683  * @param n_real_dx Number of real derivatives.
    684  * @param n_real_x Number of real differentiated variables.
    685  * @param n_real_u Number of real inputs.
    686  * @param n_real_w Number of real algebraics.
    687  * @param n_real_d Number of real discrete parameters.
    688  * @param n_integer_d Number of integer discrete parameters.
    689  * @param n_integer_u Number of integer inputs.
    690  * @param n_boolean_d Number of boolean discrete parameters.
    691  * @param n_boolean_u Number of boolean inputs.
    692  * @param n_outputs Number of outputs.
    693  * @param output_vrefs Value references of the outputs.
    694  * @param n_sw Number of switching functions in DAE \$fF\$f.
    695  * @param n_sw_init Number of switching functions in DAE initialization system \$fF_0\$f.
    696  * @param n_guards Number of guards in DAE \$fF\$f.
    697  * @param n_guards_init Number of guards in DAE initialization system \$fF_0\$f.
    698  * @param n_dae_blocks Number of DAE blocks.
    699  * @param n_dae_init_blocks Number of DAE initialization blocks.
    700  * @param n_initial_relations Number of relational operators in the initial equations.
    701  * @param initial_relations Kind of relational operators in the initial equations. One of JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ.
    702  * @param n_relations Number of relational operators in the DAE equations.
    703  * @param relations Kind of relational operators in the DAE equations. One of: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ.
    704  * @param scaling_method Scaling method. Options are JMI_SCALING_NONE or JMI_SCALING_VARIABLES.
    705  * @param homotopy_block Block number of the block which contains homotopy operators, -1 if none.
    706  * @param jmi_callbacks A jmi_callback_t struct.
     224 * \brief Copy variable values to the pre vector.
     225 *
     226 * @param jmi The jmi_t struct.
    707227 * @return Error code.
    708228 */
    709 int jmi_init(jmi_t** jmi,
    710         int n_real_ci, int n_real_cd, int n_real_pi,
    711         int n_real_pi_s, int n_real_pi_f, int n_real_pi_e, int n_real_pd,
    712         int n_integer_ci, int n_integer_cd, int n_integer_pi,
    713         int n_integer_pi_s, int n_integer_pi_f, int n_integer_pi_e, int n_integer_pd,
    714         int n_boolean_ci, int n_boolean_cd, int n_boolean_pi,
    715         int n_boolean_pi_s, int n_boolean_pi_f, int n_boolean_pi_e, int n_boolean_pd,
    716         int n_real_dx, int n_real_x, int n_real_u, int n_real_w,
    717         int n_real_d, int n_integer_d, int n_integer_u,
    718         int n_boolean_d, int n_boolean_u,
    719         int n_outputs, int* output_vrefs,
    720         int n_sw, int n_sw_init, int n_time_sw, int n_state_sw,
    721         int n_guards, int n_guards_init,
    722         int n_dae_blocks, int n_dae_init_blocks,
    723         int n_initial_relations, int* initial_relations,
    724         int n_relations, int* relations, int n_dynamic_state_sets,
    725         jmi_real_t* nominals,
    726         int scaling_method, int n_ext_objs, int homotopy_block,
    727         jmi_callbacks_t* jmi_callbacks);
    728 
    729 /**
    730  * \brief Allocates a jmi_dae_t struct.
    731  *
    732  * @param jmi A jmi_t struct.
    733  * @param F A function pointer to the DAE residual function.
    734  * @param n_eq_F Number of equations in the DAE residual.
    735  * @param sym_dF Function pointer to the symbolic Jacobian function.
    736  * @param sym_dF_n_nz Number of non-zeros in the symbolic jacobian.
    737  * @param sym_dF_row Row indices of the non-zeros in the symbolic Jacobian.
    738  * @param sym_dF_col Column indices of the non-zeros in the symbolic Jacobian.
    739  * @param cad_dir_dF A function pointer for evaluation of the AD generated directional
    740  *               derivative for the DAE residual function.
    741  * @param cad_dF_n_nz Number of non-zeros in the AD jacobian.
    742  * @param cad_dF_row Row indices of the non-zeros in the AD Jacobian.
    743  * @param cad_dF_col Column indices of the non-zeros in the AD Jacobian.
    744  * @param cad_A_n_nz Number of non-zeros in the ODE AD Jacobian A.
    745  * @param cad_A_row Row indices of the non-zeros in the ODE AD Jacobian A.
    746  * @param cad_A_col Column indices of the non-zeros in the ODE AD Jacobian A.
    747  * @param cad_B_n_nz Number of non-zeros in the ODE AD Jacobian B.
    748  * @param cad_B_row Row indices of the non-zeros in the ODE AD Jacobian B.
    749  * @param cad_B_col Column indices of the non-zeros in the ODE AD Jacobian B.
    750  * @param cad_C_n_nz Number of non-zeros in the ODE AD Jacobian C.
    751  * @param cad_C_row Row indices of the non-zeros in the ODE AD Jacobian C.
    752  * @param cad_C_col Column indices of the non-zeros in the ODE AD Jacobian C.
    753  * @param cad_D_n_nz Number of non-zeros in the ODE AD Jacobian D.
    754  * @param cad_D_row Row indices of the non-zeros in the ODE AD Jacobian D.
    755  * @param cad_D_col Column indices of the non-zeros in the ODE AD Jacobian D.
    756  * @param R A function pointer to the DAE event indicator residual function.
    757  * @param n_eq_R Number of equations in the event indicator function.
    758  * @param dR Function pointer to the symbolic Jacobian function.
    759  * @param dR_n_nz Number of non-zeros in the symbolic jacobian.
    760  * @param dR_row Row indices of the non-zeros in the symbolic Jacobian.
    761  * @param dR_col Column indices of the non-zeros in the symbolic Jacobian.
    762  * @param ode_derivatives A function pointer to the ODE RHS function.
    763  * @param ode_derivatives_dir_der A function pointer to the ODE directional derivative function.
    764  * @param ode_outputs A function pointer to the ODE output function.
    765  * @param ode_initialize A function pointer to the ODE initialization function.
    766  * @param ode_guards A function pointer for evaluating the guard expressions.
    767  * @param ode_guards_init A function pointer for evaluating the guard expressions.
    768  *        in the initial equations.
    769  * @return Error code.
    770  */
    771 int jmi_dae_init(jmi_t* jmi, jmi_residual_func_t F, int n_eq_F,
    772         jmi_jacobian_func_t sym_dF, int sym_dF_n_nz, int* sym_dF_row, int* sym_dF_col,
    773         jmi_directional_der_residual_func_t cad_dir_dF,
    774         int cad_dF_n_nz, int* cad_dF_row, int* cad_dF_col,
    775         int cad_A_n_nz, int* cad_A_row, int* cad_A_col,
    776         int cad_B_n_nz, int* cad_B_row, int* cad_B_col,
    777         int cad_C_n_nz, int* cad_C_row, int* cad_C_col,
    778         int cad_D_n_nz, int* cad_D_row, int* cad_D_col,
    779         jmi_residual_func_t R, int n_eq_R,
    780         jmi_jacobian_func_t dR, int dR_n_nz, int* dR_row, int* dR_col,
    781         jmi_generic_func_t ode_derivatives,
    782         jmi_generic_func_t ode_derivatives_dir_der,
    783         jmi_generic_func_t ode_outputs,
    784         jmi_generic_func_t ode_initialize,
    785         jmi_generic_func_t ode_guards,
    786         jmi_generic_func_t ode_guards_init,
    787         jmi_next_time_event_func_t ode_next_time_event);
    788 
    789 /**
    790  * \brief Allocates memory for the contents of a jmi_simple_color_info struct
    791  *
    792  * @param c_info A jmi_simple_color_info struct
    793  * @param n_cols, Number of columns in Jacobian
    794  * @param n_cols_in_grouping, Number of columns to include in the coloring
    795  * @param n_nz, Number of non-zeros
    796  * @param rows, Row indices of non-zero elements
    797  * @param cols, Column indices of non-zero elements
    798  * @param col_offset, Offset of the first column to include in the coloring
    799  * @param one_indexing If 1, then assume FORTRAN style 1-indexing, if 0 assume C style 0-indexing
    800  *
    801  * @return Error code
    802  */
    803 int jmi_new_simple_color_info(jmi_simple_color_info_t** c_info, int n_cols, int n_cols_in_grouping, int n_nz,
    804         int* rows, int* cols, int col_offset, int one_indexing);
    805 
    806 /**
    807  * \brief Deletes the contents of a jmi_simple_color_info struct
    808  *
    809  * @param c_info A jmi_color_info struct
    810  * @return Error code
    811  */
    812 void jmi_delete_simple_color_info(jmi_simple_color_info_t **c_info_ptr);
    813 
    814 /**
    815  * \brief Allocates memory for the contents of a jmi_color_info struct
    816  *
    817  * @param c_info A jmi_color_info struct
    818  * @param dF_n_cols, number of columns
    819  * @param dF_n_nz, number of non-zeros
    820  *
    821  * @return Error code
    822  */
    823 int jmi_new_color_info(jmi_color_info** c_info, int dF_n_cols, int dF_n_nz);
    824 
    825 /**
    826  * \brief Deletes the contents of a jmi_color_info struct
    827  *
    828  * @param c_i A jmi_color_info struct
    829  * @return Error code
    830  */
    831 int jmi_delete_color_info(jmi_color_info *c_i);
    832 
    833 /**
    834  * \brief Allocates a jmi_init_t struct.
    835  *
    836  * @param jmi A jmi_t struct.
    837  * @param F0 A function pointer to the DAE initialization residual function
    838  * \f$F_0\f$.
    839  * @param n_eq_F0 Number of equations in the DAE initialization residual
    840  *        function \f$F_0\f$.
    841  * @param dF0 Function pointer to the symbolic Jacobian of \f$F_0\f$.
    842  * @param dF0_n_nz Number of non-zeros in the symbolic jacobian of \f$F_0\f$.
    843  * @param dF0_row Row indices of the non-zeros in the symbolic Jacobian
    844  *        of \f$F_0\f$.
    845  * @param dF0_col Column indices of the non-zeros in the symbolic Jacobian
    846  *        of \f$F_0\f$.
    847  * @param F1 A function pointer to the DAE initialization residual function
    848  * \f$F_1\f$.
    849  * @param n_eq_F1 Number of equations in the DAE initialization residual
    850  *        function \f$F_1\f$.
    851  * @param dF1 Function pointer to the symbolic Jacobian of \f$F_1\f$.
    852  * @param dF1_n_nz Number of non-zeros in the symbolic jacobian of \f$F_1\f$.
    853  * @param dF1_row Row indices of the non-zeros in the symbolic Jacobian
    854  *        of \f$F_1\f$.
    855  * @param dF1_col Column indices of the non-zeros in the symbolic Jacobian
    856  *        of \f$F_1\f$.
    857  * @param Fp A function pointer to the DAE initialization residual function
    858  * \f$F_p\f$.
    859  * @param n_eq_Fp Number of equations in the DAE initialization residual
    860  *        function \f$F_p\f$.
    861  * @param dFp Function pointer to the symbolic Jacobian of \f$F_p\f$.
    862  * @param dFp_n_nz Number of non-zeros in the symbolic jacobian of \f$F_p\f$.
    863  * @param dFp_row Row indices of the non-zeros in the symbolic Jacobian
    864  *        of \f$F_p\f$.
    865  * @param dFp_col Column indices of the non-zeros in the symbolic Jacobian
    866  *        of \f$F_p\f$.
    867  * @param R0 A function pointer to the DAE event indicator residual function.
    868  * @param n_eq_R0 Number of equations in the event indicator function.
    869  * @param dR0 Function pointer to the symbolic Jacobian function.
    870  * @param dR0_n_nz Number of non-zeros in the symbolic jacobian.
    871  * @param dR0_row Row indices of the non-zeros in the symbolic Jacobian.
    872  * @param dR0_col Column indices of the non-zeros in the symbolic Jacobian.
    873  * @return Error code.
    874  *
    875  */
    876 int jmi_init_init(jmi_t* jmi, jmi_residual_func_t F0, int n_eq_F0,
    877           jmi_jacobian_func_t dF0,
    878           int dF0_n_nz, int* dF0_row, int* dF0_col,
    879           jmi_residual_func_t F1, int n_eq_F1,
    880           jmi_jacobian_func_t dF1,
    881           int dF1_n_nz, int* dF1_row, int* dF1_col,
    882           jmi_residual_func_t Fp, int n_eq_Fp,
    883           jmi_jacobian_func_t dFp,
    884           int dFp_n_nz, int* dFp_row, int* dFp_col,
    885           jmi_generic_func_t eval_parameters,
    886           jmi_residual_func_t R0, int n_eq_R0,
    887           jmi_jacobian_func_t dR0,
    888           int dR0_n_nz, int* dR0_row, int* dR0_col);
    889 
    890 /**
    891  * \brief Frees memory from jmi_init_t struct.
    892  *
    893  * @param init is the pointer to init field in jmi. It's set to NULL on return.
    894  */
    895 void jmi_delete_init(jmi_init_t** pinit);
    896 
    897 /**
    898  * \brief Contains a pointers to the runtime modules.
    899  */
    900 struct jmi_modules_t {
    901     jmi_module_t *mod_get_set;
    902 
    903     /* Add future modules here */
    904 };
    905 
    906 typedef struct jmi_z_offsets {
    907     int o_ci, o_cd, o_pi, o_pd, o_ps, o_pf, o_pe;
    908     int n_ci, n_cd, n_pi, n_pd, n_ps, n_pf, n_pe, n;
    909 } jmi_z_offsets_t;
    910 
    911 typedef struct jmi_z_strings {
    912     char** values;
    913     jmi_z_offsets_t offsets;
    914 } jmi_z_strings_t;
    915 
    916 typedef struct jmi_z {
    917     jmi_z_strings_t strings;
    918 } jmi_z_t;
    919 
    920 /**
    921  * \brief The main struct of the JMI Model interface containing
    922  * dimension information and pointers to jmi_dae_t and jmi_init_t.
    923  *
    924  * jmi_t is the main struct in the JMI model interface. It contains
    925  * pointers to structs of types jmi_dae_t and jmi_init_t to represent
    926  * the DAE, DAE initialization and Optimization interfaces.
    927  */
    928 struct jmi_t {
    929     jmi_callbacks_t jmi_callbacks;      /**< \brief Struct containing callbacks the jmi runtime needs. */
    930 
    931     jmi_dae_t* dae;                      /**< \brief A jmi_dae_t struct pointer. */
    932     jmi_init_t* init;                    /**< \brief A jmi_init_t struct pointer. */
    933    
    934     jmi_generic_func_t init_delay;       /**< \brief Function for initializing delay structures. */
    935     jmi_generic_func_t sample_delay;       /**< \brief Function for initializing delay structures. */
    936 
    937     jmi_z_t z_t;
    938 
    939     int n_real_ci;                       /**< \brief Number of independent constants. */
    940     int n_real_cd;                       /**< \brief Number of dependent constants. */
    941     int n_real_pi;                       /**< \brief Number of independent parameters. */
    942     int n_real_pd;                       /**< \brief Number of dependent parameters. */
    943 
    944     int n_integer_ci;                    /**< \brief Number of integer independent constants. */
    945     int n_integer_cd;                    /**< \brief Number of integer dependent constants. */
    946     int n_integer_pi;                    /**< \brief Number of integer independent parameters. */
    947     int n_integer_pd;                    /**< \brief Number of integer dependent parameters. */
    948 
    949     int n_boolean_ci;                    /**< \brief Number of boolean independent constants. */
    950     int n_boolean_cd;                    /**< \brief Number of boolean dependent constants. */
    951     int n_boolean_pi;                    /**< \brief Number of boolean independent parameters. */
    952     int n_boolean_pd;                    /**< \brief Number of boolean dependent parameters. */
    953 
    954     int n_real_dx;                       /**< \brief Number of derivatives. */
    955     int n_real_x;                        /**< \brief Number of differentiated states. */
    956     int n_real_u;                        /**< \brief Number of inputs. */
    957     int n_real_w;                        /**< \brief Number of algebraics. */
    958 
    959     int n_real_d;                        /**< \brief Number of discrete variables. */
    960 
    961     int n_integer_d;                     /**< \brief Number of integer discrete variables. */
    962     int n_integer_u;                     /**< \brief Number of integer inputs. */
    963 
    964     int n_boolean_d;                     /**< \brief Number of boolean discrete variables. */
    965     int n_boolean_u;                     /**< \brief Number of boolean inputs. */
    966 
    967     int n_outputs;                       /** \brief Number of output variables. */
    968 
    969     int *output_vrefs;                   /** \brief Value references of the output variables. */
    970 
    971     int n_sw;                            /**< \brief Number of switching functions in the DAE \f$F\f$. */
    972     int n_sw_init;                       /**< \brief Number of switching functions in the DAE initialization system\f$F_0\f$. */
    973     int n_time_sw;                       /**< \brief Number of switches related to time events in the DAE \f$F\f$. */
    974     int n_state_sw;                      /**< \brief Number of switches related to state events in the DAE \f$F\f$. */
    975 
    976     int n_guards;                        /**< \brief Number of guards in the DAE \f$F\f$. */
    977     int n_guards_init;                   /**< \brief Number of guards in the DAE initialization system\f$F_0\f$. */
    978 
    979     int n_v;                             /**< \brief Number of elements in \f$v\f$. Number of equations??*/
    980 
    981     int n_z;                             /**< \brief Number of elements in \f$z\f$. */
    982    
    983     int n_dae_blocks;                    /**< \brief Number of BLT blocks. */
    984     int n_dae_init_blocks;               /**< \brief Number of initial BLT blocks. */
    985 
    986     int n_delays;                        /**< \brief Number of (fixed and variable time) delay blocks. */
    987     int n_spatialdists;                  /**< \brief Number of spatialDistribution blocks. */
    988 
    989     /* Offset variables in the z vector, for convenience. */
    990     /* Structural, final, and evaluated parameters "_pi_s", "_ip_f", and
    991      * "_pi_e" are subsets of independent parameters "_pi"
    992      * and their offsets are only used for generating error messages */
    993     int offs_real_ci;                    /**< \brief  Offset of the independent real constant vector in \f$z\f$. */
    994     int offs_real_cd;                    /**< \brief  Offset of the dependent real constant vector in \f$z\f$. */
    995     int offs_real_pi;                    /**< \brief  Offset of the independent real parameter vector in \f$z\f$. */
    996     int offs_real_pi_s;                  /**< \brief  Offset of the structural real parameter vector in \f$z\f$. */
    997     int offs_real_pi_f;                  /**< \brief  Offset of the final real parameter vector in \f$z\f$. */
    998     int offs_real_pi_e;                  /**< \brief  Offset of the evaluated real parameter vector in \f$z\f$. */
    999     int offs_real_pd;                    /**< \brief  Offset of the dependent real parameter vector in \f$z\f$. */
    1000 
    1001     int offs_integer_ci;                 /**< \brief  Offset of the independent integer constant vector in \f$z\f$. */
    1002     int offs_integer_cd;                 /**< \brief  Offset of the dependent integer constant vector in \f$z\f$. */
    1003     int offs_integer_pi;                 /**< \brief  Offset of the independent integer parameter vector in \f$z\f$. */
    1004     int offs_integer_pi_s;               /**< \brief  Offset of the structural integer parameter vector in \f$z\f$. */
    1005     int offs_integer_pi_f;               /**< \brief  Offset of the final integer parameter vector in \f$z\f$. */
    1006     int offs_integer_pi_e;               /**< \brief  Offset of the evaluated integer parameter vector in \f$z\f$. */
    1007     int offs_integer_pd;                 /**< \brief  Offset of the dependent integer parameter vector in \f$z\f$. */
    1008 
    1009     int offs_boolean_ci;                 /**< \brief  Offset of the independent boolean constant vector in \f$z\f$. */
    1010     int offs_boolean_cd;                 /**< \brief  Offset of the dependent boolean constant vector in \f$z\f$. */
    1011     int offs_boolean_pi;                 /**< \brief  Offset of the independent boolean parameter vector in \f$z\f$. */
    1012     int offs_boolean_pi_s;               /**< \brief  Offset of the structural boolean parameter vector in \f$z\f$. */
    1013     int offs_boolean_pi_f;               /**< \brief  Offset of the final boolean parameter vector in \f$z\f$. */
    1014     int offs_boolean_pi_e;               /**< \brief  Offset of the evaluated boolean parameter vector in \f$z\f$. */
    1015     int offs_boolean_pd;                 /**< \brief  Offset of the dependent boolean parameter vector in \f$z\f$. */
    1016 
    1017     int offs_real_dx;                    /**< \brief  Offset of the derivative real vector in \f$z\f$. */
    1018     int offs_real_x;                     /**< \brief  Offset of the differentiated real variable vector in \f$z\f$. */
    1019     int offs_real_u;                     /**< \brief  Offset of the input real vector in \f$z\f$. */
    1020     int offs_real_w;                     /**< \brief  Offset of the algebraic real variables vector in \f$z\f$. */
    1021     int offs_t;                          /**< \brief  Offset of the time entry in \f$z\f$. */
    1022     int offs_homotopy_lambda;            /**< \brief  Offset of the homotopy lambda entry in \f$z\f$. */
    1023 
    1024     int offs_real_d;                     /**< \brief  Offset of the discrete real variable vector in \f$z\f$. */
    1025 
    1026     int offs_integer_d;                  /**< \brief  Offset of the discrete integer variable vector in \f$z\f$. */
    1027     int offs_integer_u;                  /**< \brief  Offset of the input integer vector in \f$z\f$. */
    1028 
    1029     int offs_boolean_d;                  /**< \brief  Offset of the discrete boolean variable vector in \f$z\f$. */
    1030     int offs_boolean_u;                  /**< \brief  Offset of the input boolean vector in \f$z\f$. */
    1031 
    1032     int offs_sw;                         /**< \brief  Offset of the first switching function in the DAE \f$F\f$ */
    1033     int offs_sw_init;                    /**< \brief  Offset of the first switching function in the DAE initialization system \f$F_0\f$ */
    1034     int offs_state_sw;                   /**< \brief  Offset of the first switching function (state) in the DAE \f$F\f$ */
    1035     int offs_time_sw;                    /**< \brief  Offset of the first switching function (time) in the DAE \f$F\f$ */
    1036 
    1037     int offs_guards;                     /**< \brief  Offset of the first guard \f$F\f$ */
    1038     int offs_guards_init;                /**< \brief  Offset of the first guard in the DAE initialization system \f$F_0\f$ */
    1039 
    1040     int offs_pre_real_dx;                /**< \brief  Offset of the pre derivative real vector in \f$z\f$. */
    1041     int offs_pre_real_x;                 /**< \brief  Offset of the pre differentiated real variable vector in \f$z\f$. */
    1042     int offs_pre_real_u;                 /**< \brief  Offset of the pre input real vector in \f$z\f$. */
    1043     int offs_pre_real_w;                 /**< \brief  Offset of the pre algebraic real variables vector in \f$z\f$. */
    1044 
    1045     int offs_pre_real_d;                 /**< \brief  Offset of the pre discrete real variable vector in \f$z\f$. */
    1046 
    1047     int offs_pre_integer_d;              /**< \brief  Offset of the pre discrete integer variable vector in \f$z\f$. */
    1048     int offs_pre_integer_u;              /**< \brief  Offset of the pre input integer vector in \f$z\f$. */
    1049 
    1050     int offs_pre_boolean_d;              /**< \brief  Offset of the pre discrete boolean variable vector in \f$z\f$. */
    1051     int offs_pre_boolean_u;              /**< \brief  Offset of the pre input boolean vector in \f$z\f$. */
    1052 
    1053     int offs_pre_sw;                     /**< \brief  Offset of the first pre switching function in the DAE \f$F\f$ */
    1054     int offs_pre_sw_init;                /**< \brief  Offset of the first pre switching function in the DAE initialization system \f$F_0\f$ */
    1055 
    1056     int offs_pre_guards;                 /**< \brief  Offset of the first pre guard \f$F\f$ */
    1057     int offs_pre_guards_init;            /**< \brief  Offset of the first pre guard in the DAE initialization system \f$F_0\f$ */
    1058 
    1059     jmi_real_t** z;                      /**< \brief  This vector contains the actual values. */
    1060     jmi_real_t** z_last;                 /**< \brief  This vector contains the values from the last successful integration step. */
    1061     jmi_real_t** dz;                     /**< \brief  This vector is used to store calculated directional derivatives */
    1062     int dz_active_index;                 /**< \brief The element in dz_active_variables to be used (0..JMI_ACTIVE_VAR_BUFS_NUM). Needed for local iterations */
    1063     int block_level;                     /**< \brief Block level for nested equation blocks. Currently 0 or 1. */
    1064     jmi_real_t *dz_active_variables[1];  /**< \brief  This vector is used to store seed-values for active variables in block Jacobians */
    1065 #define JMI_ACTIVE_VAR_BUFS_NUM 3
    1066     jmi_real_t *dz_active_variables_buf[JMI_ACTIVE_VAR_BUFS_NUM];  /**< \brief  This vector is the buffer used by dz_active_variables */
    1067     void** ext_objs;                     /**< \brief This vector contains the external object pointers. */
    1068    
    1069     jmi_real_t* nominals;                             /**< \brief Nominal values of differentiated states. */
    1070     jmi_real_t *variable_scaling_factors;             /**< \brief Scaling factors. For convenience the vector has the same size as z but only scaling of reals are used. */
    1071     int scaling_method;                               /**< \brief Scaling method: JMI_SCALING_NONE, JMI_SCALING_VARIABLES */
    1072     jmi_block_residual_t** dae_block_residuals;       /**< \brief A vector of function pointers to DAE equation blocks */
    1073     jmi_block_residual_t** dae_init_block_residuals;  /**< \brief A vector of function pointers to DAE initialization equation blocks */
    1074     int cached_block_jacobians;                       /**< \brief This flag indicates weather the Jacobian needs to be refactorized */
    1075 
    1076     jmi_delay_t *delays;                 /**< \brief Delay blocks (fixed and variable time) */
    1077     jmi_spatialdist_t *spatialdists;     /**< \brief spatialDistribution blocks */
    1078     jmi_boolean delay_event_mode;        /**< \brief Controls operation of `jmi_delay_record_sample` and `jmi_spatialdist_record_sample` */
    1079    
    1080     jmi_dynamic_state_set_t* dynamic_state_sets; /**< \brief Struct for the list of dynamic state sets */
    1081     jmi_int_t n_dynamic_state_sets;              /**< \brief Number of set of dynamic state variables */
    1082 
    1083     jmi_int_t n_initial_relations;       /**< \brief Number of relational operators used in the event indicators for the initialization system. There should be the same number of initial relations as there are event indicators */
    1084     jmi_int_t* initial_relations;        /**< \brief Kind of relational operators used in the event indicators for the initialization system: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ */
    1085     jmi_int_t n_relations;               /**< \brief Number of relational operators used in the event indicators for the DAE system */
    1086     jmi_int_t* relations;                /**< \brief Kind of relational operators used in the event indicators for the DAE system: JMI_REL_GT, JMI_REL_GEQ, JMI_REL_LT, JMI_REL_LEQ */
    1087 
    1088     jmi_real_t atEvent;                  /**< \brief A boolean variable indicating if the model equations are evaluated at an event.*/
    1089     jmi_real_t atInitial;                /**< \brief A boolean variable indicating if the model equations are evaluated at the initial time */
    1090     jmi_real_t atTimeEvent;              /**< \brief A boolean variable indicating if the model equations are evaluated at an time event time */
    1091     int eventPhase;                      /**< \brief Zero if in first phase of event iteration, non zero if in second phase */