Changeset 8993
- Timestamp:
- Jun 23, 2016 9:18:34 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/base.c
r8300 r8993 181 181 jmi_z_offset_strings(&(*jmi)->z_t.strings.offsets); 182 182 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); 195 197 196 198 $C_dynamic_state_add_call$ 197 199 198 200 model_add_blocks(jmi); 199 200 201 model_init_add_blocks(jmi); 201 202 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); 225 211 226 212 /* 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); 228 215 229 216 return 0; -
trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/base.h
r8300 r8993 28 28 int model_ode_derivatives(jmi_t* jmi); 29 29 int model_ode_initialize(jmi_t* jmi); 30 int model_ dae_R(jmi_t* jmi, jmi_real_t** res);30 int model_ode_event_indicators(jmi_t* jmi, jmi_real_t** res); 31 31 int model_init_R0(jmi_t* jmi, jmi_real_t** res); 32 32 void model_add_blocks(jmi_t** jmi); -
trunk/Compiler/ModelicaCBackEnd/templates/FMIBase/equ.c
r7967 r8993 35 35 } 36 36 37 int model_ dae_R(jmi_t* jmi, jmi_real_t** res) {37 int model_ode_event_indicators(jmi_t* jmi, jmi_real_t** res) { 38 38 $C_DAE_event_indicator_residuals$ 39 39 return 0; -
trunk/RuntimeLibrary/src/fmi1_me/fmi1_me.c
r8305 r8993 361 361 } 362 362 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 379 363 #ifdef JMI_PROFILE_RUNTIME 380 364 { … … 414 398 415 399 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 made495 * 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 has596 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 debugging732 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 debbugging755 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 used824 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);935 400 if (retval != 0) { 936 401 return fmiError; -
trunk/RuntimeLibrary/src/fmi2/fmi2_me.c
r8979 r8993 388 388 /* Negate the values of the retrieved "negate alias" variables. */ 389 389 for (i = 0; i < nvr; i++) { 390 if ( is_negated(vr[i])) {390 if (jmi_value_ref_is_negated(vr[i])) { 391 391 value[i] = -value[i]; 392 392 } … … 412 412 /* Negate the values of the retrieved "negate alias" variables. */ 413 413 for (i = 0; i < nvr; i++) { 414 if ( is_negated(vr[i])) {414 if (jmi_value_ref_is_negated(vr[i])) { 415 415 value[i] = -value[i]; 416 416 } … … 471 471 for (i = 0; i < nvr; i++) { 472 472 /* Negate the values before setting the "negate alias" variables. */ 473 if ( is_negated(vr[i])) {473 if (jmi_value_ref_is_negated(vr[i])) { 474 474 fmi2_me->work_real_array[i] = -value[i]; 475 475 } else { … … 504 504 /* Negate the values before setting the "negate alias" variables. */ 505 505 for (i = 0; i < nvr; i++) { 506 if ( is_negated(vr[i])) {506 if (jmi_value_ref_is_negated(vr[i])) { 507 507 fmi2_me->work_int_array[i] = -value[i]; 508 508 } else { -
trunk/RuntimeLibrary/src/jmi/jmi.c
r8736 r8993 38 38 void jmi_z_delete(jmi_z_t* z) { 39 39 free(z->strings.values); 40 } 41 42 void 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 62 void jmi_model_delete(jmi_t* jmi) { 63 if (jmi->model) { 64 free(jmi->model); 65 } 40 66 } 41 67 … … 50 76 int n_real_d, int n_integer_d, int n_integer_u, 51 77 int n_boolean_d, int n_boolean_u, 52 int n_outputs, int* output_vrefs,53 78 int n_sw, int n_sw_init, int n_time_sw, int n_state_sw, 54 79 int n_guards, int n_guards_init, … … 64 89 /* Create jmi struct */ 65 90 jmi_ = *jmi; 66 /* Set struct pointers in jmi */ 67 jmi_->dae = NULL; 68 jmi_->init = NULL; 69 /* jmi_->user_func = NULL; */ 70 91 71 92 /* Set sizes of dae vectors */ 72 93 jmi_->n_real_ci = n_real_ci; … … 97 118 jmi_->n_boolean_d = n_boolean_d; 98 119 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 }105 120 106 121 jmi_->n_sw = n_sw; … … 207 222 208 223 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; 210 225 211 226 for (i=0;i<jmi_->n_z;i++) { … … 233 248 jmi_->real_u_work = (jmi_real_t*)calloc(jmi_->n_real_u,sizeof(jmi_real_t)); 234 249 235 jmi_->scaling_method = scaling_method;236 250 237 251 jmi_->n_initial_relations = n_initial_relations; … … 285 299 286 300 return 0; 287 288 301 } 289 302 … … 292 305 293 306 jmi_me_delete_modules(jmi); 294 295 307 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++) { 311 312 jmi_delete_block_residual(jmi->dae_init_block_residuals[i]); 312 313 } 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++) { 315 318 jmi_delete_block_residual(jmi->dae_block_residuals[i]); 316 319 } 317 320 free(jmi->dae_block_residuals); 318 321 319 322 for (i=0; i < jmi->n_dynamic_state_sets; i++) { … … 324 327 jmi_chattering_delete(jmi->chattering); 325 328 326 free(jmi->output_vrefs);327 329 free(*(jmi->z)); 328 330 free(jmi->z); … … 410 412 } 411 413 412 int jmi_ func_F(jmi_t *jmi, jmi_func_t *func, jmi_real_t *res) {414 int jmi_generic_func(jmi_t *jmi, jmi_generic_func_t func) { 413 415 int return_status; 414 416 int depth = jmi_prepare_try(jmi); 415 416 if (jmi_try(jmi, depth)) { 417 if (jmi_try(jmi, depth)) 417 418 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); 438 421 jmi_finalize_try(jmi, depth); 439 422 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 }546 423 } 547 424 … … 560 437 561 438 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); 563 440 564 441 if ((jmi->jmi_callbacks.log_options.log_level >= 5)) { … … 571 448 } 572 449 573 int jmi_ode_derivatives_dir_der(jmi_t* jmi , jmi_real_t *dv) {450 int jmi_ode_derivatives_dir_der(jmi_t* jmi) { 574 451 575 452 int return_status; 576 453 jmi->block_level = 0; /* to recover from errors */ 577 454 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); 579 456 580 457 return return_status; 581 458 } 582 459 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 }591 460 592 461 int jmi_ode_initialize(jmi_t* jmi) { … … 601 470 } 602 471 603 return_status = jmi_generic_func(jmi, jmi-> dae->ode_initialize);472 return_status = jmi_generic_func(jmi, jmi->model->ode_initialize); 604 473 605 474 if ((jmi->jmi_callbacks.log_options.log_level >= 5)) { … … 609 478 return return_status; 610 479 } 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 630 480 int jmi_ode_next_time_event(jmi_t* jmi, jmi_time_event_t* event) { 631 481 … … 635 485 if (jmi_try(jmi, depth)) { 636 486 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); 640 489 } 641 490 jmi_finalize_try(jmi, depth); … … 643 492 } 644 493 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 726 494 int 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; 732 508 } 733 509 … … 763 539 } 764 540 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 905 541 int 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); 920 543 } 921 544 -
trunk/RuntimeLibrary/src/jmi/jmi.h
r8679 r8993 22 22 **/ 23 23 24 /** \mainpage The JModelica.org C runtime library25 *26 * The JModelica C runtime library contains functions and data structures for27 * accessing the C model representation that is generated by the JModelica28 * Modelica and Optimica front-ends, respectively. The library is organized into29 * two main parts.30 *31 * \section fmi_model_interfance The Functional Mock-up interface32 * The Functional Mock-up Interface (FMI) defines a standard for model exchange33 * with a small set of functions for model interaction while at the same time34 * provide the necessary means for simulation of complex hybrid dynamic models.35 * - <a href="group__fmi__public.html"> Documentation of the public Functional36 * 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 interface40 * The JMI Model interface interface contains functions41 * for evaluating the function generated by the compiler, including the DAE residual, the42 * residual functions for the DAE initialization problem, and the functions related to43 * 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 for46 * 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 Limitations51 * The JModelica.org JMI interface is under development. The function signatures52 * are likely to change in the future - all feedback is very welcome. The following53 * limitations apply:54 * - Symbolic Jacobians are not provided by the compiler. This is actually55 * a limitation in the code generation module, but as a consequence, the56 * JMI_DER_SYMBOLIC flag cannot be used in the JMI interface.57 * - The ODE interface is very limited and requires a Modelica model to be58 * 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 interface64 *65 * \brief Documentation of the public JMI Model interface.66 *67 * \section DesignConsiderations Design considerations68 *69 * The JMI Model interface is intended to be used in a wide range of70 * applications and on multiple platforms. This also includes embedded71 * platforms in HILS applications.72 *73 * It is desirable that the JMI Model interface can be easily interfaced74 * with Python. Python is the intended language for scripting in JModelica and it is75 * therefore important that the generated code is straight forward to use with the76 * 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 that80 * 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 a83 * limited extent C++ where needed (e.g. in solver interfaces and in most likely in the84 * AD framework).85 *86 * It should also be possible to build shared libraries, in order to87 * build applications that contains several models.88 *89 *90 * \section MathDescr Mathematical description of the JMI Model interface91 *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 are94 * offered to the user for evaluation of the DAE residual, cost functions, constraints95 * etc. These functions takes as arguments one more of the following three argument96 * types:97 *98 * Parameters (denoted \f$p\f$):99 * - \f$c_i^r\f$ independent real constant100 * - \f$c_d^r\f$ dependent real constants101 * - \f$p_i^r\f$ independent real parameters102 * - \f$p_d^r\f$ dependent real parameters103 * - \f$c_i^i\f$ independent integer constant104 * - \f$c_d^i\f$ dependent integer constants105 * - \f$p_i^i\f$ independent integer parameters106 * - \f$p_d^i\f$ dependent integer parameters107 * - \f$c_i^b\f$ independent boolean constant108 * - \f$c_d^b\f$ dependent boolean constants109 * - \f$p_i^b\f$ independent boolean parameters110 * - \f$p_d^b\f$ dependent boolean parameters111 *112 * with113 *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 variables119 * - \f$x\f$ real variables that appear differentiated120 * - \f$u\f$ real inputs121 * - \f$w\f$ real algebraic variables122 * - \f$t\f$ time123 *124 * with125 *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 variables141 * - \f$d^i\f$ integer variables142 * - \f$u^i\f$ integer inputs143 * - \f$d^b\f$ boolean variables144 * - \f$u^b\f$ boolean inputs145 * - \f$s\f$ boolean switches mapped from relational expressions Notice that these boolean variables146 * do not originate from boolean variable declarations, but from boolean valued expressions such as147 * 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 interface156 *157 * The DAE interface is defined by the residual function \f$F(p,v,d)\f$ where158 *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 interface164 *165 * The DAE initialization interface is defined by the functions \f$F_0(p,v)\f$ and \f$F_1(p,v)\f$ where166 *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 equations171 * and start values that are fixed. \f$F_1\f$ on the other hand contains equations for172 * initialization of variables for which the value given in the start attribute is173 * not fixed.174 *175 * In addition, a residual function for dependent parameters is provided176 *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 the183 * <a href="group__Initialization.html">DAE initialization functions documentation. </a>184 *185 * \subsection Ode_interface The ODE interface186 *187 * The ODE interace is defined by the relation188 *189 * \f$\dot x = f(p,x,u,t,d). \f$190 *191 * WARNING: The current version of the JMI interface supports only Modelica192 * models which are written explicitly on ODE form. Accordingly, no193 * algebraic variables are supported in this version.194 *195 * \section Jacobians Evaluation of Jacobians196 *197 * Evaluation of Jacobians is controlled by four arguments:198 *199 * - eval_alg This argument is used to select the method evaluation200 * for the Jacobian. JMI_DER_SYMBOLIC and JMI_DER_CPPAD201 * is currently supported.202 * - sparsity This argument is a mask that selects whether203 * sparse or dense evaluation of the Jacobian should204 * be used. The constants JMI_DER_SPARSE are used to205 * specify a sparse Jacobian, whereas JMI_DER_DENSE_COL_MAJOR206 * and JMI_DER_DENSE_ROW_MAJOR are used to specify dense207 * column major or row major Jacobians respectively.208 * - independent_vars This argument is used to specify which variable types209 * are considered to be independent variables in the Jacobian210 * evaluation. The constants JMI_DER_NN are used to indicate that211 * 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 dense213 * Jacobian (equal to the size of the vector \f$z\f$), and holds the value of 0 if the corresponding Jacobian214 * column should not be computed. If the value of an entry in215 * mask i 1, then the corresponding Jacobian column will be evaluated.216 * The evaluated Jacobian columns are stored in the first217 * entries of the output argument jac.218 *219 * Notice that only Jacobian evaluation w.r.t. real parameters and variables220 * is currently supported.221 *222 * TODO: It may be interesting to include an additional layer that enables223 * support for partially defined Jacobians. This would be beneficial if symbolic224 * expressions for the Jacobian is available for some entries, but for other225 * an AD algorithm is to be used.226 *227 * \section ErrorHandling Error handling228 */229 230 24 #ifndef _JMI_H 231 25 #define _JMI_H 232 26 27 #include "jmi_ode_solver.h" 233 28 #include "jmi_util.h" 234 29 #include "jmi_global.h" … … 253 48 #define JMI_TIME_EXACT 0 /**< \brief Time events that are exact shall be handled. */ 254 49 #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_PD288 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_T292 50 293 51 /** \brief Definitions of boolean true and false literals.*/ … … 317 75 #define JMI_DISCRETE_REALS_AND_NON_REALS_CHANGED -7 318 76 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 345 85 */ 346 86 347 87 /* @{ */ 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 */ 95 typedef 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 */ 104 typedef 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 */ 118 typedef 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 */ 134 typedef 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 */ 193 int 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 */ 217 int 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 */ 230 void 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 */ 243 void jmi_model_delete(jmi_t* jmi); 244 245 /** 246 * \brief Contains a pointers to the runtime modules. 247 */ 248 struct jmi_modules_t { 249 jmi_module_t *mod_get_set; 250 251 /* Add future modules here */ 252 }; 253 254 typedef 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 259 typedef struct jmi_z_strings { 260 char** values; 261 jmi_z_offsets_t offsets; 262 } jmi_z_strings_t; 263 264 typedef 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 */ 276 struct 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 */ 479 struct 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 }; 348 487 349 488 /** … … 369 508 370 509 /** 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_t381 *382 * \brief The fields of jmi_t are conveniently accessed using the setter and getter383 * functions provided in the JMI Model interface.384 *385 * Notice that it is not recommended to access the fields directely, since the internal386 * implementation of jmi_t may change, wheras the setters and getters are less likely to387 * 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 0402 /**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 #endif427 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 references702 * 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 and757 * 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 /**766 510 * \brief Get the name of the model that produced this FMU/JMU. 767 511 */ 768 512 const char *jmi_get_model_identifier(); 769 513 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 */ 517 int jmi_generic_func(jmi_t *jmi, jmi_generic_func_t func); 874 518 875 519 /** … … 888 532 * @return Error code. 889 533 */ 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); 534 int jmi_ode_derivatives_dir_der(jmi_t* jmi); 899 535 900 536 /** … … 907 543 908 544 /** 909 * \brief Evaluate the DAE guard expressions910 *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 expressions918 *919 * @param jmi A jmi_t struct.920 * @return Error code.921 */922 int jmi_ode_guards_init(jmi_t* jmi);923 924 /**925 545 * \brief Computes the next time event. 926 546 * … … 930 550 */ 931 551 int jmi_ode_next_time_event(jmi_t* jmi, jmi_time_event_t* event); 932 933 934 /* @} */935 936 /*********************************************937 *938 * DAE interface939 *940 ********************************************/941 942 /**943 * \defgroup DAE DAE interface944 * \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 event952 * indicator residuals.953 *954 * @param jmi A jmi_t struct.955 * @param n_eq_F (Output) The number of DAE equations is stored in this956 * argument.957 * @param n_eq_R (Output) The number of DAE event indicator residuals is958 * 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 to968 * 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 to981 * 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_MAJOR987 * to indicate the output format of the Jacobian.988 * @param independent_vars Used to indicate which columns of the full Jacobian should989 * be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used990 * to set this argument.991 * @param mask This argument is a vector containing ones for the Jacobian columns that992 * 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 DAE1013 * 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 zero1031 * 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 as1049 *1050 * dF = dF/dz * dz1051 *1052 * where dF/dz is the Jacobian of the residual function F, dF1053 * is the directional derivative and dz is the seed vector.1054 *1055 * The user sets the input variables by writing to1056 * 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 int1060 * @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);1067 552 1068 553 /** … … 1094 579 1095 580 /** 1096 * \brief Compare the evaluated CAD derivative with the FD evaluation1097 *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_MAJOR1100 * to indicate the output format of the Jacobian.1101 * @param independent_vars Used to indicate which columns of the full Jacobian should1102 * be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used1103 * 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 screen1105 * 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 that1107 * 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 interface1119 *1120 ********************************************/1121 1122 /**1123 * \defgroup Initialization DAE Initialization Interface1124 * \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 to1155 * 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 DAE1180 * 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-zero1198 * elements in the Jacobian of the DAE initialization residual function \f$F_0\f$ given1199 * 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 to1226 * 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 DAE1251 * 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-zero1269 * elements in the Jacobian of the DAE initialization residual function \f$F_1\f$ given1270 * 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 to1297 * 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 DAE1322 * 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-zero1340 * elements in the Jacobian of the DAE initialization residual function \f$F_p\f$ given1341 * 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 /**1356 581 * \brief Evaluate the dependent parameters. 1357 582 * … … 1360 585 */ 1361 586 int 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 to1367 * 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);1375 587 1376 588 /* @} */ … … 1381 593 */ 1382 594 /* @{ */ 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 and1395 * one or more ordinates. If the interpolation point resides outside of the1396 * interval of the provided abscissa, then the initial or final ordinate1397 * 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 following1402 * 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 plus1405 * one for the abscissa.1406 * @param y (Output) A vector of size m-1 containing the interpolated ordinate1407 * 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);1423 595 1424 596 /** -
trunk/RuntimeLibrary/src/jmi/jmi_block_residual.c
r8873 r8993 544 544 block->nr_vref[i] = (jmi_int_t)nr_vref_tmp[i]; 545 545 /* 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]); 547 547 548 548 type = jmi_get_type_from_value_ref(block->nr_vref[i]); … … 558 558 for (i = 0; i < block->n_dr; i++) { 559 559 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]); 561 561 /* Initialize discrete real nominal vector */ 562 562 block->discrete_nominals[i] = 1; … … 572 572 for (i = 0; i < block->n_direct_nr; i++) { 573 573 /* 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]); 575 575 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]); 578 578 block->n_direct_bool++; 579 579 j++; -
trunk/RuntimeLibrary/src/jmi/jmi_cs.c
r8984 r8993 28 28 int is_integer_input, is_boolean_input; 29 29 30 z_index = get_index_from_value_ref(valueref[i]);30 z_index = jmi_get_index_from_value_ref(valueref[i]); 31 31 is_integer_input = (z_index >= jmi->offs_integer_u && z_index < jmi->offs_boolean_d); 32 32 is_boolean_input = (z_index >= jmi->offs_boolean_u && z_index < jmi->offs_sw); -
trunk/RuntimeLibrary/src/jmi/jmi_global.c
r8825 r8993 28 28 #include "jmi_global.h" 29 29 #include "jmi_log.h" 30 #include "jmi _util.h"30 #include "jmi.h" 31 31 32 32 -
trunk/RuntimeLibrary/src/jmi/jmi_global.h
r8825 r8993 29 29 #include <setjmp.h> 30 30 31 #include "jmi _util.h"31 #include "jmi.h" 32 32 33 33 -
trunk/RuntimeLibrary/src/jmi/jmi_me.c
r8979 r8993 24 24 #include "module_include/jmi_get_set.h" 25 25 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 50 27 51 28 int jmi_me_init(jmi_callbacks_t* jmi_callbacks, jmi_t* jmi, jmi_string GUID, jmi_string_t resource_location) { … … 98 75 /* Write start values to the pre vector*/ 99 76 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 }129 77 130 78 return 0; … … 258 206 for (i = 0; i < nvr; i = i + 1) { 259 207 /* 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]); 261 209 if (index >= start && index < end) { 262 210 jmi_log_node(jmi->log, logError, "CannotSetVariable", … … 406 354 407 355 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); 412 360 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]; 414 362 } 415 363 … … 704 652 jmi->atEvent = JMI_FALSE; 705 653 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 714 654 /* Final evaluation of the model with event flag set to false. It can 715 655 * for example change values of booleans that should only be true during … … 857 797 } 858 798 859 static int get_option_index(char* option) {799 static unsigned int get_option_index(char* option) { 860 800 const char** found=(const char**)bsearch(&option, 861 801 fmi_runtime_options_map_names, … … 868 808 if(index >= fmi_runtime_options_map_length ) return 0; 869 809 vr = fmi_runtime_options_map_vrefs[index]; 870 return get_index_from_value_ref(vr);810 return jmi_get_index_from_value_ref(vr); 871 811 } 872 812 -
trunk/RuntimeLibrary/src/jmi/jmi_me.h
r8979 r8993 27 27 #include "jmi_math.h" 28 28 #include "jmi_types.h" 29 30 typedef unsigned int jmi_value_reference;31 29 32 30 typedef struct jmi_event_info_t jmi_event_info_t; … … 65 63 */ 66 64 extern 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);73 65 74 66 int 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 47 47 typedef void (*jmi_ode_delete_func_t)(jmi_ode_solver_t* block); 48 48 49 49 typedef enum { 50 JMI_ODE_CVODE, 51 JMI_ODE_EULER 52 } jmi_ode_method_t; 50 53 51 54 struct jmi_ode_solver_t { -
trunk/RuntimeLibrary/src/jmi/jmi_types.h
r8972 r8993 43 43 /* Forward declaration of jmi structs */ 44 44 typedef 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. */ 45 typedef struct jmi_model_t jmi_model_t; /**< \brief Forward declaration of struct. */ 47 46 typedef struct jmi_func_t jmi_func_t; /**< \brief Forward declaration of struct. */ 48 47 typedef struct jmi_block_residual_t jmi_block_residual_t; /**< \brief Forward declaration of struct. */ … … 180 179 #define FALSE 0 181 180 182 #define JMI_REAL 0x00000000 183 #define JMI_INTEGER 0x10000000 184 #define JMI_BOOLEAN 0x20000000 181 typedef enum { 182 JMI_REAL, 183 JMI_INTEGER, 184 JMI_BOOLEAN, 185 JMI_STRING 186 } jmi_type_t; 185 187 186 188 typedef char jmi_boolean; 187 189 typedef const char* jmi_string; 190 typedef unsigned int jmi_value_reference; 188 191 189 192 #endif -
trunk/RuntimeLibrary/src/jmi/jmi_util.c
r8679 r8993 51 51 } 52 52 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 a121 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 else134 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 the277 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 and285 store the result, coloring done contains information if the result is stored or not. func->c_info contains the286 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 every299 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 which302 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_opt424 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 might529 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 used628 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 761 53 int jmi_copy_pre_values(jmi_t *jmi) { 762 54 int i; … … 772 64 } 773 65 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 1107 66 jmi_real_t* jmi_get_z(jmi_t* jmi) { 1108 67 return *(jmi->z); … … 1209 168 } 1210 169 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 1219 170 jmi_real_t* jmi_get_sw(jmi_t* jmi) { 1220 171 return *(jmi->z) + jmi->offs_sw; … … 1233 184 } 1234 185 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 1316 186 void jmi_init_runtime_options(jmi_t *jmi, jmi_options_t* op) { 1317 187 jmi_block_solver_init_default_options(&op->block_solver_options); 1318 188 1319 op->nle_solver_default_tol = 1e-10; 189 op->nle_solver_default_tol = 1e-10; /**< \brief Default tolerance for the equation block solver */ 1320 190 op->nle_solver_tol_factor = 0.0001; /**< \brief Tolerance safety factor for the non-linear equation block solver. */ 1321 191 op->events_default_tol = 1e-10; /**< \brief Default tolerance for the event iterations. */ 1322 192 op->events_tol_factor = 0.0001; /**< \brief Tolerance safety factor for the event iterations. */ 1323 op->cs_solver = JMI_ODE_CVODE; /** 1324 op->cs_rel_tol = 1e-6; /** 1325 op->cs_step_size = 1e-3; /** 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. */ 1326 196 op->cs_experimental_mode = 0; 1327 197 … … 1329 199 } 1330 200 1331 int jmi_get_index_from_value_ref(intvref) {201 jmi_value_reference jmi_get_index_from_value_ref(jmi_value_reference vref) { 1332 202 /* Translate a ValueReference into variable index in z-vector. */ 1333 203 return vref & VREF_INDEX_MASK; 1334 204 } 1335 205 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) { 206 jmi_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 218 jmi_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 223 jmi_value_reference jmi_get_value_ref_from_index(int index, jmi_type_t type) { 1342 224 /* 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: 1947 231 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 } 2016 233 } 2017 234 … … 2048 265 2049 266 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 { 2052 273 sw = 0.0; 2053 274 } 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 { 2056 281 sw = 1.0; 2057 282 } 2058 283 } 2059 284 } 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 { 2062 291 sw = 0.0; 2063 292 } 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 { 2066 299 sw = 1.0; 2067 300 } … … 2077 310 * x < 0 2078 311 */ 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 { 2082 318 sw = 0.0; 2083 319 } 2084 320 } 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 { 2087 326 sw = 1.0; 2088 327 } 2089 328 } 2090 329 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 else2099 return_status = func(jmi);2100 jmi_finalize_try(jmi, depth);2101 return return_status;2102 330 } 2103 331 -
trunk/RuntimeLibrary/src/jmi/jmi_util.h
r8736 r8993 67 67 * the JMI model interface and can be viewed as an object 68 68 * 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. 77 71 * 78 72 * Instances of jmi_t are created by a call to ::jmi_new, which is a … … 84 78 * but no substructs are initialized. 85 79 * - 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. 93 86 * 94 87 */ … … 102 95 103 96 /* @{ */ 104 105 /*106 * TODO: Error codes...107 * Introduce #defines to denote different error codes108 */109 110 97 111 98 typedef struct _jmi_time_event_t { … … 121 108 void jmi_min_time_event(jmi_time_event_t* event, int def, int phase, double time); 122 109 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*/ 132 111 #define AD_WRAP_LITERAL(x) ((jmi_real_t) (x)) 133 112 … … 173 152 void jmi_flag_termination(jmi_t *jmi, const char* msg); 174 153 175 /* @} */176 177 /**178 * \defgroup jmi_function_typedefs Function typedefs179 *180 * \brief Function signatures to be used in the generated code181 */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 in204 * the generated code.205 *206 * Notice that this function signature is used for all functions in207 * 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 function218 * in the generated code.219 *220 * Notice that this function signature is used for all functions in221 * 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 in236 * generated code.237 *238 * Notice that this function signature is used for all functions in239 * 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 struct255 *256 * \brief Functions for creating, deleting and evaluating jmi_func_t257 * 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 symbolic274 * 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 AD279 * 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 the310 * 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 Jacobian318 *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 the335 * 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 residual342 * Jacobian.343 * @param col (Output) The column indices of the non-zeros in the DAE residual344 * 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-zero354 * elements in the symbolic Jacobian of a jmi_func_t given a sparsity355 * 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 of372 * 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 of387 * 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 the401 * 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 Jacobian409 *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 the428 * 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 residual435 * Jacobian.436 * @param col (Output) The column indices of the non-zeros in the DAE residual437 * 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-zero449 * elements in the AD Jacobian of a jmi_func_t given a sparsity450 * 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 of468 * 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 the483 * 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 Jacobian491 *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 the510 * 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 residual517 * Jacobian.518 * @param col (Output) The column indices of the non-zeros in the DAE residual519 * 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-zero530 * elements in the finite difference Jacobian of a jmi_func_t given a sparsity531 * 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 547 154 /**< \brief Run-time options. */ 548 155 typedef struct jmi_options_t { … … 597 204 else init_with_ubound(x, xmax, message) 598 205 599 /**600 * \brief Data structure for representing a single function601 * \f$F(z)\f$.602 *603 * jmi_func_t is a struct that contains function pointers and604 * dimension information corresponding to a mathematical vector valued605 * function, \f$F(z)\f$. The struct also contains function pointers to606 * 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 };650 206 651 207 /* @} */ 652 208 653 209 /** 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. 658 218 * 659 219 */ … … 662 222 663 223 /** 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. 707 227 * @return Error code. 708 228 */ 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 */