- Timestamp:
- 02/12/15 16:48:40 (10 years ago)
- Location:
- issm/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
- Property svn:ignore
-
old new 1 build-fw 2 build-ad 1 3 nightlylog 2 4 configure.sh
-
- Property svn:mergeinfo changed
/issm/trunk-jpl merged: 18302-18306,18308-18311,18313-18322,18326-18337,18339-18351,18353-18355,18357-18513,18515-19101
- Property svn:ignore
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/c
- Property svn:ignore
-
issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp
r18301 r19105 10 10 11 11 /*Model processing*/ 12 void LsfReinitializationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/ 13 /* Do nothing for now */ 14 }/*}}}*/ 15 void LsfReinitializationAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/ 16 /* Do nothing for now */ 17 }/*}}}*/ 18 void LsfReinitializationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/ 19 int finiteelement=P1Enum; 20 if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum); 21 ::CreateNodes(nodes,iomodel,LsfReinitializationAnalysisEnum,finiteelement); 22 iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum); 23 }/*}}}*/ 12 24 int LsfReinitializationAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/ 13 25 return 1; 14 }/*}}}*/15 void LsfReinitializationAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/16 /* Do nothing for now */17 26 }/*}}}*/ 18 27 void LsfReinitializationAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/ … … 34 43 iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum); 35 44 }/*}}}*/ 36 void LsfReinitializationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/ 37 int finiteelement=P1Enum; 38 if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum); 39 ::CreateNodes(nodes,iomodel,LsfReinitializationAnalysisEnum,finiteelement); 40 iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum); 41 }/*}}}*/ 42 void LsfReinitializationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/ 45 void LsfReinitializationAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/ 43 46 /* Do nothing for now */ 44 47 }/*}}}*/ 45 void LsfReinitializationAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/46 /* Do nothing for now */47 }/*}}}*/48 48 49 49 /*Finite element Analysis*/ 50 void LsfReinitializationAnalysis::Core(FemModel* femmodel){/*{{{*/50 void LsfReinitializationAnalysis::Core(FemModel* femmodel){/*{{{*/ 51 51 52 52 /*parameters: */ … … 249 249 return pe; 250 250 }/*}}}*/ 251 void LsfReinitializationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/ 251 void LsfReinitializationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 252 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 253 * For node i, Bi can be expressed in the actual coordinate system 254 * by: 255 * Bi=[ N ] 256 * [ N ] 257 * where N is the finiteelement function for node i. 258 * 259 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes) 260 */ 261 262 /*Fetch number of nodes for this finite element*/ 263 int numnodes = element->GetNumberOfNodes(); 264 265 /*Get nodal functions*/ 266 IssmDouble* basis=xNew<IssmDouble>(numnodes); 267 element->NodalFunctions(basis,gauss); 268 269 /*Build B: */ 270 for(int i=0;i<numnodes;i++){ 271 B[numnodes*0+i] = basis[i]; 272 B[numnodes*1+i] = basis[i]; 273 } 274 275 /*Clean-up*/ 276 xDelete<IssmDouble>(basis); 277 }/*}}}*/ 278 void LsfReinitializationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 279 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 280 * For node i, Bi' can be expressed in the actual coordinate system 281 * by: 282 * Bi_prime=[ dN/dx ] 283 * [ dN/dy ] 284 * where N is the finiteelement function for node i. 285 * 286 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes) 287 */ 288 289 /*Fetch number of nodes for this finite element*/ 290 int numnodes = element->GetNumberOfNodes(); 291 292 /*Get nodal functions derivatives*/ 293 IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes); 294 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 295 296 /*Build B': */ 297 for(int i=0;i<numnodes;i++){ 298 Bprime[numnodes*0+i] = dbasis[0*numnodes+i]; 299 Bprime[numnodes*1+i] = dbasis[1*numnodes+i]; 300 } 301 302 /*Clean-up*/ 303 xDelete<IssmDouble>(dbasis); 304 305 }/*}}}*/ 306 IssmDouble LsfReinitializationAnalysis::GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1){/*{{{*/ 307 // returns distance d of point q to straight going through points s0, s1 308 // d=|a x b|/|b| 309 // with a=q-s0, b=s1-s0 310 311 /* Intermediaries */ 312 const int dim=2; 313 int i; 314 IssmDouble a[dim], b[dim]; 315 IssmDouble norm_b; 316 317 for(i=0;i<dim;i++){ 318 a[i]=q[i]-s0[i]; 319 b[i]=s1[i]-s0[i]; 320 } 321 322 norm_b=0.; 323 for(i=0;i<dim;i++) 324 norm_b+=b[i]*b[i]; 325 norm_b=sqrt(norm_b); 326 _assert_(norm_b>0.); 327 328 return fabs(a[0]*b[1]-a[1]*b[0])/norm_b; 329 }/*}}}*/ 330 void LsfReinitializationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/ 252 331 253 332 IssmDouble lsf; … … 284 363 285 364 }/*}}}*/ 286 void LsfReinitializationAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/365 void LsfReinitializationAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/ 287 366 _error_("Not implemented yet"); 288 367 }/*}}}*/ 289 void LsfReinitializationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/368 void LsfReinitializationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/ 290 369 291 370 int domaintype; … … 301 380 } 302 381 }/*}}}*/ 303 void LsfReinitializationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/ 304 /* Do nothing for now */ 305 }/*}}}*/ 306 void LsfReinitializationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 307 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 308 * For node i, Bi can be expressed in the actual coordinate system 309 * by: 310 * Bi=[ N ] 311 * [ N ] 312 * where N is the finiteelement function for node i. 313 * 314 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes) 315 */ 316 317 /*Fetch number of nodes for this finite element*/ 318 int numnodes = element->GetNumberOfNodes(); 319 320 /*Get nodal functions*/ 321 IssmDouble* basis=xNew<IssmDouble>(numnodes); 322 element->NodalFunctions(basis,gauss); 323 324 /*Build B: */ 325 for(int i=0;i<numnodes;i++){ 326 B[numnodes*0+i] = basis[i]; 327 B[numnodes*1+i] = basis[i]; 328 } 329 330 /*Clean-up*/ 331 xDelete<IssmDouble>(basis); 332 }/*}}}*/ 333 void LsfReinitializationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 334 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 335 * For node i, Bi' can be expressed in the actual coordinate system 336 * by: 337 * Bi_prime=[ dN/dx ] 338 * [ dN/dy ] 339 * where N is the finiteelement function for node i. 340 * 341 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes) 342 */ 343 344 /*Fetch number of nodes for this finite element*/ 345 int numnodes = element->GetNumberOfNodes(); 346 347 /*Get nodal functions derivatives*/ 348 IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes); 349 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 350 351 /*Build B': */ 352 for(int i=0;i<numnodes;i++){ 353 Bprime[numnodes*0+i] = dbasis[0*numnodes+i]; 354 Bprime[numnodes*1+i] = dbasis[1*numnodes+i]; 355 } 356 357 /*Clean-up*/ 358 xDelete<IssmDouble>(dbasis); 359 360 }/*}}}*/ 361 362 /* Other */ 363 void LsfReinitializationAnalysis::SetReinitSPCs(FemModel* femmodel){/*{{{*/ 382 bool LsfReinitializationAnalysis::ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol){/*{{{*/ 383 384 /*Output*/ 385 bool converged = true; 386 387 /*Intermediary*/ 388 Vector<IssmDouble>* dlsfg = NULL; 389 IssmDouble norm_dlsf,norm_lsf; 390 391 /*compute norm(du)/norm(u)*/ 392 dlsfg=lsfg_old->Duplicate(); lsfg_old->Copy(dlsfg); dlsfg->AYPX(lsfg,-1.0); 393 norm_dlsf=dlsfg->Norm(NORM_TWO); norm_lsf=lsfg_old->Norm(NORM_TWO); 394 if (xIsNan<IssmDouble>(norm_dlsf) || xIsNan<IssmDouble>(norm_lsf)) _error_("convergence criterion is NaN!"); 395 if((norm_dlsf/norm_lsf)<reltol){ 396 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" < "<<reltol*100<<" %\n"); 397 } 398 else{ 399 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" > "<<reltol*100<<" %\n"); 400 converged=false; 401 } 402 403 /*Cleanup*/ 404 delete dlsfg; 405 406 return converged; 407 }/*}}}*/ 408 void LsfReinitializationAnalysis::SetDistanceOnIntersectedElements(FemModel* femmodel){/*{{{*/ 409 410 /* Intermediaries */ 411 int i; 412 IssmDouble dmaxp,dmaxm,val; 413 Element* element; 414 415 /*Initialize vector with number of vertices*/ 416 int numvertices=femmodel->vertices->NumberOfVertices(); 417 418 Vector<IssmDouble>* vec_dist_zerolevelset = NULL; 419 GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexPIdEnum); 420 421 /* set distance on elements intersected by zero levelset */ 422 for(i=0;i<femmodel->elements->Size();i++){ 423 element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 424 if(element->IsZeroLevelset(MaskIceLevelsetEnum)){ 425 SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element); 426 } 427 } 428 vec_dist_zerolevelset->Assemble(); 429 430 /* Get maximum distance to interface along vertices */ 431 dmaxp=0.; dmaxm=0.; 432 for(i=0;i<numvertices;i++){ 433 vec_dist_zerolevelset->GetValue(&val,i); 434 if((val>0.) && (val>dmaxp)) 435 dmaxp=val; 436 else if((val<0.) && (val<dmaxm)) 437 dmaxm=val; 438 } 439 //wait until all values are computed 440 441 /* set all none intersected vertices to max/min distance */ 442 for(i=0;i<numvertices;i++){ 443 vec_dist_zerolevelset->GetValue(&val,i); 444 if(val==1.) //FIXME: improve check 445 vec_dist_zerolevelset->SetValue(i,3.*dmaxp,INS_VAL); 446 else if(val==-1.) 447 vec_dist_zerolevelset->SetValue(i,3.*dmaxm,INS_VAL); 448 } 449 450 /*Assemble vector and serialize */ 451 vec_dist_zerolevelset->Assemble(); 452 IssmDouble* dist_zerolevelset=vec_dist_zerolevelset->ToMPISerial(); 453 InputUpdateFromVectorx(femmodel,dist_zerolevelset,MaskIceLevelsetEnum,VertexSIdEnum); 454 455 /*Clean up and return*/ 456 delete vec_dist_zerolevelset; 457 delete dist_zerolevelset; 458 459 }/*}}}*/ 460 void LsfReinitializationAnalysis::SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element){/*{{{*/ 461 462 if(!element->IsZeroLevelset(MaskIceLevelsetEnum)) 463 return; 464 465 /* Intermediaries */ 466 int dim=3; 467 int i,d; 468 IssmDouble dist,lsf_old; 469 470 int numvertices=element->GetNumberOfVertices(); 471 472 IssmDouble* lsf = xNew<IssmDouble>(numvertices); 473 IssmDouble* sign_lsf = xNew<IssmDouble>(numvertices); 474 IssmDouble* signed_dist = xNew<IssmDouble>(numvertices); 475 IssmDouble* s0 = xNew<IssmDouble>(dim); 476 IssmDouble* s1 = xNew<IssmDouble>(dim); 477 IssmDouble* v = xNew<IssmDouble>(dim); 478 IssmDouble* xyz_list = NULL; 479 IssmDouble* xyz_list_zero = NULL; 480 481 /* retrieve inputs and parameters */ 482 element->GetVerticesCoordinates(&xyz_list); 483 element->GetInputListOnVertices(lsf,MaskIceLevelsetEnum); 484 485 /* get sign of levelset function */ 486 for(i=0;i<numvertices;i++) 487 sign_lsf[i]=(lsf[i]>=0.?1.:-1.); 488 489 element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum); 490 for(i=0;i<dim;i++){ 491 s0[i]=xyz_list_zero[0+i]; 492 s1[i]=xyz_list_zero[3+i]; 493 } 494 495 /* get signed_distance of vertices to zero levelset straight */ 496 for(i=0;i<numvertices;i++){ 497 for(d=0;d<dim;d++) 498 v[d]=xyz_list[dim*i+d]; 499 dist=GetDistanceToStraight(&v[0],&s0[0],&s1[0]); 500 signed_dist[i]=sign_lsf[i]*dist; 501 } 502 503 /* insert signed_distance into vec_signed_dist, if computed distance is smaller */ 504 for(i=0;i<numvertices;i++){ 505 vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid()); 506 /* initial lsf values are +-1. Update those fields or if distance to interface smaller.*/ 507 if(fabs(lsf_old)==1. || fabs(signed_dist[i])<fabs(lsf_old)) 508 vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL); 509 } 510 511 xDelete<IssmDouble>(lsf); 512 xDelete<IssmDouble>(sign_lsf); 513 xDelete<IssmDouble>(signed_dist); 514 xDelete<IssmDouble>(s0); 515 xDelete<IssmDouble>(s1); 516 xDelete<IssmDouble>(v); 517 518 }/*}}}*/ 519 void LsfReinitializationAnalysis::SetReinitSPCs(FemModel* femmodel){/*{{{*/ 364 520 365 521 int i,k, numnodes; … … 369 525 /* deactivate all spcs */ 370 526 for(i=0;i<femmodel->elements->Size();i++){ 371 element= dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));527 element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 372 528 for(k=0;k<element->GetNumberOfNodes();k++){ 373 529 node=element->GetNode(k); … … 382 538 /* reactivate spcs on elements intersected by zero levelset */ 383 539 for(i=0;i<femmodel->elements->Size();i++){ 384 element= dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));540 element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 385 541 if(element->IsZeroLevelset(MaskIceLevelsetEnum)){ 386 542 /*iterate over nodes and set spc */ … … 399 555 400 556 }/*}}}*/ 401 void LsfReinitializationAnalysis::SetDistanceOnIntersectedElements(FemModel* femmodel){/*{{{*/ 402 403 /* Intermediaries */ 404 int i; 405 IssmDouble dmaxp,dmaxm,val; 406 Element* element; 407 408 /*Initialize vector with number of vertices*/ 409 int numvertices=femmodel->vertices->NumberOfVertices(); 410 411 Vector<IssmDouble>* vec_dist_zerolevelset = NULL; 412 GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexEnum); 413 414 /* set distance on elements intersected by zero levelset */ 415 for(i=0;i<femmodel->elements->Size();i++){ 416 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 417 if(element->IsZeroLevelset(MaskIceLevelsetEnum)){ 418 SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element); 419 } 420 } 421 vec_dist_zerolevelset->Assemble(); 422 423 /* Get maximum distance to interface along vertices */ 424 dmaxp=0.; dmaxm=0.; 425 for(i=0;i<numvertices;i++){ 426 vec_dist_zerolevelset->GetValue(&val,i); 427 if((val>0.) && (val>dmaxp)) 428 dmaxp=val; 429 else if((val<0.) && (val<dmaxm)) 430 dmaxm=val; 431 } 432 //wait until all values are computed 433 434 /* set all none intersected vertices to max/min distance */ 435 for(i=0;i<numvertices;i++){ 436 vec_dist_zerolevelset->GetValue(&val,i); 437 if(val==1.) //FIXME: improve check 438 vec_dist_zerolevelset->SetValue(i,3.*dmaxp,INS_VAL); 439 else if(val==-1.) 440 vec_dist_zerolevelset->SetValue(i,3.*dmaxm,INS_VAL); 441 } 442 443 /*Assemble vector and serialize */ 444 vec_dist_zerolevelset->Assemble(); 445 IssmDouble* dist_zerolevelset=vec_dist_zerolevelset->ToMPISerial(); 446 InputUpdateFromVectorx(femmodel,dist_zerolevelset,MaskIceLevelsetEnum,VertexSIdEnum); 447 448 /*Clean up and return*/ 449 delete vec_dist_zerolevelset; 450 delete dist_zerolevelset; 451 452 }/*}}}*/ 453 void LsfReinitializationAnalysis::SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element){/*{{{*/ 454 455 if(!element->IsZeroLevelset(MaskIceLevelsetEnum)) 456 return; 457 458 /* Intermediaries */ 459 int dim=3; 460 int i,d; 461 IssmDouble dist,lsf_old; 462 463 int numvertices=element->GetNumberOfVertices(); 464 465 IssmDouble* lsf = xNew<IssmDouble>(numvertices); 466 IssmDouble* sign_lsf = xNew<IssmDouble>(numvertices); 467 IssmDouble* signed_dist = xNew<IssmDouble>(numvertices); 468 IssmDouble* s0 = xNew<IssmDouble>(dim); 469 IssmDouble* s1 = xNew<IssmDouble>(dim); 470 IssmDouble* v = xNew<IssmDouble>(dim); 471 IssmDouble* xyz_list = NULL; 472 IssmDouble* xyz_list_zero = NULL; 473 474 /* retrieve inputs and parameters */ 475 element->GetVerticesCoordinates(&xyz_list); 476 element->GetInputListOnVertices(lsf,MaskIceLevelsetEnum); 477 478 /* get sign of levelset function */ 479 for(i=0;i<numvertices;i++) 480 sign_lsf[i]=(lsf[i]>=0.?1.:-1.); 481 482 element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum); 483 for(i=0;i<dim;i++){ 484 s0[i]=xyz_list_zero[0+i]; 485 s1[i]=xyz_list_zero[3+i]; 486 } 487 488 /* get signed_distance of vertices to zero levelset straight */ 489 for(i=0;i<numvertices;i++){ 490 for(d=0;d<dim;d++) 491 v[d]=xyz_list[dim*i+d]; 492 dist=GetDistanceToStraight(&v[0],&s0[0],&s1[0]); 493 signed_dist[i]=sign_lsf[i]*dist; 494 } 495 496 /* insert signed_distance into vec_signed_dist, if computed distance is smaller */ 497 for(i=0;i<numvertices;i++){ 498 vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid()); 499 /* initial lsf values are +-1. Update those fields or if distance to interface smaller.*/ 500 if(fabs(lsf_old)==1. || fabs(signed_dist[i])<fabs(lsf_old)) 501 vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL); 502 } 503 504 xDelete<IssmDouble>(lsf); 505 xDelete<IssmDouble>(sign_lsf); 506 xDelete<IssmDouble>(signed_dist); 507 xDelete<IssmDouble>(s0); 508 xDelete<IssmDouble>(s1); 509 xDelete<IssmDouble>(v); 510 511 }/*}}}*/ 512 IssmDouble LsfReinitializationAnalysis::GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1){/*{{{*/ 513 // returns distance d of point q to straight going through points s0, s1 514 // d=|a x b|/|b| 515 // with a=q-s0, b=s1-s0 516 517 /* Intermediaries */ 518 const int dim=2; 519 int i; 520 IssmDouble a[dim], b[dim]; 521 IssmDouble norm_b; 522 523 for(i=0;i<dim;i++){ 524 a[i]=q[i]-s0[i]; 525 b[i]=s1[i]-s0[i]; 526 } 527 528 norm_b=0.; 529 for(i=0;i<dim;i++) 530 norm_b+=b[i]*b[i]; 531 norm_b=sqrt(norm_b); 532 _assert_(norm_b>0.); 533 534 return fabs(a[0]*b[1]-a[1]*b[0])/norm_b; 535 }/*}}}*/ 536 bool LsfReinitializationAnalysis::ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol){/*{{{*/ 537 538 /*Output*/ 539 bool converged = true; 540 541 /*Intermediary*/ 542 Vector<IssmDouble>* dlsfg = NULL; 543 IssmDouble norm_dlsf,norm_lsf; 544 545 /*compute norm(du)/norm(u)*/ 546 dlsfg=lsfg_old->Duplicate(); lsfg_old->Copy(dlsfg); dlsfg->AYPX(lsfg,-1.0); 547 norm_dlsf=dlsfg->Norm(NORM_TWO); norm_lsf=lsfg_old->Norm(NORM_TWO); 548 if (xIsNan<IssmDouble>(norm_dlsf) || xIsNan<IssmDouble>(norm_lsf)) _error_("convergence criterion is NaN!"); 549 if((norm_dlsf/norm_lsf)<reltol){ 550 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" < "<<reltol*100<<" %\n"); 551 } 552 else{ 553 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" > "<<reltol*100<<" %\n"); 554 converged=false; 555 } 556 557 /*Cleanup*/ 558 delete dlsfg; 559 560 return converged; 561 }/*}}}*/ 557 void LsfReinitializationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/ 558 /* Do nothing for now */ 559 }/*}}}*/
Note:
See TracChangeset
for help on using the changeset viewer.