Changeset 4048 for issm/trunk/src/c/solutions/control_core.cpp
- Timestamp:
- 06/16/10 18:20:52 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/solutions/control_core.cpp
r4047 r4048 14 14 void control_core(FemModel* femmodel){ 15 15 16 Vec u_g=NULL;17 Vec t_g=NULL;18 Vec m_g=NULL;19 double search_scalar;16 int i,n; 17 18 /*parameters: */ 19 int verbose=0; 20 20 int control_type; 21 int control_steady; 22 int nsteps; 23 double eps_cm; 24 double tolx; 25 double cm_min; 26 double cm_max; 27 int cm_gradient; 28 21 29 double* fit=NULL; 22 30 double* optscal=NULL; 23 31 double* maxiter=NULL; 24 32 double* cm_jump=NULL; 25 double eps_cm; 26 double tolx; 27 double* param_g=NULL; 28 Vec grad_g=NULL; 29 Vec new_grad_g=NULL; 30 Vec grad_g_old=NULL; 31 double* grad_g_double=NULL; 32 double cm_min; 33 double cm_max; 34 int cm_gradient; 35 int nsteps,n,i; 36 double* J=NULL; 33 34 35 /*intermediary: */ 36 double search_scalar; 37 37 OptArgs optargs; 38 38 OptPars optpars; 39 Param* param=NULL;40 39 41 /*flags: */ 42 int analysis_type; 43 int sub_analysis_type; 44 int control_steady; 45 int verbose=0; 46 int converged=0; 47 int numberofnodes; 40 /*output: */ 41 double* J=NULL; 48 42 49 43 /*Process models*/ … … 62 56 femmodel->parameters->FindParam(&cm_max,CmMaxEnum); 63 57 femmodel->parameters->FindParam(&cm_gradient,CmGradientEnum); 64 femmodel->parameters->FindParam(¶m_g,NULL,NULL,ControlParameterEnum);65 femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);66 femmodel->parameters->FindParam(&sub_analysis_type,SubAnalysisTypeEnum);67 femmodel->parameters->FindParam(&numberofnodes,NumberOfNodesEnum);68 58 femmodel->parameters->FindParam(&control_steady,ControlSteadyEnum); 69 59 70 60 /*Initialize misfit: */ 71 61 J=(double*)xmalloc(nsteps*sizeof(double)); 72 62 63 /*Initialize some of the BrentSearch arguments: */ 64 optargs.femmodel=femmodel; 65 optpars.xmin=0; optpars.xmax=1; optpars.tolerance=tolx ; 66 73 67 /*Start looping: */ 74 68 for(n=0;n<nsteps;n++){ 75 69 76 70 _printf_("\n%s%i%s%i\n"," control method step ",n+1,"/",nsteps); 77 inputs->Add(control_type,param_g,1,numberofnodes);78 71 femmodel->UpdateInputsFromConstant(fit[n],FitEnum); 79 72 80 /*In case we are running a steady state control method, compute new temperature field using new parameter 81 * distribution: */ 73 /*In case we are running a steady state control method, compute new temperature field using new parameter * distribution: */ 82 74 if (control_steady) steadystate_core(model); 83 75 … … 87 79 /*Return gradient if asked: */ 88 80 if (cm_gradient){ 89 /*Transfer gradient from input to results: */90 81 InputToResultx(femodel->elements,femodel->nodes,femodel->vertices,femodel->loads,femodel->materials,femodel->parameters,GradientEnum); 91 return;82 goto cleanup_and_return; 92 83 } 93 84 94 /*Normalize if last gradient not satisfying (search_scalar==0)*/95 if (n>0 && search_scalar==0){96 _printf_("%s"," orthogonalization...");97 Orthx(&new_grad_g,grad_g,grad_g_old);98 _printf_("%s\n"," done.");99 }100 else{101 _printf_("%s"," normalizing directions...");102 Orthx(&new_grad_g,grad_g,NULL);103 _printf_("%s\n"," done.");104 }105 VecFree(&grad_g); VecFree(&grad_g_old);106 grad_g_old=new_grad_g;107 VecToMPISerial(&grad_g_double,new_grad_g);108 109 85 _printf_("%s\n"," optimizing along gradient direction"); 110 optargs.model=model; 111 optargs.param_g=param_g; optargs.grad_g=grad_g_double; optargs.n=n; 112 optpars.xmin=0; optpars.xmax=1; optpars.tolerance=tolx; optpars.maxiter=(int)maxiter[n];optpars.cm_jump=cm_jump[n]; 86 optargs.n=n; optpars.maxiter=(int)maxiter[n]; optpars.cm_jump=cm_jump[n]; 113 87 BrentSearch(&search_scalar,J+n,&optpars,&objectivefunctionC,&optargs); 114 88 115 89 _printf_("%s"," updating parameter using optimized search scalar..."); 116 for(i=0;i<numberofnodes;i++)param_g[i]=param_g[i]+search_scalar*optscal[n]*grad_g_double[i]; 117 _printf_("%s\n"," done."); 90 AXPYInputx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,control_type,search_scalar*optscal[n],ControlParameterEnum); 118 91 119 92 _printf_("%s"," constraining the new distribution..."); 120 ControlConstrainx(param_g,numberofnodes,cm_min,cm_max,control_type); 121 _printf_("%s\n"," done."); 93 ControlConstrainx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,control_type,cm_min,cm_max); 94 95 _printf_("%s"," save new parameter..."); 96 DuplicateInputx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,control_type,ControlParameterEnum); 122 97 123 98 _printf_("%s%i%s%g\n"," value of misfit J after optimization #",n+1,": ",J[n]); 99 100 if(controlconvergence)goto cleanup_and_return; 124 101 125 /*some freeing:*/ 126 xfree((void**)&grad_g_double); 127 128 /*Has convergence been reached?*/ 129 if (!isnan(eps_cm)){ 130 i=n-2; 131 //go through the previous misfits(starting from n-2) 132 while(i>=0){ 133 if (fit[i]==fit[n]){ 134 //convergence test only if we have the same misfits 135 if ((J[i]-J[n])/J[n] <= eps_cm){ 136 //convergence if convergence criteria fullfilled 137 converged=1; 138 _printf_("%s%g%s%g\n"," Convergence criterion: dJ/J = ",(J[i]-J[n])/J[n],"<",eps_cm); 139 } 140 else{ 141 _printf_("%s%g%s%g\n"," Convergence criterion: dJ/J = ",(J[i]-J[n])/J[n],">",eps_cm); 142 } 143 break; 144 } 145 i=i-1; 146 } 147 } 148 //stop if convergence has been reached 149 if(converged) break; 150 151 //some temporary saving 102 /*Temporary saving every 5 control steps: */ 152 103 if (((n+1)%5)==0){ 153 104 _printf_("%s"," saving temporary results..."); 154 ControlRestart(model,param_g); 155 _printf_("%s\n"," done."); 105 ControlRestart(femmodel); 156 106 } 157 107 } 158 108 159 /*Write results to disk: */160 109 _printf_("%s"," preparing final velocity solution"); 161 /*Launch diagnostic with the last parameter distribution*/ 162 if (control_steady){ 163 model->UpdateInputsFromVector(param_g,control_type,VertexEnum); 164 steadystate_results=steadystate_core(model); 110 if (control_steady) steadystate_core(femmodel); 111 else diagnostic_core(femmodel); 165 112 166 //extract u_g ,t_g and m_g from steadystate results, and erase diagnostic_results; 167 steadystate_results->FindResult(&u_g,"u_g"); 168 steadystate_results->FindResult(&m_g,"m_g"); 169 steadystate_results->FindResult(&t_g,"t_g"); 170 delete steadystate_results; 171 } 172 else{ 173 model->UpdateInputsFromVector(param_g,control_type,VertexEnum); 174 diagnostic_results=diagnostic_core(model); 113 /*some results not computed by steadystate_core or diagnostic_core: */ 114 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,control_type); //the parameter itself! 115 femmodel->otherresults->AddObject(new DoubleResult(femmodel->otherresults->Size()+1,0,1,"J",J,nsteps)); 116 femmodel->otherresults->AddObject(new StringResult(results->Size()+1,ControlTypeEnum,0,1,EnumAsString(control_type))); 175 117 176 //extract u_g from diagnostic_results, and erase diagnostic_results; 177 diagnostic_results->FindResult(&u_g,"u_g"); 178 delete diagnostic_results; 179 } 180 181 /*Plug results into output dataset: */ 182 results->AddObject(new Result(results->Size()+1,0,1,"u_g",u_g)); 183 results->AddObject(new Result(results->Size()+1,0,1,"param_g",param_g,numberofnodes)); 184 results->AddObject(new Result(results->Size()+1,0,1,"J",J,nsteps)); 185 if (control_steady){ 186 results->AddObject(new Result(results->Size()+1,0,1,"t_g",t_g)); 187 results->AddObject(new Result(results->Size()+1,0,1,"m_g",m_g)); 188 } 118 cleanup_and_return: 189 119 190 /*Add analysis_type and control_type to results: */191 results->AddObject(new StringResult(results->Size()+1,AnalysisTypeEnum,0,1,EnumAsString(analysis_type)));192 results->AddObject(new StringResult(results->Size()+1,ControlTypeEnum,0,1,EnumAsString(control_type)));193 194 120 /*Free ressources: */ 195 121 xfree((void**)&control_type); … … 198 124 xfree((void**)&maxiter); 199 125 xfree((void**)&cm_jump); 200 VecFree(&new_grad_g); //do not VecFree grad_g and grad_g_old, they point to new_grad_g201 xfree((void**)&grad_g_double);202 xfree((void**)¶m_g);203 VecFree(&u_g);204 VecFree(&t_g);205 VecFree(&m_g);206 126 xfree((void**)&J); 207 208 //return:209 return results;210 127 }
Note:
See TracChangeset
for help on using the changeset viewer.