@@ -15,24 +15,21 @@ void controlnudging_core(FemModel* femmodel){
1515 IssmDouble time;
1616 int maxiter;
1717
18- /* Hard-coded nudging parameters*/
19- IssmDouble minstep = -0.05 ; // max log10(C) decrease per step (was -0.05, too large), -0.03 or 0.03
20- IssmDouble maxstep = 0.05 ; // max log10(C) increase per step
21- IssmDouble C_log_min = -2 ; // log10(C) floor = C >= 1, 1 is the typical limit in a budd law
22- IssmDouble C_log_max = 4.0 ; // log10(C) ceiling = C <= 10000, 1000 would be the typical limit but I want it to give it a bit more leeway
23-
2418 /* User-defined nudging parameters*/
2519 femmodel->parameters ->FindParam (&maxiter, InversionMaxiterEnum);
26- IssmDouble tau_C = femmodel->parameters ->FindParam (InversionTauCEnum);
27- IssmDouble H0 = femmodel->parameters ->FindParam (InversionH0Enum);
28- IssmDouble r = femmodel->parameters ->FindParam (InversionRelaxationEnum);
29- IssmDouble yts = femmodel->parameters ->FindParam (ConstantsYtsEnum);
30- IssmDouble tmax = femmodel->parameters ->FindParam (TimesteppingFinalTimeEnum);
31- IssmDouble tmin = femmodel->parameters ->FindParam (TimesteppingStartTimeEnum);
32- IssmDouble deltat = (tmax - tmin);
20+ IssmDouble tau_C = femmodel->parameters ->FindParam (InversionTauCEnum);
21+ IssmDouble max_inc = femmodel->parameters ->FindParam (InversionMaxIncrementEnum);
22+ IssmDouble H0 = femmodel->parameters ->FindParam (InversionH0Enum);
23+ IssmDouble r = femmodel->parameters ->FindParam (InversionRelaxationEnum);
24+ IssmDouble yts = femmodel->parameters ->FindParam (ConstantsYtsEnum);
25+ IssmDouble tmax = femmodel->parameters ->FindParam (TimesteppingFinalTimeEnum);
26+ IssmDouble tmin = femmodel->parameters ->FindParam (TimesteppingStartTimeEnum);
27+ IssmDouble deltat = (tmax - tmin);
3328
3429 /* Fields before/after*/
3530 IssmDouble *C0 = NULL ;
31+ IssmDouble *Cmin = NULL ;
32+ IssmDouble *Cmax = NULL ;
3633 IssmDouble *C = NULL ;
3734 IssmDouble *H_obs = NULL ;
3835 IssmDouble *H_old = NULL ;
@@ -43,6 +40,8 @@ void controlnudging_core(FemModel* femmodel){
4340 /* Get Fields once and for all*/
4441 int numvertices = femmodel->vertices ->NumberOfVertices ();
4542 GetVectorFromInputsx (&C0 , femmodel, FrictionCoefficientEnum, VertexSIdEnum);
43+ GetVectorFromInputsx (&Cmin,femmodel, InversionMinParameterEnum, VertexSIdEnum);
44+ GetVectorFromInputsx (&Cmax,femmodel, InversionMaxParameterEnum, VertexSIdEnum);
4645 GetVectorFromInputsx (&H_obs, femmodel, ThicknessEnum, VertexSIdEnum);
4746
4847 femmodel->parameters ->SetParam (false ,SaveResultsEnum);
@@ -59,10 +58,10 @@ void controlnudging_core(FemModel* femmodel){
5958
6059 /* Extract results*/
6160 xDelete<IssmDouble>(C);
62- GetVectorFromInputsx (&H, femmodel, ThicknessEnum, VertexSIdEnum);
63- GetVectorFromInputsx (&C, femmodel, FrictionCoefficientEnum, VertexSIdEnum);
64- GetVectorFromInputsx (&V, femmodel, VelEnum, VertexSIdEnum);
65- GetVectorFromInputsx (&O_ls, femmodel, MaskOceanLevelsetEnum, VertexSIdEnum);
61+ GetVectorFromInputsx (&H, femmodel, ThicknessEnum, VertexSIdEnum);
62+ GetVectorFromInputsx (&C, femmodel, FrictionCoefficientEnum, VertexSIdEnum);
63+ GetVectorFromInputsx (&V, femmodel, VelEnum, VertexSIdEnum);
64+ GetVectorFromInputsx (&O_ls,femmodel, MaskOceanLevelsetEnum, VertexSIdEnum);
6665
6766 /* Update friction coefficient accordingly*/
6867 IssmDouble RMSE_H = 0 .;
@@ -101,8 +100,8 @@ void controlnudging_core(FemModel* femmodel){
101100 IssmDouble dC_log = deltat*(dCdt1 + dCdt2 + dCdt3);
102101
103102 /* Clip dC_log to not change too much*/
104- if (dC_log>maxstep ) dC_log = maxstep ;
105- if (dC_log<minstep ) dC_log = minstep ;
103+ if (dC_log> max_inc ) dC_log = max_inc ;
104+ if (dC_log<-max_inc ) dC_log = -max_inc ;
106105
107106 /* Correction: prevent C from decreasing where ice is too thin and
108107 * still thinning — the model needs more friction here, not less*/
@@ -112,12 +111,14 @@ void controlnudging_core(FemModel* femmodel){
112111
113112 /* Update friction coefficient now*/
114113 C[i] = pow (10 ., C_log + dC_log);
114+ if (C[i] > Cmax[i]) C[i] = Cmax[i];
115+ if (C[i] < Cmin[i]) C[i] = Cmin[i];
115116 }
116117
117118 InputUpdateFromVectorx (femmodel, C, FrictionCoefficientEnum, VertexSIdEnum);
118119
119120 /* Print statistics*/
120- _printf0_ (" → RMSE H : " << sqrt (RMSE_H /numvertices) << " m\n " );
121+ _printf0_ (" → RMSE H : " << sqrt (RMSE_H /numvertices) << " m\n " );
121122 _printf0_ (" → RMSE dHdt: " << sqrt (RMSE_dHdt/numvertices) << " m/yr\n " );
122123
123124 xDelete<IssmDouble>(H_old);
@@ -132,5 +133,7 @@ void controlnudging_core(FemModel* femmodel){
132133 /* Clean up and return*/
133134 xDelete<IssmDouble>(C);
134135 xDelete<IssmDouble>(C0 );
136+ xDelete<IssmDouble>(Cmin);
137+ xDelete<IssmDouble>(Cmax);
135138 xDelete<IssmDouble>(H_obs);
136139}
0 commit comments