Changeset 17503
- Timestamp:
- 03/20/14 11:02:44 (11 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/LsfReinitializationAnalysis.cpp
r17336 r17503 4 4 #include "../shared/shared.h" 5 5 #include "../modules/modules.h" 6 #include "../solutionsequences/solutionsequences.h" 7 #include "../cores/cores.h" 6 8 7 9 #include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h" … … 29 31 } 30 32 } 33 34 iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum); 31 35 }/*}}}*/ 32 36 void LsfReinitializationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/ 33 37 int finiteelement=P1Enum; 38 if(iomodel->meshtype!=Mesh2DhorizontalEnum) iomodel->FetchData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum); 34 39 ::CreateNodes(nodes,iomodel,LsfReinitializationAnalysisEnum,finiteelement); 40 iomodel->DeleteData(2,MeshVertexonbedEnum,MeshVertexonsurfaceEnum); 35 41 }/*}}}*/ 36 42 void LsfReinitializationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/ … … 46 52 /*parameters: */ 47 53 bool save_results; 54 int maxiter = 3; 55 int step; 56 IssmDouble reltol = 0.05; 57 58 Vector<IssmDouble>* lsfg = NULL; 59 Vector<IssmDouble>* lsfg_old = NULL; 60 48 61 femmodel->parameters->FindParam(&save_results,SaveResultsEnum); 49 62 … … 53 66 /* set spcs for reinitialization */ 54 67 if(VerboseSolution()) _printf0_("Update spcs for reinitialization:\n"); 55 UpdateReinitSPCs(femmodel); 56 57 if(VerboseSolution()) _printf0_("call computational core for reinitialization:\n"); 58 // solutionsequence_lsfreinit_linear(femmodel); 68 SetReinitSPCs(femmodel); 69 70 step = 1; 71 for(;;){ 72 73 _printf_("smoothing lsf slope\n"); 74 /* smoothen slope of lsf for computation of normal on ice domain*/ 75 levelsetfunctionslope_core(femmodel); 76 77 //solve current artificial time step 78 if(VerboseSolution()) _printf0_("call computational core for reinitialization in step " << step << ":\n"); 79 solutionsequence_linear(femmodel); 80 GetSolutionFromInputsx(&lsfg,femmodel); 81 82 if(step>1){ 83 if(VerboseSolution()) _printf0_(" checking reinitialization convergence\n"); 84 if(ReinitConvergence(lsfg,lsfg_old,reltol)) break; 85 } 86 if(step>maxiter){ 87 if(VerboseSolution()) _printf0_(" maximum number reinitialization iterations " << maxiter << " reached\n"); 88 break; 89 } 90 91 /*update results and increase counter*/ 92 delete lsfg_old;lsfg_old=lsfg; 93 step++; 94 } 59 95 60 96 if(save_results){ 61 97 if(VerboseSolution()) _printf0_(" saving results\n"); 62 int outputs = MaskIceLevelsetEnum;63 femmodel->RequestedOutputsx(&femmodel->results,&outputs ,1);98 int outputs[1] = {MaskIceLevelsetEnum}; 99 femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1); 64 100 } 65 101 … … 73 109 }/*}}}*/ 74 110 ElementMatrix* LsfReinitializationAnalysis::CreateKMatrix(Element* element){/*{{{*/ 75 111 76 112 /*Intermediaries */ 77 113 const int dim = 2; 78 114 int i,row,col,stabilization; 79 IssmDouble Jdet,D_scalar,h; 80 IssmDouble dlsf[3],normal[3]; 81 IssmDouble norm_dlsf; 82 IssmDouble hx,hy,hz,kappa; 115 IssmDouble Jdet,D_scalar; 116 IssmDouble dtau = 1.; 117 IssmDouble mu = 1.; 83 118 IssmDouble* xyz_list = NULL; 84 119 … … 88 123 /*Initialize Element vector and other vectors*/ 89 124 ElementMatrix* Ke = element->NewElementMatrix(); 90 IssmDouble* B = xNew<IssmDouble>(dim*numnodes);125 IssmDouble* basis = xNew<IssmDouble>(numnodes); 91 126 IssmDouble* Bprime = xNew<IssmDouble>(dim*numnodes); 92 IssmDouble D[dim][dim];93 94 /*Retrieve all inputs and parameters*/95 Input* lsfpicard_input=element->GetInput(LevelsetfunctionPicardEnum); _assert_(lsfpicard_input); 127 IssmDouble* D = xNew<IssmDouble>(dim*dim); 128 IssmDouble* dlsf = xNew<IssmDouble>(dim); 129 IssmDouble* normal= xNew<IssmDouble>(dim); 130 96 131 element->GetVerticesCoordinates(&xyz_list); 97 h = element->CharacteristicLength();98 132 99 133 /* Start looping on the number of gaussian points: */ … … 103 137 104 138 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 105 GetB(B,element,xyz_list,gauss); 139 D_scalar=gauss->weight*Jdet; 140 141 if(dtau!=0.){ 142 element->NodalFunctions(basis,gauss); 143 TripleMultiply(basis,numnodes,1,0, 144 &D_scalar,1,1,0, 145 basis,1,numnodes,0, 146 &Ke->values[0],1); 147 D_scalar*=dtau; 148 } 149 106 150 GetBprime(Bprime,element,xyz_list,gauss); 107 108 /* Get normal from last iteration on lsf */109 lsfpicard_input->GetInputDerivativeValue(&dlsf[0],xyz_list,gauss);110 111 norm_dlsf=0.;112 for(i=0;i<dim;i++) norm_dlsf+=dlsf[i]*dlsf[i];113 norm_dlsf=sqrt(norm_dlsf); _assert_(norm_dlsf>0.);114 for(i=0;i<dim;i++)115 normal[i]=dlsf[i]/norm_dlsf;116 117 D_scalar=gauss->weight*Jdet;118 151 119 152 for(row=0;row<dim;row++) 120 153 for(col=0;col<dim;col++) 121 154 if(row==col) 122 D[row ][col]=D_scalar*normal[row];155 D[row*dim+col]=mu*D_scalar; 123 156 else 124 D[row ][col]=0.;125 TripleMultiply(B ,dim,numnodes,1,126 &D[0][0],dim,dim,0,157 D[row*dim+col]=0.; 158 TripleMultiply(Bprime,dim,numnodes,1, 159 D,dim,dim,0, 127 160 Bprime,dim,numnodes,0, 128 161 &Ke->values[0],1); 129 162 130 /* Stabilization */ /*{{{*/131 stabilization= 1;163 /* Stabilization */ 164 stabilization=0; 132 165 if (stabilization==0){/* no stabilization, do nothing*/} 133 else if(stabilization==1){ 134 /* Artificial Diffusion */ 135 element->ElementSizes(&hx,&hy,&hz); 136 h=sqrt( pow(hx*normal[0],2) + pow(hy*normal[1],2)); 137 kappa=h/2.; 138 D[0][0]=D_scalar*kappa; 139 D[0][1]=0.; 140 D[1][0]=0.; 141 D[1][1]=D_scalar*kappa; 142 TripleMultiply(Bprime,dim,numnodes,1, 143 &D[0][0],dim,dim,0, 144 Bprime,dim,numnodes,0, 145 &Ke->values[0],1); 146 } 147 else if(stabilization==2){ 148 /*Streamline upwinding - do not use this for extrapolation: yields oscillating results due to smoothing along normal, not across */ 149 for(row=0;row<dim;row++) 150 for(col=0;col<dim;col++) 151 D[row][col]=h/(2.*1.)*normal[row]*normal[col]; 152 153 TripleMultiply(Bprime,dim,numnodes,1, 154 &D[0][0],dim,dim,0, 155 Bprime,dim,numnodes,0, 156 &Ke->values[0],1); 157 }/*}}}*/ 166 158 167 }/*}}}*/ 159 168 160 169 /*Clean up and return*/ 161 170 xDelete<IssmDouble>(xyz_list); 162 xDelete<IssmDouble>( B);171 xDelete<IssmDouble>(basis); 163 172 xDelete<IssmDouble>(Bprime); 173 xDelete<IssmDouble>(D); 164 174 delete gauss; 165 175 return Ke; … … 168 178 169 179 /*Intermediaries */ 170 IssmDouble Jdet; 171 IssmDouble* xyz_list = NULL; 172 180 int i,k; 181 int dim = 2; 182 IssmDouble dtau = 1.; 183 IssmDouble mu = 1.; 184 IssmDouble Jdet, D_scalar; 185 IssmDouble lsf; 186 IssmDouble norm_dlsf; 187 IssmDouble dbasis_normal; 188 173 189 /*Fetch number of nodes */ 174 190 int numnodes = element->GetNumberOfNodes(); 175 191 192 IssmDouble* xyz_list = NULL; 176 193 IssmDouble* basis = xNew<IssmDouble>(numnodes); 194 IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes); 195 IssmDouble* dlsf = xNew<IssmDouble>(dim); 196 IssmDouble* normal = xNew<IssmDouble>(dim); 177 197 element->GetVerticesCoordinates(&xyz_list); 178 198 179 199 /*Initialize Element vector*/ 180 200 ElementVector* pe = element->NewElementVector(); 201 202 /*Retrieve all inputs and parameters*/ 203 Input* lsf_input = element->GetInput(MaskIceLevelsetEnum); _assert_(lsf_input); 204 Input* lsf_slopex_input=element->GetInput(LevelsetfunctionSlopeXEnum); _assert_(lsf_slopex_input); 205 Input* lsf_slopey_input=element->GetInput(LevelsetfunctionSlopeYEnum); _assert_(lsf_slopey_input); 181 206 182 207 Gauss* gauss=element->NewGauss(2); … … 186 211 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 187 212 element->NodalFunctions(basis,gauss); 188 189 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*basis[i]; 213 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 214 215 D_scalar=Jdet*gauss->weight; 216 217 if(dtau!=0.){ 218 /* old function value */ 219 lsf_input->GetInputValue(&lsf,gauss); 220 for(i=0;i<numnodes;i++) pe->values[i]+=D_scalar*lsf*basis[i]; 221 D_scalar*=dtau; 222 } 223 224 lsf_slopex_input->GetInputValue(&dlsf[0],gauss); 225 lsf_slopey_input->GetInputValue(&dlsf[1],gauss); 226 227 /*get normal*/ 228 norm_dlsf=0.; 229 for(i=0;i<dim;i++) norm_dlsf+=dlsf[i]*dlsf[i]; 230 norm_dlsf=sqrt(norm_dlsf); 231 if(norm_dlsf>0.) 232 for(i=0;i<dim;i++) normal[i]=dlsf[i]/norm_dlsf; 233 else 234 for(i=0;i<dim;i++) normal[i]=0.; 235 236 /* multiply normal and dbasis */ 237 for(i=0;i<numnodes;i++){ 238 dbasis_normal=0.; 239 for(k=0;k<dim;k++) dbasis_normal+=dbasis[k*numnodes+i]*normal[k]; 240 pe->values[i]+=D_scalar*mu*dbasis_normal; 241 } 190 242 } 191 243 192 244 xDelete<IssmDouble>(basis); 245 xDelete<IssmDouble>(dbasis); 193 246 xDelete<IssmDouble>(xyz_list); 247 xDelete<IssmDouble>(dlsf); 248 xDelete<IssmDouble>(normal); 194 249 return pe; 195 250 }/*}}}*/ 196 251 void LsfReinitializationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/ 197 _error_("not implemented yet"); 252 253 IssmDouble lsf; 254 int meshtype,dim,approximation,dofpernode; 255 int* doflist = NULL; 256 257 /*Get some parameters*/ 258 element->FindParam(&meshtype,MeshTypeEnum); 259 switch(meshtype){ 260 case Mesh2DhorizontalEnum: dim = 2; dofpernode = 1; break; 261 case Mesh2DverticalEnum: dim = 2; dofpernode = 1; break; 262 case Mesh3DEnum: dim = 3; dofpernode = 1; break; 263 case Mesh3DtetrasEnum: dim = 3; dofpernode = 1; break; 264 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 265 } 266 267 /*Fetch number of nodes and dof for this finite element*/ 268 int numnodes = element->GetNumberOfNodes(); 269 int numdof = numnodes*dofpernode; 270 271 /*Fetch dof list and allocate solution vector*/ 272 element->GetDofList(&doflist,approximation,GsetEnum); 273 IssmDouble* values = xNew<IssmDouble>(numdof); 274 275 /*Get inputs*/ 276 Input* lsf_input=element->GetInput(MaskIceLevelsetEnum); _assert_(lsf_input); 277 278 Gauss* gauss=element->NewGauss(); 279 for(int i=0;i<numnodes;i++){ 280 gauss->GaussNode(element->FiniteElement(),i); 281 282 lsf_input->GetInputValue(&lsf,gauss); 283 values[i*dofpernode+0]=lsf; 284 } 285 286 solution->SetValues(numdof,doflist,values,INS_VAL); 287 288 /*Free ressources:*/ 289 delete gauss; 290 xDelete<IssmDouble>(values); 291 xDelete<int>(doflist); 292 198 293 }/*}}}*/ 199 294 void LsfReinitializationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/ 200 _error_("not implemented yet"); 295 296 int meshtype; 297 element->FindParam(&meshtype,MeshTypeEnum); 298 switch(meshtype){ 299 case Mesh2DhorizontalEnum: 300 element->InputUpdateFromSolutionOneDof(solution,MaskIceLevelsetEnum); 301 break; 302 case Mesh3DEnum: 303 element->InputUpdateFromSolutionOneDofCollapsed(solution,MaskIceLevelsetEnum); 304 break; 305 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 306 } 201 307 }/*}}}*/ 202 308 void LsfReinitializationAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/ 203 _error_("not implemented yet");309 /* Do nothing for now */ 204 310 }/*}}}*/ 205 311 void LsfReinitializationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ … … 260 366 261 367 /* Other */ 262 void LsfReinitializationAnalysis:: UpdateReinitSPCs(FemModel* femmodel){/*{{{*/368 void LsfReinitializationAnalysis::SetReinitSPCs(FemModel* femmodel){/*{{{*/ 263 369 264 370 int i,k, numnodes; … … 270 376 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 271 377 for(k=0;k<element->GetNumberOfNodes();k++){ 272 node=element->GetNode(k); 378 node=element->GetNode(k); 379 if(node->IsActive()){ 273 380 node->DofInFSet(0); 381 } 274 382 } 275 383 } … … 287 395 for(k=0;k<numnodes;k++){ 288 396 node=element->GetNode(k); 289 node->ApplyConstraint(1,lsf[k]); 397 if(node->IsActive()){ 398 node->ApplyConstraint(1,lsf[k]); 399 } 290 400 } 291 401 xDelete<IssmDouble>(lsf); … … 298 408 /* Intermediaries */ 299 409 int i,k; 410 IssmDouble dmaxp,dmaxm,val; 411 Element* element; 300 412 301 413 /*Initialize vector with number of vertices*/ 302 414 int numvertices=femmodel->vertices->NumberOfVertices(); 303 Element* element;304 415 305 416 Vector<IssmDouble>* vec_dist_zerolevelset = NULL; 306 417 GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexEnum); 307 418 419 /* set distance on elements intersected by zero levelset */ 308 420 for(i=0;i<femmodel->elements->Size();i++){ 309 421 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 310 if(element->IsZeroLevelset(MaskIceLevelsetEnum)) 311 for(k=0;k<element->GetNumberOfVertices();k++) 312 vec_dist_zerolevelset->SetValue(element->vertices[k]->Sid(),NAN,INS_VAL); 313 } 314 315 for(i=0;i<femmodel->elements->Size();i++){ 316 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 317 if(element->IsZeroLevelset(MaskIceLevelsetEnum)) 422 if(element->IsZeroLevelset(MaskIceLevelsetEnum)){ 318 423 SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element); 424 } 425 } 426 vec_dist_zerolevelset->Assemble(); 427 428 /* Get maximum distance to interface along vertices */ 429 dmaxp=0.; dmaxm=0.; 430 for(i=0;i<numvertices;i++){ 431 vec_dist_zerolevelset->GetValue(&val,i); 432 if((val>0.) && (val>dmaxp)) 433 dmaxp=val; 434 else if((val<0.) && (val<dmaxm)) 435 dmaxm=val; 436 } 437 //wait until all values are computed 438 439 /* set all none intersected vertices to max/min distance */ 440 for(i=0;i<numvertices;i++){ 441 vec_dist_zerolevelset->GetValue(&val,i); 442 if(val==1.) //FIXME: improve check 443 vec_dist_zerolevelset->SetValue(i,3.*dmaxp,INS_VAL); 444 else if(val==-1.) 445 vec_dist_zerolevelset->SetValue(i,3.*dmaxm,INS_VAL); 319 446 } 320 447 … … 327 454 delete vec_dist_zerolevelset; 328 455 delete dist_zerolevelset; 456 329 457 }/*}}}*/ 330 458 void LsfReinitializationAnalysis::SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_signed_dist, Element* element){/*{{{*/ … … 334 462 335 463 /* Intermediaries */ 336 constint dim=3;464 int dim=3; 337 465 int i,d; 466 IssmDouble dist,lsf_old; 467 338 468 int numvertices=element->GetNumberOfVertices(); 339 IssmDouble s0[dim], s1[dim], v[dim];340 IssmDouble dist,lsf_old;341 469 342 470 IssmDouble* lsf = xNew<IssmDouble>(numvertices); 343 471 IssmDouble* sign_lsf = xNew<IssmDouble>(numvertices); 344 472 IssmDouble* signed_dist = xNew<IssmDouble>(numvertices); 473 IssmDouble* s0 = xNew<IssmDouble>(dim); 474 IssmDouble* s1 = xNew<IssmDouble>(dim); 475 IssmDouble* v = xNew<IssmDouble>(dim); 345 476 IssmDouble* xyz_list = NULL; 346 477 IssmDouble* xyz_list_zero = NULL; … … 355 486 356 487 element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum); 357 for( d=0;d<dim;d++){358 s0[ d]=xyz_list_zero[0+d];359 s1[ d]=xyz_list_zero[3+d];488 for(i=0;i<dim;i++){ 489 s0[i]=xyz_list_zero[0+i]; 490 s1[i]=xyz_list_zero[3+i]; 360 491 } 361 492 … … 363 494 for(i=0;i<numvertices;i++){ 364 495 for(d=0;d<dim;d++) 365 v[d]=xyz_list[ 3*i+d];496 v[d]=xyz_list[dim*i+d]; 366 497 dist=GetDistanceToStraight(&v[0],&s0[0],&s1[0]); 367 498 signed_dist[i]=sign_lsf[i]*dist; … … 371 502 for(i=0;i<numvertices;i++){ 372 503 vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid()); 373 if(xIsNan<IssmDouble>(lsf_old) || fabs(signed_dist[i])<fabs(lsf_old)) 504 /* initial lsf values are +-1. Update those fields or if distance to interface smaller.*/ 505 if(fabs(lsf_old)==1. || fabs(signed_dist[i])<fabs(lsf_old)) 374 506 vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL); 375 507 } … … 378 510 xDelete<IssmDouble>(sign_lsf); 379 511 xDelete<IssmDouble>(signed_dist); 512 xDelete<IssmDouble>(s0); 513 xDelete<IssmDouble>(s1); 514 xDelete<IssmDouble>(v); 515 380 516 }/*}}}*/ 381 517 IssmDouble LsfReinitializationAnalysis::GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1){/*{{{*/ … … 403 539 return fabs(a[0]*b[1]-a[1]*b[0])/norm_b; 404 540 }/*}}}*/ 405 541 bool LsfReinitializationAnalysis::ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol){/*{{{*/ 542 543 /*Output*/ 544 bool converged = true; 545 546 /*Intermediary*/ 547 Vector<IssmDouble>* dlsfg = NULL; 548 IssmDouble norm_dlsf,norm_lsf; 549 550 /*compute norm(du)/norm(u)*/ 551 dlsfg=lsfg_old->Duplicate(); lsfg_old->Copy(dlsfg); dlsfg->AYPX(lsfg,-1.0); 552 norm_dlsf=dlsfg->Norm(NORM_TWO); norm_lsf=lsfg_old->Norm(NORM_TWO); 553 if (xIsNan<IssmDouble>(norm_dlsf) || xIsNan<IssmDouble>(norm_lsf)) _error_("convergence criterion is NaN!"); 554 if((norm_dlsf/norm_lsf)<reltol){ 555 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" < "<<reltol*100<<" %\n"); 556 } 557 else{ 558 if(VerboseConvergence()) _printf0_("\n"<<setw(50)<<left<<" Velocity convergence: norm(du)/norm(u)"<<norm_dlsf/norm_lsf*100<<" > "<<reltol*100<<" %\n"); 559 converged=false; 560 } 561 562 /*Cleanup*/ 563 delete dlsfg; 564 565 return converged; 566 }/*}}}*/ -
issm/trunk-jpl/src/c/analyses/LsfReinitializationAnalysis.h
r17334 r17503 33 33 34 34 /* Other */ 35 void UpdateReinitSPCs(FemModel* femmodel);35 void SetReinitSPCs(FemModel* femmodel); 36 36 void SetDistanceOnIntersectedElements(FemModel* femmodel); 37 37 void SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_dist, Element* element); 38 38 IssmDouble GetDistanceToStraight(IssmDouble* q, IssmDouble* s0, IssmDouble* s1); 39 bool ReinitConvergence(Vector<IssmDouble>* lsfg,Vector<IssmDouble>* lsfg_old,IssmDouble reltol); 39 40 }; 40 41 #endif -
issm/trunk-jpl/src/c/modules/ModelProcessorx/ModelProcessorx.cpp
r17236 r17503 76 76 if(solution_enum==TransientSolutionEnum && analysis_enum==LevelsetAnalysisEnum && islevelset==false) continue; 77 77 if(solution_enum==TransientSolutionEnum && analysis_enum==ExtrapolationAnalysisEnum && islevelset==false) continue; 78 if(solution_enum==TransientSolutionEnum && analysis_enum==LsfReinitializationAnalysisEnum && islevelset==false) continue; 78 79 79 80
Note:
See TracChangeset
for help on using the changeset viewer.