@@ -99,6 +99,7 @@ typedef struct NLS_KINSOL_DATA
9999 int kinsolStrategy ;
100100 int retries ;
101101 int solved ; /* if the system is once solved reuse linear matrix information */
102+ int nominalJac ;
102103
103104 /* ### tolerances ### */
104105 double fnormtol ; /* function tolerance */
@@ -190,6 +191,7 @@ int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolver
190191 kinsolData -> scsteptol = newtonXTol ; /* step tolerance */
191192
192193 kinsolData -> maxstepfactor = maxStepFactor ; /* step tolerance */
194+ kinsolData -> nominalJac = 0 ; /* calculate for scaling the scaled matrix */
193195
194196 kinsolData -> initialGuess = N_VNew_Serial (size );
195197 kinsolData -> xScale = N_VNew_Serial (size );
@@ -368,7 +370,12 @@ int nlsDenseJac(long int N, N_Vector vecX, N_Vector vecFX, DlsMat Jac, void *use
368370
369371 for (j = 0 ; j < N ; j ++ )
370372 {
371- DENSE_ELEM (Jac , j , i ) = (fRes [j ] - fx [j ]) * delta_hh ;
373+ if (kinsolData -> nominalJac ){
374+ DENSE_ELEM (Jac , j , i ) = (fRes [j ] - fx [j ]) * delta_hh / xScaling [i ];
375+ }else {
376+ DENSE_ELEM (Jac , j , i ) = (fRes [j ] - fx [j ]) * delta_hh ;
377+ }
378+
372379 }
373380 x [i ] = xsave ;
374381 }
@@ -474,7 +481,11 @@ int nlsSparseJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N_Ve
474481 while (nth < sparsePattern -> leadindex [ii + 1 ])
475482 {
476483 j = sparsePattern -> index [nth ];
477- setJacElementKluSparse (j , ii , (fRes [j ] - fx [j ]) * delta_hh [ii ], nth , Jac );
484+ if (kinsolData -> nominalJac ){
485+ setJacElementKluSparse (j , ii , (fRes [j ] - fx [j ]) * delta_hh [ii ] / xScaling [ii ], nth , Jac );
486+ }else {
487+ setJacElementKluSparse (j , ii , (fRes [j ] - fx [j ]) * delta_hh [ii ], nth , Jac );
488+ }
478489 nth ++ ;
479490 };
480491 x [ii ] = xsave [ii ];
@@ -520,6 +531,7 @@ int nlsSparseSymJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N
520531 /* prepare variables */
521532 double * x = N_VGetArrayPointer (vecX );
522533 double * fx = N_VGetArrayPointer (vecFX );
534+ double * xScaling = NV_DATA_S (kinsolData -> xScale );
523535
524536 SPARSE_PATTERN * sparsePattern = & (nlsData -> sparsePattern );
525537 ANALYTIC_JACOBIAN * analyticJacobian = & data -> simulationInfo -> analyticJacobians [nlsData -> jacobianIndex ];
@@ -534,16 +546,13 @@ int nlsSparseSymJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N
534546 /* reset matrix */
535547 SlsSetToZero (Jac );
536548
537- /* update x for the matrix */
538- nlsKinsolResiduals (vecX , vecFX , userData );
539-
540549 for (i = 0 ; i < sparsePattern -> maxColors ; i ++ )
541550 {
542551 for (ii = 0 ; ii < kinsolData -> size ; ii ++ )
543552 {
544553 if (sparsePattern -> colorCols [ii ]- 1 == i )
545554 {
546- analyticJacobian -> seedVars [ii ] = 1 ;
555+ analyticJacobian -> seedVars [ii ] = 1.0 ;
547556 }
548557 }
549558 ((nlsData -> analyticalJacobianColumn ))(data , threadData );
@@ -556,7 +565,11 @@ int nlsSparseSymJac(N_Vector vecX, N_Vector vecFX, SlsMat Jac, void *userData, N
556565 while (nth < sparsePattern -> leadindex [ii + 1 ])
557566 {
558567 j = sparsePattern -> index [nth ];
559- setJacElementKluSparse (j , ii , analyticJacobian -> resultVars [j ], nth , Jac );
568+ if (kinsolData -> nominalJac ){
569+ setJacElementKluSparse (j , ii , analyticJacobian -> resultVars [j ] / xScaling [ii ] , nth , Jac );
570+ }else {
571+ setJacElementKluSparse (j , ii , analyticJacobian -> resultVars [j ], nth , Jac );
572+ }
560573 nth ++ ;
561574 };
562575 analyticJacobian -> seedVars [ii ] = 0 ;
@@ -731,6 +744,12 @@ void nlsKinsolFScaling(DATA* data, NLS_KINSOL_DATA *kinsolData, NONLINEAR_SYSTEM
731744 N_Vector tmp1 = N_VNew_Serial (kinsolData -> size );
732745 N_Vector tmp2 = N_VNew_Serial (kinsolData -> size );
733746
747+ /* enable scaled jacobian */
748+ kinsolData -> nominalJac = 1 ;
749+
750+ /* update x for the matrix */
751+ nlsKinsolResiduals (x , kinsolData -> fTmp , & kinsolData -> userData );
752+
734753 /* calculate the right jacobian */
735754 if (nlsData -> isPatternAvailable && kinsolData -> linearSolverMethod == 3 )
736755 {
@@ -747,15 +766,10 @@ void nlsKinsolFScaling(DATA* data, NLS_KINSOL_DATA *kinsolData, NONLINEAR_SYSTEM
747766 nlsDenseJac (nlsData -> size , x , kinsolData -> fTmp , denseJac , & kinsolData -> userData , tmp1 , tmp2 );
748767 spJac = SlsConvertDls (denseJac );
749768 }
769+ /* disable scaled jacobian */
770+ kinsolData -> nominalJac = 0 ;
750771
751- /* debug */
752- if (ACTIVE_STREAM (LOG_NLS_JAC )){
753- infoStreamPrint (LOG_NLS_JAC , 1 , "##KINSOL## Matrix for F-Scaling:" );
754- PrintSparseMat (spJac );
755- messageClose (LOG_NLS_JAC );
756- }
757-
758- _omc_fillVector (_omc_createVector (nlsData -> size ,fScaling ), 1. );
772+ _omc_fillVector (_omc_createVector (nlsData -> size ,fScaling ), 1e-12 );
759773 for (i = 0 ; i < spJac -> NNZ ; ++ i ){
760774 if (fScaling [spJac -> rowvals [i ]] < fabs (spJac -> data [i ])){
761775 fScaling [spJac -> rowvals [i ]] = fabs (spJac -> data [i ]);
@@ -1016,7 +1030,9 @@ int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber)
10161030 {
10171031 /* check if solution really solves the residuals */
10181032 nlsKinsolResiduals (kinsolData -> initialGuess , kinsolData -> fRes , & kinsolData -> userData );
1019- fNormValue = N_VWL2Norm (kinsolData -> fRes , kinsolData -> fScale );
1033+ N_VProd (kinsolData -> fRes , kinsolData -> fScale , kinsolData -> fRes );
1034+ fNormValue = N_VWL2Norm (kinsolData -> fRes , kinsolData -> fRes );
1035+
10201036 infoStreamPrint (LOG_NLS , 0 , "scaled Euclidean norm of F(u) = %e" , fNormValue );
10211037 if (FTOL_WITH_LESS_ACCURANCY < fNormValue )
10221038 {
0 commit comments