- Timestamp:
- 05/26/14 11:22:52 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/AdjointBalancethicknessAnalysis.cpp
r18057 r18060 151 151 }/*}}}*/ 152 152 void AdjointBalancethicknessAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/ 153 _error_("Not implemented yet"); 153 /*The gradient of the cost function is calculated in 2 parts. 154 * 155 * dJ \partial J \partial lambda^T(KU-F) 156 * -- = ---------- + ------------------------ 157 * dk \partial k \parial k 158 * 159 * */ 160 161 /*If on water, grad = 0: */ 162 if(!element->IsIceInElement()) return; 163 164 /*Get list of cost functions*/ 165 int *responses = NULL; 166 int num_responses,resp; 167 element->FindParam(&num_responses,InversionNumCostFunctionsEnum); 168 element->FindParam(&responses,NULL,InversionCostFunctionsEnum); 169 170 /*Check that control_type is supported*/ 171 if(control_type!=VxEnum && 172 control_type!=VyEnum && 173 control_type!=BalancethicknessThickeningRateEnum){ 174 _error_("Control "<<EnumToStringx(control_type)<<" not supported"); 175 } 176 177 /*Deal with first part (partial derivative a J with respect to k)*/ 178 for(resp=0;resp<num_responses;resp++) switch(responses[resp]){ 179 case ThicknessAbsMisfitEnum: /*Nothing, \partial J/\partial k = 0*/ break; 180 case ThicknessAbsGradientEnum: /*Nothing, \partial J/\partial k = 0*/ break; 181 case ThicknessAlongGradientEnum: /*Nothing, \partial J/\partial k = 0*/ break; 182 case ThicknessAcrossGradientEnum: /*Nothing, \partial J/\partial k = 0*/ break; 183 default: _error_("response " << EnumToStringx(responses[resp]) << " not supported yet"); 184 } 185 186 /*Deal with second term*/ 187 switch(control_type){ 188 case BalancethicknessThickeningRateEnum: GradientJDhDt(element,gradient,control_index); break; 189 case VxEnum: GradientJVx( element,gradient,control_index); break; 190 case VyEnum: GradientJVy( element,gradient,control_index); break; 191 default: _error_("control type not supported yet: " << EnumToStringx(control_type)); 192 } 193 194 /*Clean up and return*/ 195 xDelete<int>(responses); 196 197 }/*}}}*/ 198 void AdjointBalancethicknessAnalysis::GradientJVx(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/ 199 200 /*Intermediaries*/ 201 IssmDouble Jdet,weight; 202 IssmDouble thickness,Dlambda[3],dp[3]; 203 IssmDouble *xyz_list= NULL; 204 205 /*Fetch number of vertices for this finite element*/ 206 int numvertices = element->GetNumberOfVertices(); 207 208 /*Initialize some vectors*/ 209 IssmDouble* basis = xNew<IssmDouble>(numvertices); 210 IssmDouble* ge = xNewZeroInit<IssmDouble>(numvertices); 211 int* vertexpidlist = xNew<int>(numvertices); 212 213 /*Retrieve all inputs we will be needing: */ 214 element->GetVerticesCoordinates(&xyz_list); 215 element->GradientIndexing(&vertexpidlist[0],control_index); 216 Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input); 217 Input* adjoint_input = element->GetInput(AdjointEnum); _assert_(adjoint_input); 218 219 /* Start looping on the number of gaussian points: */ 220 Gauss* gauss=element->NewGauss(4); 221 for(int ig=gauss->begin();ig<gauss->end();ig++){ 222 gauss->GaussPoint(ig); 223 224 adjoint_input->GetInputDerivativeValue(&Dlambda[0],xyz_list,gauss); 225 thickness_input->GetInputValue(&thickness, gauss); 226 thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 227 228 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 229 element->NodalFunctionsP1(basis,gauss); 230 231 /*Build gradient vector (actually -dJ/dD): */ 232 for(int i=0;i<numvertices;i++){ 233 ge[i]+=thickness*Dlambda[0]*Jdet*gauss->weight*basis[i]; 234 _assert_(!xIsNan<IssmDouble>(ge[i])); 235 } 236 } 237 gradient->SetValues(numvertices,vertexpidlist,ge,ADD_VAL); 238 239 /*Clean up and return*/ 240 xDelete<IssmDouble>(xyz_list); 241 xDelete<IssmDouble>(basis); 242 xDelete<IssmDouble>(ge); 243 xDelete<int>(vertexpidlist); 244 delete gauss; 245 }/*}}}*/ 246 void AdjointBalancethicknessAnalysis::GradientJVy(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/ 247 248 /*Intermediaries*/ 249 IssmDouble Jdet,weight; 250 IssmDouble thickness,Dlambda[3],dp[3]; 251 IssmDouble *xyz_list= NULL; 252 253 /*Fetch number of vertices for this finite element*/ 254 int numvertices = element->GetNumberOfVertices(); 255 256 /*Initialize some vectors*/ 257 IssmDouble* basis = xNew<IssmDouble>(numvertices); 258 IssmDouble* ge = xNewZeroInit<IssmDouble>(numvertices); 259 int* vertexpidlist = xNew<int>(numvertices); 260 261 /*Retrieve all inputs we will be needing: */ 262 element->GetVerticesCoordinates(&xyz_list); 263 element->GradientIndexing(&vertexpidlist[0],control_index); 264 Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input); 265 Input* adjoint_input = element->GetInput(AdjointEnum); _assert_(adjoint_input); 266 267 /* Start looping on the number of gaussian points: */ 268 Gauss* gauss=element->NewGauss(4); 269 for(int ig=gauss->begin();ig<gauss->end();ig++){ 270 gauss->GaussPoint(ig); 271 272 adjoint_input->GetInputDerivativeValue(&Dlambda[0],xyz_list,gauss); 273 thickness_input->GetInputValue(&thickness, gauss); 274 thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 275 276 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 277 element->NodalFunctionsP1(basis,gauss); 278 279 /*Build gradient vector (actually -dJ/dvy): */ 280 for(int i=0;i<numvertices;i++){ 281 ge[i]+=thickness*Dlambda[1]*Jdet*gauss->weight*basis[i]; 282 _assert_(!xIsNan<IssmDouble>(ge[i])); 283 } 284 } 285 gradient->SetValues(numvertices,vertexpidlist,ge,ADD_VAL); 286 287 /*Clean up and return*/ 288 xDelete<IssmDouble>(xyz_list); 289 xDelete<IssmDouble>(basis); 290 xDelete<IssmDouble>(ge); 291 xDelete<int>(vertexpidlist); 292 delete gauss; 293 }/*}}}*/ 294 void AdjointBalancethicknessAnalysis::GradientJDhDt(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/ 295 296 /*Fetch number of vertices for this finite element*/ 297 int numvertices = element->GetNumberOfVertices(); 298 299 /*Initialize some vectors*/ 300 IssmDouble* ge = xNewZeroInit<IssmDouble>(numvertices); 301 IssmDouble* lambda = xNew<IssmDouble>(numvertices); 302 int* vertexpidlist = xNew<int>(numvertices); 303 304 /*Retrieve all inputs we will be needing: */ 305 element->GradientIndexing(&vertexpidlist[0],control_index); 306 element->GetInputListOnVertices(lambda,AdjointEnum); 307 for(int i=0;i<numvertices;i++){ 308 ge[i]=-lambda[i]; 309 _assert_(!xIsNan<IssmDouble>(ge[i])); 310 } 311 gradient->SetValues(numvertices,vertexpidlist,ge,INS_VAL); 312 313 /*Clean up and return*/ 314 xDelete<IssmDouble>(ge); 315 xDelete<IssmDouble>(lambda); 316 xDelete<int>(vertexpidlist); 154 317 }/*}}}*/ 155 318 void AdjointBalancethicknessAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
Note:
See TracChangeset
for help on using the changeset viewer.