7272#include <idas/idas_spbcgs.h>
7373#include <idas/idas_sptfqmr.h>
7474
75- static int callDenseNumJac (long int Neq , double tt , double cj ,
75+ static int callDenseJacobian (long int Neq , double tt , double cj ,
7676 N_Vector yy , N_Vector yp , N_Vector rr ,
7777 DlsMat Jac , void * user_data ,
7878 N_Vector tmp1 , N_Vector tmp2 , N_Vector tmp3 );
7979
80- static int jacobianSparseNum (realtype tt , realtype cj ,
80+ static int callSparseJacobian (realtype tt , realtype cj ,
8181 N_Vector yy , N_Vector yp , N_Vector rr , SlsMat Jac , void * user_data ,
8282 N_Vector tmp1 , N_Vector tmp2 , N_Vector tmp3 );
8383
@@ -403,7 +403,7 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
403403 }
404404
405405
406- /* if FLAG_JACOBIAN is set, choose dassl jacobian calculation method */
406+ /* if FLAG_JACOBIAN is set, choose jacobian calculation method */
407407 if (omc_flag [FLAG_JACOBIAN ])
408408 {
409409 for (i = 1 ; i < JAC_MAX ;i ++ )
@@ -413,6 +413,11 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
413413 break ;
414414 }
415415 }
416+ if (idaData -> daeMode && ( idaData -> jacobianMethod == COLOREDSYMJAC || idaData -> jacobianMethod == SYMJAC ))
417+ {
418+ warningStreamPrint (LOG_STDOUT , 1 , "Symbolic Jacobians are currently not supported by DAE Mode. Switch back to numerical Jacobian!" );
419+ idaData -> jacobianMethod = COLOREDNUMJAC ;
420+ }
416421 if (idaData -> jacobianMethod == JAC_UNKNOWN )
417422 {
418423 if (ACTIVE_WARNING_STREAM (LOG_SOLVER ))
@@ -430,21 +435,13 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
430435 }
431436 else
432437 {
433- if (idaData -> linearSolverMethod == IDA_LS_KLU )
434- {
435- idaData -> jacobianMethod = KLUSPARSE ;
436- }
437- else
438- {
439- idaData -> jacobianMethod = COLOREDNUMJAC ;
440- }
438+ idaData -> jacobianMethod = COLOREDNUMJAC ;
441439 }
442440
443441 /* selects the calculation method of the jacobian */
444442 /* in daeMode sparse pattern is already initialized in DAEMODE_DATA */
445443 if (!idaData -> daeMode && (idaData -> jacobianMethod == COLOREDNUMJAC ||
446444 idaData -> jacobianMethod == COLOREDSYMJAC ||
447- idaData -> jacobianMethod == KLUSPARSE ||
448445 idaData -> jacobianMethod == SYMJAC ))
449446 {
450447 if (data -> callback -> initialAnalyticJacobianA (data , threadData ))
@@ -466,6 +463,7 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
466463 {
467464 idaData -> NNZ = data -> simulationInfo -> daeModeData -> sparsePattern -> numberOfNoneZeros ;
468465 flag = IDAKLU (idaData -> ida_mem , idaData -> N , idaData -> NNZ );
466+ idaData -> jacobianMethod = COLOREDNUMJAC ; /* In DAE mode only numerical matrix is supported */
469467 }
470468 else
471469 {
@@ -479,11 +477,14 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
479477 }
480478
481479 switch (idaData -> jacobianMethod ){
482- case KLUSPARSE :
483- flag = IDASlsSetSparseJacFn (idaData -> ida_mem , jacobianSparseNum );
480+ case SYMJAC :
481+ case NUMJAC :
482+ case COLOREDSYMJAC :
483+ case COLOREDNUMJAC :
484+ flag = IDASlsSetSparseJacFn (idaData -> ida_mem , callSparseJacobian );
484485 break ;
485486 default :
486- throwStreamPrint (threadData ,"For the klu solver jacobian calculation method has to be %s" , JACOBIAN_METHOD [KLUSPARSE ]);
487+ throwStreamPrint (threadData ,"For the klu solver jacobian calculation method has to be %s or %s " , JACOBIAN_METHOD [COLOREDSYMJAC ], JACOBIAN_METHOD [ COLOREDNUMJAC ]);
487488 break ;
488489 }
489490 }
@@ -492,12 +493,10 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
492493 switch (idaData -> jacobianMethod ){
493494 case SYMJAC :
494495 case COLOREDSYMJAC :
495- infoStreamPrint (LOG_STDOUT , 0 , "The symbolic jacobian is not implemented, yet! Switch back to internal." );
496- break ;
497496 case COLOREDNUMJAC :
498497 case NUMJAC :
499498 /* set jacobian function */
500- flag = IDADlsSetDenseJacFn (idaData -> ida_mem , callDenseNumJac );
499+ flag = IDADlsSetDenseJacFn (idaData -> ida_mem , callDenseJacobian );
501500 break ;
502501 case INTERNALNUMJAC :
503502 break ;
@@ -1268,7 +1267,7 @@ int rootsFunctionIDA(double time, N_Vector yy, N_Vector yp, double *gout, void*
12681267 * into a dense DlsMat matrix
12691268 */
12701269static
1271- int jacOwnNumColoredIDA (double tt , N_Vector yy , N_Vector yp , N_Vector rr , DlsMat Jac , double cj , void * userData )
1270+ int jacColoredNumericalDense (double tt , N_Vector yy , N_Vector yp , N_Vector rr , DlsMat Jac , double cj , void * userData )
12721271{
12731272 TRACE_PUSH
12741273 IDA_SOLVER * idaData = (IDA_SOLVER * )userData ;
@@ -1365,69 +1364,60 @@ int jacOwnNumColoredIDA(double tt, N_Vector yy, N_Vector yp, N_Vector rr, DlsMat
13651364}
13661365
13671366/*
1368- * function calculates a jacobian matrix by
1369- * numerical method finite differences without coloring
1370- * into a dense DlsMat matrix
1367+ * function calculates the Jacobian matrix symbolical
1368+ * with considering also the coloring and pass it in a
1369+ * dense DlsMat matrix.
13711370 */
13721371static
1373- int jacOwnNumIDA (double tt , N_Vector yy , N_Vector yp , N_Vector rr , DlsMat Jac , double cj , void * userData )
1372+ int jacColoredSymbolicalDense (double tt , N_Vector yy , N_Vector yp , N_Vector rr , DlsMat Jac , double cj , void * userData )
13741373{
13751374 TRACE_PUSH
13761375 IDA_SOLVER * idaData = (IDA_SOLVER * )userData ;
13771376 DATA * data = (DATA * )(((IDA_USERDATA * )idaData -> simData )-> data );
1377+ threadData_t * threadData = (threadData_t * )(((IDA_USERDATA * )idaData -> simData )-> threadData );
13781378 void * ida_mem = idaData -> ida_mem ;
1379+ const int index = data -> callback -> INDEX_JAC_A ;
1380+ unsigned int i ,ii ,j , nth ;
1381+ ANALYTIC_JACOBIAN * jacData = & (data -> simulationInfo -> analyticJacobians [index ]);
1382+ SPARSE_PATTERN * sparsePattern = & (jacData -> sparsePattern );
13791383
13801384 /* prepare variables */
13811385 double * states = N_VGetArrayPointer (yy );
13821386 double * yprime = N_VGetArrayPointer (yp );
1383- double * delta = N_VGetArrayPointer (rr );
1384- double * newdelta = N_VGetArrayPointer (idaData -> newdelta );
1385- double * errwgt = N_VGetArrayPointer (idaData -> errwgt );
1386-
1387- double ysave , ypsave ;
1388-
1389- double delta_h = numericalDifferentiationDeltaXsolver ;
1390- double delta_hh ;
1391- double delta_hhh ;
1392- double deltaInv ;
1393- long int i ,j ;
1394-
1395- double currentStep ;
1396-
1397- /* set values */
1398- IDAGetCurrentStep (ida_mem , & currentStep );
1399- if (!idaData -> disableScaling ){
1400- IDAGetErrWeights (ida_mem , idaData -> errwgt );
1401- }
14021387
14031388 setContext (data , & tt , CONTEXT_JACOBIAN );
14041389
1405- for (i = 0 ; i < idaData -> N ; i ++ )
1390+ for (i = 0 ; i < sparsePattern -> maxColors ; i ++ )
14061391 {
1407- delta_hhh = currentStep * yprime [i ];
1408- delta_hh = delta_h * fmax (fmax (fabs (states [i ]),fabs (delta_hhh )),fabs (1. /errwgt [i ]));
1409- delta_hh = (delta_hhh >= 0 ? delta_hh : - delta_hh );
1410- delta_hh = (states [i ] + delta_hh ) - states [i ];
1411- deltaInv = 1. / delta_hh ;
1412- ysave = states [i ];
1413- states [i ] += delta_hh ;
1414- if (idaData -> daeMode ){
1415- ypsave = yprime [i ];
1416- yprime [i ] += cj * delta_hh ;
1392+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
1393+ {
1394+ if (sparsePattern -> colorCols [ii ]- 1 == i )
1395+ {
1396+ jacData -> seedVars [ii ] = 1 ;
1397+ }
14171398 }
14181399
1419- (* idaData -> residualFunction )(tt , yy , yp , idaData -> newdelta , userData );
1420-
1400+ data -> callback -> functionJacA_column (data , threadData );
14211401 increaseJacContext (data );
14221402
1423- for (j = 0 ; j < idaData -> N ; j ++ )
1403+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
14241404 {
1425- DENSE_ELEM (Jac , j , i ) = (newdelta [j ] - delta [j ]) * deltaInv ;
1426-
1405+ if (sparsePattern -> colorCols [ii ]- 1 == i )
1406+ {
1407+ nth = sparsePattern -> leadindex [ii ];
1408+ while (nth < sparsePattern -> leadindex [ii + 1 ])
1409+ {
1410+ j = sparsePattern -> index [nth ];
1411+ infoStreamPrint (LOG_JAC , 0 , "### symbolical jacobian at [%d,%d] = %f ###" , j , ii , jacData -> resultVars [j ]);
1412+ DENSE_ELEM (Jac , j , ii ) = jacData -> resultVars [j ];
1413+ nth ++ ;
1414+ };
1415+ }
14271416 }
1428- states [i ] = ysave ;
1429- if (idaData -> daeMode ){
1430- yprime [i ] = ypsave ;
1417+
1418+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
1419+ {
1420+ jacData -> seedVars [ii ] = 0 ;
14311421 }
14321422 }
14331423 unsetContext (data );
@@ -1437,9 +1427,9 @@ int jacOwnNumIDA(double tt, N_Vector yy, N_Vector yp, N_Vector rr, DlsMat Jac, d
14371427}
14381428
14391429/*
1440- * provides a numerical Jacobian
1430+ * wrapper function to call dense Jacobian
14411431 */
1442- static int callDenseNumJac (long int Neq , double tt , double cj ,
1432+ static int callDenseJacobian (long int Neq , double tt , double cj ,
14431433 N_Vector yy , N_Vector yp , N_Vector rr ,
14441434 DlsMat Jac , void * user_data ,
14451435 N_Vector tmp1 , N_Vector tmp2 , N_Vector tmp3 )
@@ -1452,13 +1442,17 @@ static int callDenseNumJac(long int Neq, double tt, double cj,
14521442 /* profiling */
14531443 rt_tick (SIM_TIMER_JACOBIAN );
14541444
1455- if (idaData -> jacobianMethod == COLOREDNUMJAC )
1445+ if (idaData -> jacobianMethod == COLOREDNUMJAC || idaData -> jacobianMethod == NUMJAC )
14561446 {
1457- retVal = jacOwnNumColoredIDA (tt , yy , yp , rr , Jac , cj , user_data );
1447+ retVal = jacColoredNumericalDense (tt , yy , yp , rr , Jac , cj , user_data );
14581448 }
1459- else if (idaData -> jacobianMethod == NUMJAC )
1449+ else if (idaData -> jacobianMethod == COLOREDSYMJAC || idaData -> jacobianMethod == SYMJAC )
14601450 {
1461- retVal = jacOwnNumIDA (tt , yy , yp , rr , Jac , cj , user_data );
1451+ retVal = jacColoredSymbolicalDense (tt , yy , yp , rr , Jac , cj , user_data );
1452+ }
1453+ else
1454+ {
1455+ throwStreamPrint (threadData , "##IDA## Something goes wrong while obtain jacobian matrix!" );
14621456 }
14631457
14641458 /* profiling */
@@ -1514,7 +1508,7 @@ static void finishSparseColPtr(SlsMat mat, int nnz)
15141508 * into a sparse SlsMat matrix
15151509 */
15161510static
1517- int jacobianSparseNumIDA (double tt , N_Vector yy , N_Vector yp , N_Vector rr , SlsMat Jac , double cj , void * userData )
1511+ int jacoColoredNumericalSparse (double tt , N_Vector yy , N_Vector yp , N_Vector rr , SlsMat Jac , double cj , void * userData )
15181512{
15191513 TRACE_PUSH
15201514 IDA_SOLVER * idaData = (IDA_SOLVER * )userData ;
@@ -1645,15 +1639,83 @@ int jacobianSparseNumIDA(double tt, N_Vector yy, N_Vector yp, N_Vector rr, SlsMa
16451639 return 0 ;
16461640}
16471641
1642+ /* \fn jacColoredSymbolicalSparse(double tt, N_Vector yy, N_Vector yp, N_Vector rr, SlsMat Jac, double cj, void *userData)
1643+ *
1644+ *
1645+ * This function calculates symbolically the jacobian matrix and exploiting the coloring.
1646+ */
1647+ int
1648+ jacColoredSymbolicalSparse (double tt , N_Vector yy , N_Vector yp , N_Vector rr , SlsMat Jac , double cj , void * userData )
1649+ {
1650+ TRACE_PUSH
1651+ IDA_SOLVER * idaData = (IDA_SOLVER * )userData ;
1652+ DATA * data = (DATA * )(((IDA_USERDATA * )idaData -> simData )-> data );
1653+ threadData_t * threadData = (threadData_t * )(((IDA_USERDATA * )idaData -> simData )-> threadData );
1654+ void * ida_mem = idaData -> ida_mem ;
1655+ const int index = data -> callback -> INDEX_JAC_A ;
1656+ unsigned int i ,ii ,j ,nth ;
1657+
1658+ /* prepare variables */
1659+ double * states = N_VGetArrayPointer (yy );
1660+ double * yprime = N_VGetArrayPointer (yp );
1661+
1662+ ANALYTIC_JACOBIAN * jacData = & (data -> simulationInfo -> analyticJacobians [index ]);
1663+ SPARSE_PATTERN * sparsePattern = & (jacData -> sparsePattern );
1664+
1665+ /* it's needed to clear the matrix */
1666+ SlsSetToZero (Jac );
1667+
1668+ setContext (data , & tt , CONTEXT_JACOBIAN );
1669+
1670+ for (i = 0 ; i < sparsePattern -> maxColors ; i ++ )
1671+ {
1672+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
1673+ {
1674+ if (sparsePattern -> colorCols [ii ]- 1 == i )
1675+ {
1676+ jacData -> seedVars [ii ] = 1 ;
1677+ }
1678+ }
1679+
1680+ data -> callback -> functionJacA_column (data , threadData );
1681+ increaseJacContext (data );
1682+
1683+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
1684+ {
1685+ if (sparsePattern -> colorCols [ii ]- 1 == i )
1686+ {
1687+ nth = sparsePattern -> leadindex [ii ];
1688+ while (nth < sparsePattern -> leadindex [ii + 1 ])
1689+ {
1690+ j = sparsePattern -> index [nth ];
1691+ setJacElementKluSparse (j , ii , jacData -> resultVars [j ], nth , Jac );
1692+ nth ++ ;
1693+ };
1694+ }
1695+ }
1696+
1697+ for (ii = 0 ; ii < idaData -> N ; ii ++ )
1698+ {
1699+ jacData -> seedVars [ii ] = 0 ;
1700+ }
1701+ }
1702+ finishSparseColPtr (Jac , sparsePattern -> numberOfNoneZeros );
1703+ unsetContext (data );
1704+
1705+ TRACE_POP
1706+ return 0 ;
1707+ }
1708+
16481709/*
1649- * Wrapper function for jacobianSparseNumIDA
1710+ * Wrapper function to call numerical or symbolical jacobian matrix
16501711 */
1651- static int jacobianSparseNum (double tt , double cj ,
1712+ static int callSparseJacobian (double tt , double cj ,
16521713 N_Vector yy , N_Vector yp , N_Vector rr ,
16531714 SlsMat Jac , void * user_data ,
16541715 N_Vector tmp1 , N_Vector tmp2 , N_Vector tmp3 )
16551716{
16561717 TRACE_PUSH
1718+ int retVal ;
16571719
16581720 IDA_SOLVER * idaData = (IDA_SOLVER * )user_data ;
16591721 DATA * data = (DATA * )(((IDA_USERDATA * )idaData -> simData )-> data );
@@ -1662,11 +1724,13 @@ static int jacobianSparseNum(double tt, double cj,
16621724 /* profiling */
16631725 rt_tick (SIM_TIMER_JACOBIAN );
16641726
1665- if ( jacobianSparseNumIDA ( tt , yy , yp , rr , Jac , cj , user_data ) )
1727+ if ( idaData -> jacobianMethod == COLOREDSYMJAC || idaData -> jacobianMethod == SYMJAC )
16661728 {
1667- throwStreamPrint (threadData , "Error, can not get Matrix A " );
1668- TRACE_POP
1669- return 1 ;
1729+ retVal = jacColoredSymbolicalSparse (tt , yy , yp , rr , Jac , cj , user_data );
1730+ }
1731+ else if (idaData -> jacobianMethod == COLOREDNUMJAC || idaData -> jacobianMethod == NUMJAC )
1732+ {
1733+ retVal = jacoColoredNumericalSparse (tt , yy , yp , rr , Jac , cj , user_data );
16701734 }
16711735
16721736 /* profiling */
@@ -1692,7 +1756,7 @@ static int jacobianSparseNum(double tt, double cj,
16921756 }
16931757
16941758 TRACE_POP
1695- return 0 ;
1759+ return retVal ;
16961760}
16971761
16981762static
@@ -1727,13 +1791,13 @@ int getScalingFactors(DATA* data, IDA_SOLVER *idaData, SlsMat inScaleMatrix)
17271791 if (idaData -> linearSolverMethod == IDA_LS_KLU )
17281792 {
17291793 scaleMatrix = NewSparseMat (idaData -> N , idaData -> N , idaData -> NNZ );
1730- jacobianSparseNum (data -> localData [0 ]-> timeValue , 1.0 , idaData -> y , idaData -> yp , rres ,
1794+ callSparseJacobian (data -> localData [0 ]-> timeValue , 1.0 , idaData -> y , idaData -> yp , rres ,
17311795 scaleMatrix , idaData , tmp1 , tmp2 , tmp3 );
17321796 }
17331797 else
17341798 {
17351799 DlsMat denseMatrix = NewDenseMat (idaData -> N , idaData -> N );
1736- callDenseNumJac (idaData -> N , data -> localData [0 ]-> timeValue , 1.0 , idaData -> y , idaData -> yp , rres ,
1800+ callDenseJacobian (idaData -> N , data -> localData [0 ]-> timeValue , 1.0 , idaData -> y , idaData -> yp , rres ,
17371801 denseMatrix , idaData , tmp1 , tmp2 , tmp3 );
17381802 scaleMatrix = SlsConvertDls (denseMatrix );
17391803 }
0 commit comments