Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit a275e4c

Browse files
Willi BraunOpenModelica-Hudson
authored andcommitted
more fixes for ticket:4395
- scale matrix for residual factors - fix additional check of fnorm
1 parent ff26927 commit a275e4c

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

SimulationRuntime/c/simulation/solver/kinsolSolver.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)