Index: ../trunk-jpl/src/c/shared/Numerics/BrentSearch.cpp =================================================================== --- ../trunk-jpl/src/c/shared/Numerics/BrentSearch.cpp (revision 18127) +++ ../trunk-jpl/src/c/shared/Numerics/BrentSearch.cpp (revision 18128) @@ -19,205 +19,226 @@ #include "./types.h" #include "./isnan.h" -void BrentSearch(IssmDouble* psearch_scalar,IssmDouble* pJ,OptPars* optpars,IssmDouble (*f)(IssmDouble,void*),void* optargs){ +void BrentSearch(IssmDouble** pJ,OptPars optpars,IssmDouble* X0,IssmDouble (*f)(IssmDouble*,void*),IssmDouble (*g)(IssmDouble**,IssmDouble*,void*),void* usr){ /* This routine is optimizing a given function using Brent's method * (Golden or parabolic procedure)*/ /*Intermediary*/ + int iter; IssmDouble si,gold,intervalgold,oldintervalgold; - IssmDouble parab_num,parab_den; - IssmDouble distance,cm_jump; + IssmDouble parab_num,parab_den,distance; IssmDouble fxmax,fxmin,fxbest; IssmDouble fx,fx1,fx2; - IssmDouble xmax,xmin,xbest; - IssmDouble x,x1,x2,xm; + IssmDouble x,x1,x2,xm,xbest; IssmDouble tol1,tol2,seps; IssmDouble tolerance = 1.e-4; - int maxiter ,iter; - bool loop= true,goldenflag; /*Recover parameters:*/ - xmin=optpars->xmin; - xmax=optpars->xmax; - maxiter=optpars->maxiter; - cm_jump=optpars->cm_jump; + int nsteps = optpars.nsteps; + int nsize = optpars.nsize; + IssmDouble xmin = optpars.xmin; + IssmDouble xmax = optpars.xmax; + int *maxiter = optpars.maxiter; + IssmDouble *cm_jump = optpars.cm_jump; - /*initialize counter and get response at the boundaries*/ - iter=0; - fxmin = (*f)(xmin,optargs); - if (xIsNan(fxmin)) _error_("Function evaluation returned NaN"); - cout<(fxmax)) _error_("Function evaluation returned NaN"); - if(VerboseControl()) _printf0_(" N/A "<(nsteps); + IssmDouble* X = xNew(nsize); - /*test if jump option activated and xmin==0*/ - if (!xIsNan(cm_jump) && (xmin==0) && (fxmax/fxmin)(fxmin)) _error_("Function evaluation returned NaN"); + if(VerboseControl()) _printf0_("\n"); + if(VerboseControl()) _printf0_(" Iteration x f(x) Tolerance Procedure\n"); + if(VerboseControl()) _printf0_("\n"); + if(VerboseControl()) _printf0_(" N/A "<(fxmax)) _error_("Function evaluation returned NaN"); + if(VerboseControl()) _printf0_(" N/A "<(fxbest)) _error_("Function evaluation returned NaN"); - iter=iter+1; + /*test if jump option activated and xmin==0*/ + if(!xIsNan(cm_jump[n]) && (xmin==0) && (fxmax/fxmin)(G); + J[n]=fxmax; + continue; + } - /*3: update the other variables*/ - fx1=fxbest; - fx2=fxbest; - /*xm is always in the middle of a and b*/ - xm=0.5*(xmin+xmax); - /*update tolerances*/ - tol1=seps*sqrt(pow(xbest,2))+tolerance/3.0; - tol2=2.0*tol1; + /*initialize optimization variables*/ + seps=sqrt(DBL_EPSILON); //precision of a IssmDouble + distance=0.0; //new_x=old_x + distance + gold=0.5*(3.0-sqrt(5.0)); //gold = 1 - golden ratio + intervalgold=0.0; //distance used by Golden procedure - /*4: print result*/ - if(VerboseControl()) - _printf0_(" "<(cm_jump) && (xmin==0) && ((fxbest/fxmin)(fxbest)) _error_("Function evaluation returned NaN"); + iter++; - goldenflag=true; + /*3: update the other variables*/ + fx1=fxbest; + fx2=fxbest; + /*xm is always in the middle of a and b*/ + xm=0.5*(xmin+xmax); + /*update tolerances*/ + tol1=seps*sqrt(pow(xbest,2))+tolerance/3.0; + tol2=2.0*tol1; - // Is a parabolic fit possible ? - if (sqrt(pow(intervalgold,2))>tol1){ + /*4: print result*/ + if(VerboseControl()) + _printf0_(" "<(cm_jump[n]) && (xmin==0) && ((fxbest/fxmin)0.0){ - parab_num=-parab_num; - } - parab_den=sqrt(pow(parab_den,2)); - oldintervalgold=intervalgold; - intervalgold=distance; + bool goldenflag=true; - // Is the parabola acceptable (we use seps here because in some configuration parab_num==parab_den*(xmax-xbest) - // and the result is not repeatable anymore - if (( sqrt(pow(parab_num,2)) < sqrt(pow(0.5*parab_den*oldintervalgold,2))) && - (parab_num>parab_den*(xmin-xbest)+seps) && - (parab_numtol1){ - // Yes, parabolic interpolation step - distance=parab_num/parab_den; - x=xbest+distance; + // Yes, so fit parabola + goldenflag=false; + parab_num=(xbest-x1)*(xbest-x1)*(fxbest-fx2)-(xbest-x2)*(xbest-x2)*(fxbest-fx1);; + parab_den=2.0*(xbest-x1)*(fxbest-fx2)-2.0*(xbest-x2)*(fxbest-fx1); - // f must not be evaluated too close to min_x or max_x - if (((x-xmin)0.0){ + parab_num=-parab_num; } + parab_den=sqrt(pow(parab_den,2)); + oldintervalgold=intervalgold; + intervalgold=distance; + + // Is the parabola acceptable (we use seps here because in some configuration parab_num==parab_den*(xmax-xbest) + // and the result is not repeatable anymore + if (( sqrt(pow(parab_num,2)) < sqrt(pow(0.5*parab_den*oldintervalgold,2))) && + (parab_num>parab_den*(xmin-xbest)+seps) && + (parab_num=xm){ - intervalgold=xmin-xbest; + //Golden procedure + if(goldenflag){ + // compute the new distance d + if(xbest>=xm){ + intervalgold=xmin-xbest; + } + else{ + intervalgold=xmax-xbest; + } + distance=gold*intervalgold; } - else{ - intervalgold=xmax-xbest; - } - distance=gold*intervalgold; - } - // The function must not be evaluated too close to xbest - if(distance<0) si=-1; - else si=1; - if(sqrt(pow(distance,2))>tol1) x=xbest+si*sqrt(pow(distance,2)); - else x=xbest+si*tol1; + // The function must not be evaluated too close to xbest + if(distance<0) si=-1; + else si=1; + if(sqrt(pow(distance,2))>tol1) x=xbest+si*sqrt(pow(distance,2)); + else x=xbest+si*tol1; - //evaluate function on x - fx = (*f)(x,optargs); - if(xIsNan(fx)) _error_("Function evaluation returned NaN"); - iter=iter+1; + //evaluate function on x + for(int i=0;i(fx)) _error_("Function evaluation returned NaN"); + iter++; - // Update a, b, xm, x1, x2, tol1, tol2 - if (fx<=fxbest){ - if (x>=xbest) xmin=xbest; - else xmax=xbest; - x1=x2; fx1=fx2; - x2=xbest; fx2=fxbest; - xbest=x; fxbest=fx; - } - else{ // fx > fxbest - if (x=xbest) xmin=xbest; + else xmax=xbest; + x1=x2; fx1=fx2; + x2=xbest; fx2=fxbest; + xbest=x; fxbest=fx; } - else if ( (fx <= fx1) || (x1 == xbest) || (x1 == x2) ){ - x1=x; fx1=fx; + else{ // fx > fxbest + if (x=maxiter[n]){ + if(VerboseControl()) _printf0_(" exiting: Maximum number of iterations has been exceeded ('maxiter'=" << maxiter[n] << ")\n"); + loop=false; + } + else if (!xIsNan(cm_jump[n]) && (xmin==0) && ((fxbest/fxmin)fxmin){ + xbest=optpars.xmin; fxbest=fxmin; } - else if (iter>=maxiter){ - if(VerboseControl()) _printf0_(" exiting: Maximum number of iterations has been exceeded ('maxiter'=" << maxiter << ")\n"); - loop=false; + if (fxbest>fxmax){ + xbest=optpars.xmax; fxbest=fxmax; } - else if (!xIsNan(cm_jump) && (xmin==0) && ((fxbest/fxmin)fxmin){ - xbest=optpars->xmin; fxbest=fxmin; + /*Assign output pointers: */ + for(int i=0;i(G); + J[n]=fxbest; } - if (fxbest>fxmax){ - xbest=optpars->xmax; fxbest=fxmax; - } - - /*Assign output pointers: */ - *psearch_scalar=xbest; - *pJ=fxbest; + + /*return*/ + xDelete(X); + *pJ=J; } Index: ../trunk-jpl/src/c/shared/Numerics/numerics.h =================================================================== --- ../trunk-jpl/src/c/shared/Numerics/numerics.h (revision 18127) +++ ../trunk-jpl/src/c/shared/Numerics/numerics.h (revision 18128) @@ -29,7 +29,7 @@ int min(int a,int b); int max(int a,int b); -void BrentSearch(IssmDouble *psearch_scalar,IssmDouble*pJ,OptPars*optpars,IssmDouble (*f)(IssmDouble,void*),void* optargs); +void BrentSearch(IssmDouble** pJ,OptPars optpars,IssmDouble* X0,IssmDouble (*f)(IssmDouble*,void*),IssmDouble (*g)(IssmDouble**,IssmDouble*,void*),void* usr); void cross(IssmDouble *result,IssmDouble*vector1,IssmDouble*vector2); void XZvectorsToCoordinateSystem(IssmDouble *T,IssmDouble*xzvectors); int cubic(IssmDouble a, IssmDouble b, IssmDouble c, IssmDouble d, double X[3], int *num); Index: ../trunk-jpl/src/c/shared/Numerics/OptPars.h =================================================================== --- ../trunk-jpl/src/c/shared/Numerics/OptPars.h (revision 18127) +++ ../trunk-jpl/src/c/shared/Numerics/OptPars.h (revision 18128) @@ -9,10 +9,12 @@ struct OptPars{ - IssmDouble xmin; - IssmDouble xmax; - IssmDouble cm_jump; - int maxiter; + IssmDouble xmin; + IssmDouble xmax; + IssmDouble *cm_jump; + int* maxiter; + int nsteps; + int nsize; }; Index: ../trunk-jpl/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp =================================================================== --- ../trunk-jpl/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp (revision 18127) +++ ../trunk-jpl/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp (revision 18128) @@ -15,10 +15,10 @@ int num_control_type; int num_cm_responses; int *control_type = NULL; + int *maxiter = NULL; int *cm_responses = NULL; IssmDouble *cm_jump = NULL; IssmDouble *optscal = NULL; - IssmDouble *maxiter = NULL; /*retrieve some parameters: */ iomodel->Constant(&control_analysis,InversionIscontrolEnum); @@ -55,7 +55,7 @@ iomodel->FetchData(&maxiter,NULL,NULL,InversionMaxiterPerStepEnum); parameters->AddObject(new DoubleMatParam(InversionGradientScalingEnum,optscal,nsteps,num_control_type)); parameters->AddObject(new DoubleVecParam(InversionStepThresholdEnum,cm_jump,nsteps)); - parameters->AddObject(new DoubleVecParam(InversionMaxiterPerStepEnum,maxiter,nsteps)); + parameters->AddObject(new IntVecParam(InversionMaxiterPerStepEnum,maxiter,nsteps)); break; case 1:/*TAO*/ parameters->AddObject(iomodel->CopyConstantObject(InversionFatolEnum)); @@ -82,8 +82,8 @@ xDelete(control_type); xDelete(cm_responses); + xDelete(maxiter); iomodel->DeleteData(cm_jump,InversionStepThresholdEnum); iomodel->DeleteData(optscal,InversionGradientScalingEnum); - iomodel->DeleteData(maxiter,InversionMaxiterPerStepEnum); } } Index: ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp =================================================================== --- ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp (revision 18127) +++ ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp (revision 18128) @@ -6,18 +6,18 @@ #include "../../shared/shared.h" #include "../../toolkits/toolkits.h" -void SetControlInputsFromVectorx(Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters,IssmDouble* vector){ +void SetControlInputsFromVectorx(FemModel* femmodel,IssmDouble* vector){ int num_controls; int *control_type = NULL; /*Retrieve some parameters*/ - parameters->FindParam(&num_controls,InversionNumControlParametersEnum); - parameters->FindParam(&control_type,NULL,InversionControlParametersEnum); + femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum); + femmodel->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum); for(int i=0;iSize();j++){ - Element* element=(Element*)elements->GetObjectByOffset(j); + for(int j=0;jelements->Size();j++){ + Element* element=(Element*)femmodel->elements->GetObjectByOffset(j); element->SetControlInputsFromVector(vector,control_type[i],i); } } @@ -25,14 +25,9 @@ xDelete(control_type); } -void SetControlInputsFromVectorx(Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters,Vector* vector){ +void SetControlInputsFromVectorx(FemModel* femmodel,Vector* vector){ - IssmDouble* serial_vector=NULL; - - serial_vector=vector->ToMPISerial(); - - SetControlInputsFromVectorx(elements,nodes, vertices, loads, materials, parameters,serial_vector); - - /*Free ressources:*/ + IssmDouble* serial_vector=vector->ToMPISerial(); + SetControlInputsFromVectorx(femmodel,serial_vector); xDelete(serial_vector); } Index: ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.h =================================================================== --- ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.h (revision 18127) +++ ../trunk-jpl/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.h (revision 18128) @@ -7,7 +7,7 @@ #include "../../classes/classes.h" /* local prototypes: */ -void SetControlInputsFromVectorx(Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials, Parameters* parameters,Vector* vector); -void SetControlInputsFromVectorx(Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials, Parameters* parameters,IssmDouble* vector); +void SetControlInputsFromVectorx(FemModel* femmodel,Vector* vector); +void SetControlInputsFromVectorx(FemModel* femmodel,IssmDouble* vector); #endif Index: ../trunk-jpl/src/c/modules/Gradjx/Gradjx.cpp =================================================================== --- ../trunk-jpl/src/c/modules/Gradjx/Gradjx.cpp (revision 18127) +++ ../trunk-jpl/src/c/modules/Gradjx/Gradjx.cpp (revision 18128) @@ -49,6 +49,8 @@ gradient->AXPY(gradient_list[i],1.0); delete gradient_list[i]; } + //gradient->Echo(); + //_error_("S"); /*Check that gradient is clean*/ norm_inf=gradient->Norm(NORM_INF); Index: ../trunk-jpl/src/c/cores/controlvalidation_core.cpp =================================================================== --- ../trunk-jpl/src/c/cores/controlvalidation_core.cpp (revision 18127) +++ ../trunk-jpl/src/c/cores/controlvalidation_core.cpp (revision 18128) @@ -72,7 +72,7 @@ for(int i=0;ielements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X); + SetControlInputsFromVectorx(femmodel,X); solutioncore(femmodel); femmodel->CostFunctionx(&j,NULL,NULL); Index: ../trunk-jpl/src/c/cores/controlm1qn3_core.cpp =================================================================== --- ../trunk-jpl/src/c/cores/controlm1qn3_core.cpp (revision 18127) +++ ../trunk-jpl/src/c/cores/controlm1qn3_core.cpp (revision 18128) @@ -105,7 +105,7 @@ } /*Get solution*/ - SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X); + SetControlInputsFromVectorx(femmodel,X); ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G); femmodel->OutputControlsx(&femmodel->results); femmodel->results->AddObject(new GenericExternalResult(JEnum,f,1,0)); @@ -130,10 +130,9 @@ int solution_type; FemModel *femmodel = (FemModel*)dzs; - /*Recover responses*/ - int num_responses; - int *responses = NULL; - femmodel->parameters->FindParam(&responses,&num_responses,InversionCostFunctionsEnum); + /*Recover number of cost functions responses*/ + int num_responses; + femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum); /*Constrain input vector*/ IssmDouble *XL = NULL; @@ -146,7 +145,7 @@ } /*Update control input*/ - SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X); + SetControlInputsFromVectorx(femmodel,X); /*Recover some parameters*/ femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); @@ -169,7 +168,6 @@ if(indic==0){ /*dry run, no gradient required*/ - xDelete(responses); xDelete(XU); xDelete(XL); return; @@ -192,7 +190,6 @@ } /*Clean-up and return*/ - xDelete(responses); xDelete(XU); xDelete(XL); } Index: ../trunk-jpl/src/c/cores/control_core.cpp =================================================================== --- ../trunk-jpl/src/c/cores/control_core.cpp (revision 18127) +++ ../trunk-jpl/src/c/cores/control_core.cpp (revision 18128) @@ -10,15 +10,19 @@ #include "../solutionsequences/solutionsequences.h" /*Local prototypes*/ -bool controlconvergence(IssmDouble J, IssmDouble tol_cm); -IssmDouble objectivefunction(IssmDouble search_scalar,void* optargs); +IssmDouble FormFunction(IssmDouble* X,void* usr); +IssmDouble FormFunctionGradient(IssmDouble** pG,IssmDouble* X,void* usr); +typedef struct { + FemModel* femmodel; + int nsize; +} AppCtx; void control_core(FemModel* femmodel){ int i; /*parameters: */ - int num_controls; + int num_controls,nsize; int nsteps; IssmDouble tol_cm; int solution_type; @@ -26,11 +30,10 @@ bool dakota_analysis = false; int *control_type = NULL; - IssmDouble *maxiter = NULL; + int* maxiter = NULL; IssmDouble *cm_jump = NULL; /*intermediary: */ - IssmDouble search_scalar = 1.; OptPars optpars; /*Solution and Adjoint core pointer*/ @@ -60,37 +63,41 @@ if(VerboseControl()) _printf0_(" preparing initial solution\n"); if(isFS) solutioncore(femmodel); - /*Initialize cost function: */ - J=xNew(nsteps); + /*Get initial guess*/ + Vector *Xpetsc = NULL; + GetVectorFromControlInputsx(&Xpetsc,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value"); + IssmDouble* X0 = Xpetsc->ToMPISerial(); + Xpetsc->GetSize(&nsize); + delete Xpetsc; /*Initialize some of the BrentSearch arguments: */ - optpars.xmin=0; optpars.xmax=1; + optpars.xmin = 0; + optpars.xmax = 1; + optpars.nsteps = nsteps; + optpars.nsize = nsize; + optpars.maxiter = maxiter; + optpars.cm_jump = cm_jump; - /*Start looping: */ - for(int n=0;n(maxiter[n]); optpars.cm_jump=cm_jump[n]; - BrentSearch(&search_scalar,J+n,&optpars,&objectivefunction,(void*)femmodel); - - if(VerboseControl()) _printf0_(" updating parameter using optimized search scalar\n"); //true means update save controls - InputControlUpdatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,search_scalar,true); - - if(controlconvergence(J[n],tol_cm)) break; + if(VerboseControl()) _printf0_(" preparing final solution\n"); + IssmDouble *XL = NULL; + IssmDouble *XU = NULL; + GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound"); + GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound"); + for(long i=0;iXU[i]) X0[i]=XU[i]; + if(X0[i](XU); + xDelete(XL); + SetControlInputsFromVectorx(femmodel,X0); femmodel->parameters->SetParam(true,SaveResultsEnum); solutioncore(femmodel); @@ -110,84 +117,187 @@ /*Free ressources: */ xDelete(control_type); - xDelete(maxiter); + xDelete(maxiter); xDelete(cm_jump); xDelete(J); + xDelete(X0); } -bool controlconvergence(IssmDouble J, IssmDouble tol_cm){ - bool converged=false; +IssmDouble FormFunction(IssmDouble* X,void* usrvoid){ - /*Has convergence been reached?*/ - if (!xIsNan(tol_cm) && Jfemmodel; + int nsize = usr->nsize; /*Recover parameters: */ femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum); femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum); femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); + femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum); - /*set analysis type to compute velocity: */ + /*Constrain input vector*/ + IssmDouble *XL = NULL; + IssmDouble *XU = NULL; + GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound"); + GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound"); + for(long i=0;iXU[i]) X[i]=XU[i]; + if(X[i]SetCurrentConfiguration(StressbalanceAnalysisEnum); + stressbalance_core(femmodel); //We need a 3D velocity!! (vz is required for the next thermal run) + break; case StressbalanceSolutionEnum: femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum); + solutionsequence_nonlinear(femmodel,conserve_loads); break; case BalancethicknessSolutionEnum: femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum); + solutionsequence_linear(femmodel); break; case BalancethicknessSoftSolutionEnum: - femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum); + /*NOTHING*/ break; case Balancethickness2SolutionEnum: femmodel->SetCurrentConfiguration(Balancethickness2AnalysisEnum); + solutionsequence_linear(femmodel); break; default: _error_("Solution " << EnumToStringx(solution_type) << " not implemented yet"); } - /*update parameter according to scalar: */ //false means: do not save control - InputControlUpdatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,search_scalar,false); + /*Compute misfit for this velocity field.*/ + IssmDouble* Jlist = NULL; + femmodel->CostFunctionx(&J,&Jlist,NULL); + //_printf0_("f(x) = "<(XU); + xDelete(XL); + xDelete(Jlist); + return J; +} +IssmDouble FormFunctionGradient(IssmDouble** pG,IssmDouble* X,void* usrvoid){ + + /*output: */ + IssmDouble J; + + /*parameters: */ + void (*adjointcore)(FemModel*)=NULL; + int solution_type,analysis_type,num_responses,num_controls,numvertices; + bool isFS = false; + bool conserve_loads = true; + IssmDouble *scalar_list = NULL; + IssmDouble *Jlist = NULL; + IssmDouble *G = NULL; + IssmDouble *norm_list = NULL; + AppCtx *usr = (AppCtx*)usrvoid; + FemModel *femmodel = usr->femmodel; + int nsize = usr->nsize; + + /*Recover parameters: */ + femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum); + femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum); + femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); + femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum); + femmodel->parameters->FindParam(&scalar_list,NULL,NULL,InversionGradientScalingEnum); + femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum); _assert_(num_controls); + numvertices=femmodel->vertices->NumberOfVertices(); + + /*Constrain input vector*/ + IssmDouble *XL = NULL; + IssmDouble *XU = NULL; + GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound"); + GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound"); + for(long i=0;iXU[i]) X[i]=XU[i]; + if(X[i]elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters); + + /*Compute scaling factor*/ + IssmDouble scalar = scalar_list[0]/norm_list[0]; + for(int i=1;ielements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G); + + for(long i=0;i=XU[i]) G[i]=0.; + if(X[i]<=XL[i]) G[i]=0.; } - else if (solution_type==Balancethickness2SolutionEnum){ - solutionsequence_linear(femmodel); + + /*solve forward: (FIXME: not needed actually...)*/ + switch(solution_type){ + case SteadystateSolutionEnum: + femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum); + stressbalance_core(femmodel); //We need a 3D velocity!! (vz is required for the next thermal run) + break; + case StressbalanceSolutionEnum: + femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum); + solutionsequence_nonlinear(femmodel,conserve_loads); + break; + case BalancethicknessSolutionEnum: + femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum); + solutionsequence_linear(femmodel); + break; + case BalancethicknessSoftSolutionEnum: + /*NOTHING*/ + break; + case Balancethickness2SolutionEnum: + femmodel->SetCurrentConfiguration(Balancethickness2AnalysisEnum); + solutionsequence_linear(femmodel); + break; + default: + _error_("Solution " << EnumToStringx(solution_type) << " not implemented yet"); } - else if (solution_type==BalancethicknessSoftSolutionEnum){ - /*Don't do anything*/ - } - else{ - _error_("Solution " << EnumToStringx(solution_type) << " not implemented yet"); - } /*Compute misfit for this velocity field.*/ - femmodel->CostFunctionx(&J,NULL,NULL); + femmodel->CostFunctionx(&J,&Jlist,NULL); + //_printf0_("f(x) = "<(XU); + xDelete(XL); + xDelete(norm_list); + xDelete(scalar_list); + xDelete(Jlist); + *pG = G; return J; } Index: ../trunk-jpl/src/c/cores/controltao_core.cpp =================================================================== --- ../trunk-jpl/src/c/cores/controltao_core.cpp (revision 18127) +++ ../trunk-jpl/src/c/cores/controltao_core.cpp (revision 18128) @@ -92,7 +92,7 @@ TaoGetSolutionVector(tao,&X->pvector->vector); G=new Vector(0); VecFree(&G->pvector->vector); TaoGetGradientVector(tao,&G->pvector->vector); - SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X); + SetControlInputsFromVectorx(femmodel,X); ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G); femmodel->OutputControlsx(&femmodel->results); femmodel->results->AddObject(new GenericExternalResult(femmodel->results->Size()+1,JEnum,user.J,maxiter+3,1,1,0)); @@ -112,11 +112,11 @@ TaoDestroy(&tao); TaoFinalize(); } -int FormFunctionGradient(TaoSolver tao, Vec Xpetsc, IssmDouble *fcn,Vec G,void *userCtx){ +int FormFunctionGradient(TaoSolver tao, Vec Xpetsc, IssmDouble *fcn,Vec G,void *uservoid){ /*Retreive arguments*/ int solution_type; - AppCtx *user = (AppCtx *)userCtx; + AppCtx *user = (AppCtx *)uservoid; FemModel *femmodel = user->femmodel; Vector *gradient = NULL; Vector *X = NULL; @@ -126,7 +126,7 @@ /*Set new variable*/ //VecView(X,PETSC_VIEWER_STDOUT_WORLD); - SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X); + SetControlInputsFromVectorx(femmodel,X); delete X; /*Recover some parameters*/ Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp =================================================================== --- ../trunk-jpl/src/c/classes/Elements/Tria.cpp (revision 18127) +++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp (revision 18128) @@ -983,7 +983,6 @@ this->inputs->AddInput(new IntInput(ApproximationEnum,reCast(iomodel->Data(FlowequationElementEquationEnum)[index]))); } - /*Control Inputs*/ if (control_analysis && iomodel->Data(InversionControlParametersEnum)){ for(i=0;iGetInput(control_enum); if(!input) _error_("Input " << EnumToStringx(control_enum) << " not found in element"); @@ -2864,10 +2865,21 @@ void Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){/*{{{*/ IssmDouble values[NUMVERTICES]; - int vertexpidlist[NUMVERTICES]; - Input *input = NULL; - Input *new_input = NULL; + int vertexpidlist[NUMVERTICES],control_init; + Input *input = NULL; + Input *new_input = NULL; + /*Specific case for depth averaged quantities*/ + control_init=control_enum; + if(control_enum==MaterialsRheologyBbarEnum){ + control_enum=MaterialsRheologyBEnum; + if(!IsOnBase()) return; + } + if(control_enum==DamageDbarEnum){ + control_enum=DamageDEnum; + if(!IsOnBase()) return; + } + /*Get out if this is not an element input*/ if(!IsInput(control_enum)) return; @@ -2875,7 +2887,7 @@ GradientIndexing(&vertexpidlist[0],control_index); /*Get values on vertices*/ - for (int i=0;iSetInput(new_input); + + if(control_init==MaterialsRheologyBbarEnum){ + this->InputExtrude(control_enum); + } + if(control_init==DamageDbarEnum){ + this->InputExtrude(control_enum); + } } /*}}}*/ Index: ../trunk-jpl/src/m/classes/inversion.m =================================================================== --- ../trunk-jpl/src/m/classes/inversion.m (revision 18127) +++ ../trunk-jpl/src/m/classes/inversion.m (revision 18128) @@ -24,55 +24,55 @@ thickness_obs = NaN end methods - function createxml(obj,fid) % {{{ - fprintf(fid, '\n'); - - % inversion parameters - fprintf(fid,'%s\n%s\n%s\n','','
'); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' is inversion activated? ',' '); - - % incompleteadjoing drop-down (0 or 1) - fprintf(fid,'%s\n%s\n%s\n%s\n',' ','
',' 1: linear viscosity, 0: non-linear viscosity '); - fprintf(fid,'%s\n',' '); - fprintf(fid,'%s\n%s\n',' ',''); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''} ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' number of optimization searches ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' indicate the type of response for each optimization step ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' misfit convergence criterion. Default is 1%, NaN if not applied ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' maximum iterations during each optimization step ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' scaling factor on gradient direction during optimization, for each optimization step ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' decrease threshold for misfit, default is 30% ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' absolute minimum acceptable value of the inversed parameter on each vertex ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' absolute maximum acceptable value of the inversed parameter on each vertex ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity x component [m/yr] ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity y component [m/yr] ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity magnitude [m/yr] ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed thickness [m]) ',' '); - - fprintf(fid,'%s\n%s\n',''); - - fprintf(fid,'%s\n%s\n%s\n','','
'); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); - - fprintf(fid,'%s\n%s\n',''); - - end % }}} + function createxml(obj,fid) % {{{ + fprintf(fid, '\n'); + + % inversion parameters + fprintf(fid,'%s\n%s\n%s\n','','
'); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' is inversion activated? ',' '); + + % incompleteadjoing drop-down (0 or 1) + fprintf(fid,'%s\n%s\n%s\n%s\n',' ','
',' 1: linear viscosity, 0: non-linear viscosity '); + fprintf(fid,'%s\n',' '); + fprintf(fid,'%s\n%s\n',' ',''); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''} ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' number of optimization searches ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' indicate the type of response for each optimization step ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' misfit convergence criterion. Default is 1%, NaN if not applied ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' maximum iterations during each optimization step ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' scaling factor on gradient direction during optimization, for each optimization step ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' decrease threshold for misfit, default is 30% ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' absolute minimum acceptable value of the inversed parameter on each vertex ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' absolute maximum acceptable value of the inversed parameter on each vertex ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity x component [m/yr] ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity y component [m/yr] ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed velocity magnitude [m/yr] ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' observed thickness [m]) ',' '); + + fprintf(fid,'%s\n%s\n',''); + + fprintf(fid,'%s\n%s\n%s\n','','
'); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',' ','
',' ',' '); + + fprintf(fid,'%s\n%s\n',''); + + end % }}} function obj = inversion(varargin) % {{{ switch nargin case 0 @@ -195,7 +195,7 @@ WriteData(fid,'object',obj,'fieldname','incomplete_adjoint','format','Boolean'); if ~obj.iscontrol, return; end WriteData(fid,'object',obj,'fieldname','nsteps','format','Integer'); - WriteData(fid,'object',obj,'fieldname','maxiter_per_step','format','DoubleMat','mattype',3); + WriteData(fid,'object',obj,'fieldname','maxiter_per_step','format','IntMat','mattype',3); WriteData(fid,'object',obj,'fieldname','cost_functions_coefficients','format','DoubleMat','mattype',1); WriteData(fid,'object',obj,'fieldname','gradient_scaling','format','DoubleMat','mattype',3); WriteData(fid,'object',obj,'fieldname','cost_function_threshold','format','Double');