Changeset 25655
- Timestamp:
- 10/08/20 00:06:51 (4 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/SealevelriseAnalysis.cpp
r25627 r25655 175 175 IssmDouble planetradius=0; 176 176 IssmDouble planetarea=0; 177 bool elastic=false; 177 bool rigid=false; 178 bool elastic=false; 178 179 179 180 int numoutputs; … … 231 232 } /*}}}*/ 232 233 /*Deal with elasticity {{{*/ 234 iomodel->FetchData(&rigid,"md.solidearth.settings.rigid"); 233 235 iomodel->FetchData(&elastic,"md.solidearth.settings.elastic"); 234 // if(elastic){ 235 /*love numbers: */ 236 iomodel->FetchData(&love_h,&nl,NULL,"md.solidearth.lovenumbers.h"); 237 iomodel->FetchData(&love_k,&nl,NULL,"md.solidearth.lovenumbers.k"); 238 iomodel->FetchData(&love_l,&nl,NULL,"md.solidearth.lovenumbers.l"); 239 iomodel->FetchData(&love_th,&nl,NULL,"md.solidearth.lovenumbers.th"); 240 iomodel->FetchData(&love_tk,&nl,NULL,"md.solidearth.lovenumbers.tk"); 241 iomodel->FetchData(&love_tl,&nl,NULL,"md.solidearth.lovenumbers.tl"); 242 parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.lovenumbers.tk2secular",TidalLoveK2SecularEnum)); 243 244 parameters->AddObject(new DoubleMatParam(LoadLoveHEnum,love_h,nl,1)); 245 parameters->AddObject(new DoubleMatParam(LoadLoveKEnum,love_k,nl,1)); 246 parameters->AddObject(new DoubleMatParam(LoadLoveLEnum,love_l,nl,1)); 247 parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,love_th,nl,1)); 248 parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,love_tk,nl,1)); 249 parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,love_tl,nl,1)); 250 251 /*compute elastic green function for a range of angles*/ 252 iomodel->FetchData(°acc,"md.solidearth.settings.degacc"); 253 M=reCast<int,IssmDouble>(180./degacc+1.); 254 255 // AD performance is sensitive to calls to ensurecontiguous. 256 // // Providing "t" will cause ensurecontiguous to be called. 257 #ifdef _HAVE_AD_ 258 G_rigid=xNew<IssmDouble>(M,"t"); 259 G_elastic=xNew<IssmDouble>(M,"t"); 260 U_elastic=xNew<IssmDouble>(M,"t"); 261 H_elastic=xNew<IssmDouble>(M,"t"); 262 #else 263 G_rigid=xNew<IssmDouble>(M); 264 G_elastic=xNew<IssmDouble>(M); 265 U_elastic=xNew<IssmDouble>(M); 266 H_elastic=xNew<IssmDouble>(M); 267 #endif 268 269 /*compute combined legendre + love number (elastic green function:*/ 270 m=DetermineLocalSize(M,IssmComm::GetComm()); 271 GetOwnershipBoundariesFromRange(&lower_row,&upper_row,m,IssmComm::GetComm()); 272 // AD performance is sensitive to calls to ensurecontiguous. 273 // // Providing "t" will cause ensurecontiguous to be called. 274 #ifdef _HAVE_AD_ 275 G_elastic_local=xNew<IssmDouble>(m,"t"); 276 G_rigid_local=xNew<IssmDouble>(m,"t"); 277 U_elastic_local=xNew<IssmDouble>(m,"t"); 278 H_elastic_local=xNew<IssmDouble>(m,"t"); 279 #else 280 G_elastic_local=xNew<IssmDouble>(m); 281 G_rigid_local=xNew<IssmDouble>(m); 282 U_elastic_local=xNew<IssmDouble>(m); 283 H_elastic_local=xNew<IssmDouble>(m); 284 #endif 285 286 for(int i=lower_row;i<upper_row;i++){ 287 IssmDouble alpha,x; 288 alpha= reCast<IssmDouble>(i)*degacc * PI / 180.0; 289 290 G_rigid_local[i-lower_row]= .5/sin(alpha/2.0); 291 G_elastic_local[i-lower_row]= (love_k[nl-1]-love_h[nl-1])*G_rigid_local[i-lower_row]; 292 U_elastic_local[i-lower_row]= (love_h[nl-1])*G_rigid_local[i-lower_row]; 293 H_elastic_local[i-lower_row]= 0; 294 IssmDouble Pn = 0.; 295 IssmDouble Pn1 = 0.; 296 IssmDouble Pn2 = 0.; 297 IssmDouble Pn_p = 0.; 298 IssmDouble Pn_p1 = 0.; 299 IssmDouble Pn_p2 = 0.; 300 301 for (int n=0;n<nl;n++) { 302 IssmDouble deltalove_G; 303 IssmDouble deltalove_U; 304 305 deltalove_G = (love_k[n]-love_k[nl-1]-love_h[n]+love_h[nl-1]); 306 deltalove_U = (love_h[n]-love_h[nl-1]); 307 308 /*compute legendre polynomials: P_n(cos\theta) & d P_n(cos\theta)/ d\theta: */ 309 if(n==0){ 310 Pn=1; 311 Pn_p=0; 236 if (rigid) { 237 if (elastic) { 238 /*love numbers: */ 239 iomodel->FetchData(&love_h,&nl,NULL,"md.solidearth.lovenumbers.h"); 240 iomodel->FetchData(&love_k,&nl,NULL,"md.solidearth.lovenumbers.k"); 241 iomodel->FetchData(&love_l,&nl,NULL,"md.solidearth.lovenumbers.l"); 242 iomodel->FetchData(&love_th,&nl,NULL,"md.solidearth.lovenumbers.th"); 243 iomodel->FetchData(&love_tk,&nl,NULL,"md.solidearth.lovenumbers.tk"); 244 iomodel->FetchData(&love_tl,&nl,NULL,"md.solidearth.lovenumbers.tl"); 245 parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.lovenumbers.tk2secular",TidalLoveK2SecularEnum)); 246 247 parameters->AddObject(new DoubleMatParam(LoadLoveHEnum,love_h,nl,1)); 248 parameters->AddObject(new DoubleMatParam(LoadLoveKEnum,love_k,nl,1)); 249 parameters->AddObject(new DoubleMatParam(LoadLoveLEnum,love_l,nl,1)); 250 parameters->AddObject(new DoubleMatParam(TidalLoveHEnum,love_th,nl,1)); 251 parameters->AddObject(new DoubleMatParam(TidalLoveKEnum,love_tk,nl,1)); 252 parameters->AddObject(new DoubleMatParam(TidalLoveLEnum,love_tl,nl,1)); 253 254 /*compute elastic green function for a range of angles*/ 255 iomodel->FetchData(°acc,"md.solidearth.settings.degacc"); 256 M=reCast<int,IssmDouble>(180./degacc+1.); 257 258 // AD performance is sensitive to calls to ensurecontiguous. 259 // // Providing "t" will cause ensurecontiguous to be called. 260 #ifdef _HAVE_AD_ 261 G_rigid=xNew<IssmDouble>(M,"t"); 262 G_elastic=xNew<IssmDouble>(M,"t"); 263 U_elastic=xNew<IssmDouble>(M,"t"); 264 H_elastic=xNew<IssmDouble>(M,"t"); 265 #else 266 G_rigid=xNew<IssmDouble>(M); 267 G_elastic=xNew<IssmDouble>(M); 268 U_elastic=xNew<IssmDouble>(M); 269 H_elastic=xNew<IssmDouble>(M); 270 #endif 271 272 /*compute combined legendre + love number (elastic green function:*/ 273 m=DetermineLocalSize(M,IssmComm::GetComm()); 274 GetOwnershipBoundariesFromRange(&lower_row,&upper_row,m,IssmComm::GetComm()); 275 // AD performance is sensitive to calls to ensurecontiguous. 276 // // Providing "t" will cause ensurecontiguous to be called. 277 #ifdef _HAVE_AD_ 278 G_elastic_local=xNew<IssmDouble>(m,"t"); 279 G_rigid_local=xNew<IssmDouble>(m,"t"); 280 U_elastic_local=xNew<IssmDouble>(m,"t"); 281 H_elastic_local=xNew<IssmDouble>(m,"t"); 282 #else 283 G_elastic_local=xNew<IssmDouble>(m); 284 G_rigid_local=xNew<IssmDouble>(m); 285 U_elastic_local=xNew<IssmDouble>(m); 286 H_elastic_local=xNew<IssmDouble>(m); 287 #endif 288 289 for(int i=lower_row;i<upper_row;i++){ 290 IssmDouble alpha,x; 291 alpha= reCast<IssmDouble>(i)*degacc * PI / 180.0; 292 293 G_rigid_local[i-lower_row]= .5/sin(alpha/2.0); 294 G_elastic_local[i-lower_row]= (love_k[nl-1]-love_h[nl-1])*G_rigid_local[i-lower_row]; 295 U_elastic_local[i-lower_row]= (love_h[nl-1])*G_rigid_local[i-lower_row]; 296 H_elastic_local[i-lower_row]= 0; 297 IssmDouble Pn = 0.; 298 IssmDouble Pn1 = 0.; 299 IssmDouble Pn2 = 0.; 300 IssmDouble Pn_p = 0.; 301 IssmDouble Pn_p1 = 0.; 302 IssmDouble Pn_p2 = 0.; 303 304 for (int n=0;n<nl;n++) { 305 IssmDouble deltalove_G; 306 IssmDouble deltalove_U; 307 308 deltalove_G = (love_k[n]-love_k[nl-1]-love_h[n]+love_h[nl-1]); 309 deltalove_U = (love_h[n]-love_h[nl-1]); 310 311 /*compute legendre polynomials: P_n(cos\theta) & d P_n(cos\theta)/ d\theta: */ 312 if(n==0){ 313 Pn=1; 314 Pn_p=0; 315 } 316 else if(n==1){ 317 Pn = cos(alpha); 318 Pn_p = 1; 319 } 320 else{ 321 Pn = ( (2*n-1)*cos(alpha)*Pn1 - (n-1)*Pn2 ) /n; 322 Pn_p = ( (2*n-1)*(Pn1+cos(alpha)*Pn_p1) - (n-1)*Pn_p2 ) /n; 323 } 324 Pn2=Pn1; Pn1=Pn; 325 Pn_p2=Pn_p1; Pn_p1=Pn_p; 326 327 G_elastic_local[i-lower_row] += deltalove_G*Pn; // gravitational potential 328 U_elastic_local[i-lower_row] += deltalove_U*Pn; // vertical (up) displacement 329 H_elastic_local[i-lower_row] += sin(alpha)*love_l[n]*Pn_p; // horizontal displacements 312 330 } 313 else if(n==1){314 Pn = cos(alpha);315 Pn_p = 1;316 }317 else{318 Pn = ( (2*n-1)*cos(alpha)*Pn1 - (n-1)*Pn2 ) /n;319 Pn_p = ( (2*n-1)*(Pn1+cos(alpha)*Pn_p1) - (n-1)*Pn_p2 ) /n;320 }321 Pn2=Pn1; Pn1=Pn;322 Pn_p2=Pn_p1; Pn_p1=Pn_p;323 324 G_elastic_local[i-lower_row] += deltalove_G*Pn; // gravitational potential325 U_elastic_local[i-lower_row] += deltalove_U*Pn; // vertical (up) displacement326 H_elastic_local[i-lower_row] += sin(alpha)*love_l[n]*Pn_p; // horizontal displacements327 331 } 328 } 329 330 /*merge G_elastic_local into G_elastic; U_elastic_local into U_elastic; H_elastic_local to H_elastic:{{{*/ 331 int* recvcounts=xNew<int>(IssmComm::GetSize()); 332 int* displs=xNew<int>(IssmComm::GetSize()); 333 334 //recvcounts: 335 ISSM_MPI_Allgather(&m,1,ISSM_MPI_INT,recvcounts,1,ISSM_MPI_INT,IssmComm::GetComm()); 336 337 /*displs: */ 338 ISSM_MPI_Allgather(&lower_row,1,ISSM_MPI_INT,displs,1,ISSM_MPI_INT,IssmComm::GetComm()); 339 340 /*All gather:*/ 341 ISSM_MPI_Allgatherv(G_rigid_local, m, ISSM_MPI_DOUBLE, G_rigid, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 342 ISSM_MPI_Allgatherv(G_elastic_local, m, ISSM_MPI_DOUBLE, G_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 343 ISSM_MPI_Allgatherv(U_elastic_local, m, ISSM_MPI_DOUBLE, U_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 344 ISSM_MPI_Allgatherv(H_elastic_local, m, ISSM_MPI_DOUBLE, H_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 345 346 /*free resources: */ 347 xDelete<int>(recvcounts); 348 xDelete<int>(displs); 349 350 /*}}}*/ 351 352 /*Avoid singularity at 0: */ 353 G_rigid[0]=G_rigid[1]; 354 parameters->AddObject(new DoubleVecParam(SealevelriseGRigidEnum,G_rigid,M)); 355 G_elastic[0]=G_elastic[1]; 356 parameters->AddObject(new DoubleVecParam(SealevelriseGElasticEnum,G_elastic,M)); 357 U_elastic[0]=U_elastic[1]; 358 parameters->AddObject(new DoubleVecParam(SealevelriseUElasticEnum,U_elastic,M)); 359 H_elastic[0]=H_elastic[1]; 360 parameters->AddObject(new DoubleVecParam(SealevelriseHElasticEnum,H_elastic,M)); 361 362 /*free resources: */ 363 xDelete<IssmDouble>(love_h); 364 xDelete<IssmDouble>(love_k); 365 xDelete<IssmDouble>(love_l); 366 xDelete<IssmDouble>(love_th); 367 xDelete<IssmDouble>(love_tk); 368 xDelete<IssmDouble>(love_tl); 369 xDelete<IssmDouble>(G_rigid); 370 xDelete<IssmDouble>(G_rigid_local); 371 xDelete<IssmDouble>(G_elastic); 372 xDelete<IssmDouble>(G_elastic_local); 373 xDelete<IssmDouble>(U_elastic); 374 xDelete<IssmDouble>(U_elastic_local); 375 xDelete<IssmDouble>(H_elastic); 376 xDelete<IssmDouble>(H_elastic_local); 377 // } 332 333 /*merge G_elastic_local into G_elastic; U_elastic_local into U_elastic; H_elastic_local to H_elastic:{{{*/ 334 int* recvcounts=xNew<int>(IssmComm::GetSize()); 335 int* displs=xNew<int>(IssmComm::GetSize()); 336 337 //recvcounts: 338 ISSM_MPI_Allgather(&m,1,ISSM_MPI_INT,recvcounts,1,ISSM_MPI_INT,IssmComm::GetComm()); 339 340 /*displs: */ 341 ISSM_MPI_Allgather(&lower_row,1,ISSM_MPI_INT,displs,1,ISSM_MPI_INT,IssmComm::GetComm()); 342 343 /*All gather:*/ 344 ISSM_MPI_Allgatherv(G_rigid_local, m, ISSM_MPI_DOUBLE, G_rigid, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 345 ISSM_MPI_Allgatherv(G_elastic_local, m, ISSM_MPI_DOUBLE, G_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 346 ISSM_MPI_Allgatherv(U_elastic_local, m, ISSM_MPI_DOUBLE, U_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 347 ISSM_MPI_Allgatherv(H_elastic_local, m, ISSM_MPI_DOUBLE, H_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 348 349 /*free resources: */ 350 xDelete<int>(recvcounts); 351 xDelete<int>(displs); 352 353 /*}}}*/ 354 355 /*Avoid singularity at 0: */ 356 G_rigid[0]=G_rigid[1]; 357 parameters->AddObject(new DoubleVecParam(SealevelriseGRigidEnum,G_rigid,M)); 358 G_elastic[0]=G_elastic[1]; 359 parameters->AddObject(new DoubleVecParam(SealevelriseGElasticEnum,G_elastic,M)); 360 U_elastic[0]=U_elastic[1]; 361 parameters->AddObject(new DoubleVecParam(SealevelriseUElasticEnum,U_elastic,M)); 362 H_elastic[0]=H_elastic[1]; 363 parameters->AddObject(new DoubleVecParam(SealevelriseHElasticEnum,H_elastic,M)); 364 365 /*free resources: */ 366 xDelete<IssmDouble>(love_h); 367 xDelete<IssmDouble>(love_k); 368 xDelete<IssmDouble>(love_l); 369 xDelete<IssmDouble>(love_th); 370 xDelete<IssmDouble>(love_tk); 371 xDelete<IssmDouble>(love_tl); 372 xDelete<IssmDouble>(G_rigid); 373 xDelete<IssmDouble>(G_rigid_local); 374 xDelete<IssmDouble>(G_elastic); 375 xDelete<IssmDouble>(G_elastic_local); 376 xDelete<IssmDouble>(U_elastic); 377 xDelete<IssmDouble>(U_elastic_local); 378 xDelete<IssmDouble>(H_elastic); 379 xDelete<IssmDouble>(H_elastic_local); 380 } else { /*elastic==false*/ 381 /*compute elastic green function for a range of angles*/ 382 iomodel->FetchData(°acc,"md.solidearth.settings.degacc"); 383 M=reCast<int,IssmDouble>(180./degacc+1.); 384 385 // AD performance is sensitive to calls to ensurecontiguous. 386 // // Providing "t" will cause ensurecontiguous to be called. 387 #ifdef _HAVE_AD_ 388 G_rigid=xNew<IssmDouble>(M,"t"); 389 #else 390 G_rigid=xNew<IssmDouble>(M); 391 #endif 392 393 /*compute combined legendre + love number (elastic green function:*/ 394 m=DetermineLocalSize(M,IssmComm::GetComm()); 395 GetOwnershipBoundariesFromRange(&lower_row,&upper_row,m,IssmComm::GetComm()); 396 // AD performance is sensitive to calls to ensurecontiguous. 397 // // Providing "t" will cause ensurecontiguous to be called. 398 #ifdef _HAVE_AD_ 399 G_rigid_local=xNew<IssmDouble>(m,"t"); 400 #else 401 G_rigid_local=xNew<IssmDouble>(m); 402 #endif 403 404 for(int i=lower_row;i<upper_row;i++){ 405 IssmDouble alpha,x; 406 alpha=reCast<IssmDouble>(i)*degacc*PI/180.0; 407 G_rigid_local[i-lower_row]=.5/sin(alpha/2.0); 408 } 409 410 /*merge G_elastic_local into G_elastic; U_elastic_local into U_elastic; H_elastic_local to H_elastic:{{{*/ 411 int* recvcounts=xNew<int>(IssmComm::GetSize()); 412 int* displs=xNew<int>(IssmComm::GetSize()); 413 414 //recvcounts: 415 ISSM_MPI_Allgather(&m,1,ISSM_MPI_INT,recvcounts,1,ISSM_MPI_INT,IssmComm::GetComm()); 416 417 /*displs: */ 418 ISSM_MPI_Allgather(&lower_row,1,ISSM_MPI_INT,displs,1,ISSM_MPI_INT,IssmComm::GetComm()); 419 420 /*All gather:*/ 421 ISSM_MPI_Allgatherv(G_rigid_local, m, ISSM_MPI_DOUBLE, G_rigid, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); 422 423 /*free resources: */ 424 xDelete<int>(recvcounts); 425 xDelete<int>(displs); 426 427 /*}}}*/ 428 429 /*Avoid singularity at 0: */ 430 G_rigid[0]=G_rigid[1]; 431 parameters->AddObject(new DoubleVecParam(SealevelriseGRigidEnum,G_rigid,M)); 432 433 /*free resources: */ 434 xDelete<IssmDouble>(G_rigid); 435 xDelete<IssmDouble>(G_rigid_local); 436 } 437 } else { /*rigid==false*/ 438 if (elastic) { 439 _error_("Must set md.solidearth.settings.rigid=1 when setting md.solidearth.settings.elastic=1"); 440 } 441 } 378 442 379 /*Indicate we have not yet r an the Geometry Core module: */443 /*Indicate we have not yet run the Geometry Core module: */ 380 444 parameters->AddObject(new BoolParam(SealevelriseGeometryDoneEnum,false)); 381 445 382 /*}}}*/383 446 /*Transitions:{{{ */ 384 447 iomodel->FetchData(&transitions,&transitions_M,&transitions_N,&ntransitions,"md.solidearth.transitions"); -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r25627 r25655 5475 5475 5476 5476 /*recover precomputed green function kernels:*/ 5477 DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGRigidEnum)); _assert_(parameter); 5478 parameter->GetParameterValueByPointer((IssmDouble**)&G_rigid_precomputed,&M); 5479 5480 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGElasticEnum)); _assert_(parameter); 5481 parameter->GetParameterValueByPointer((IssmDouble**)&G_elastic_precomputed,&M); 5482 5483 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(parameter); 5484 parameter->GetParameterValueByPointer((IssmDouble**)&U_elastic_precomputed,&M); 5485 5486 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(parameter); 5487 parameter->GetParameterValueByPointer((IssmDouble**)&H_elastic_precomputed,&M); 5488 5489 /*allocate indices:*/ 5490 indices=xNew<IssmDouble>(gsize); 5491 G=xNewZeroInit<IssmDouble>(gsize); 5492 GU=xNewZeroInit<IssmDouble>(gsize); 5493 if(horiz){ 5494 GN=xNewZeroInit<IssmDouble>(gsize); 5495 GE=xNewZeroInit<IssmDouble>(gsize); 5496 } 5497 5498 5499 /* Where is the centroid of this element:*/ 5500 5501 /*retrieve coordinates: */ 5502 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 5503 5504 /*figure out gravity center of our element (Cartesian): */ 5505 x_element=(xyz_list[0][0]+xyz_list[1][0]+xyz_list[2][0])/3.0; 5506 y_element=(xyz_list[0][1]+xyz_list[1][1]+xyz_list[2][1])/3.0; 5507 z_element=(xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2])/3.0; 5508 5509 /*compute gravity center in lat,long: */ 5510 late= asin(z_element/planetradius); 5511 longe = atan2(y_element,x_element); 5512 5513 constant=3/rho_earth*area/planetarea; 5514 5515 for(int i=0;i<gsize;i++){ 5516 IssmDouble alpha; 5517 IssmDouble delPhi,delLambda; 5518 5519 /*Compute alpha angle between centroid and current vertex and index into precomputed tables: */ 5520 lati=latitude[i]/180*PI; longi=longitude[i]/180*PI; 5521 delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>PI)delLambda=2*PI-delLambda; 5522 alpha=2.*asin(sqrt(pow(sin(delPhi/2),2)+cos(lati)*cos(late)*pow(sin(delLambda/2),2))); 5523 indices[i]=alpha/PI*reCast<IssmDouble,int>(M-1); 5524 index=reCast<int,IssmDouble>(indices[i]); 5525 5526 /*Rigid earth gravitational perturbation: */ 5527 if(computerigid){ 5528 G[i]+=G_rigid_precomputed[index]; 5529 } 5477 if(computerigid){ 5478 DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGRigidEnum)); _assert_(parameter); 5479 parameter->GetParameterValueByPointer((IssmDouble**)&G_rigid_precomputed,&M); 5480 5481 /*allocate indices:*/ 5482 indices=xNew<IssmDouble>(gsize); 5483 G=xNewZeroInit<IssmDouble>(gsize); 5484 5530 5485 if(computeelastic){ 5531 G[i]+=G_elastic_precomputed[index]; 5532 } 5533 G[i]=G[i]*constant; 5534 5535 /*Elastic components:*/ 5536 GU[i] = constant * U_elastic_precomputed[index]; 5537 if(horiz){ 5538 /*Compute azimuths, both north and east components: */ 5539 x = xx[i]; y = yy[i]; z = zz[i]; 5540 if(latitude[i]==90){ 5541 x=1e-12; y=1e-12; 5542 } 5543 if(latitude[i]==-90){ 5544 x=1e-12; y=1e-12; 5545 } 5546 dx = x_element-x; dy = y_element-y; dz = z_element-z; 5547 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5548 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5549 5550 GN[i] = constant*H_elastic_precomputed[index]*N_azim; 5551 GE[i] = constant*H_elastic_precomputed[index]*E_azim; 5552 } 5553 } 5554 5555 /*Add in inputs:*/ 5556 this->inputs->SetArrayInput(SealevelriseIndicesEnum,this->lid,indices,gsize); 5557 this->inputs->SetArrayInput(SealevelriseGEnum,this->lid,G,gsize); 5558 this->inputs->SetArrayInput(SealevelriseGUEnum,this->lid,GU,gsize); 5559 if(horiz){ 5560 this->inputs->SetArrayInput(SealevelriseGNEnum,this->lid,GN,gsize); 5561 this->inputs->SetArrayInput(SealevelriseGEEnum,this->lid,GE,gsize); 5562 } 5563 5564 /* NOTE: May need to remove these two lines (from merge) */ 5565 this->inputs->SetDoubleInput(AreaEnum,this->lid,area); 5566 this->AddInput(SealevelAreaEnum,&area,P0Enum); 5567 5568 /*Free allocations:*/ 5569 #ifdef _HAVE_RESTRICT_ 5570 delete indices; 5571 delete G; 5572 delete GU; 5573 if(horiz){ 5574 delete GN; 5575 delete GE; 5576 } 5577 #else 5578 xDelete(indices); 5579 xDelete(G); 5580 xDelete(GU); 5581 if(horiz){ 5582 xDelete(GN); 5583 xDelete(GE); 5584 } 5585 #endif 5486 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGElasticEnum)); _assert_(parameter); 5487 parameter->GetParameterValueByPointer((IssmDouble**)&G_elastic_precomputed,&M); 5488 5489 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(parameter); 5490 parameter->GetParameterValueByPointer((IssmDouble**)&U_elastic_precomputed,&M); 5491 5492 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(parameter); 5493 parameter->GetParameterValueByPointer((IssmDouble**)&H_elastic_precomputed,&M); 5494 5495 /*allocate indices:*/ 5496 GU=xNewZeroInit<IssmDouble>(gsize); 5497 if(horiz){ 5498 GN=xNewZeroInit<IssmDouble>(gsize); 5499 GE=xNewZeroInit<IssmDouble>(gsize); 5500 } 5501 5502 /* Where is the centroid of this element:*/ 5503 5504 /*retrieve coordinates: */ 5505 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 5506 5507 /*figure out gravity center of our element (Cartesian): */ 5508 x_element=(xyz_list[0][0]+xyz_list[1][0]+xyz_list[2][0])/3.0; 5509 y_element=(xyz_list[0][1]+xyz_list[1][1]+xyz_list[2][1])/3.0; 5510 z_element=(xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2])/3.0; 5511 5512 /*compute gravity center in lat,long: */ 5513 late= asin(z_element/planetradius); 5514 longe = atan2(y_element,x_element); 5515 5516 constant=3/rho_earth*area/planetarea; 5517 5518 for(int i=0;i<gsize;i++){ 5519 IssmDouble alpha; 5520 IssmDouble delPhi,delLambda; 5521 5522 /*Compute alpha angle between centroid and current vertex and index into precomputed tables: */ 5523 lati=latitude[i]/180*PI; longi=longitude[i]/180*PI; 5524 delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>PI)delLambda=2*PI-delLambda; 5525 alpha=2.*asin(sqrt(pow(sin(delPhi/2),2)+cos(lati)*cos(late)*pow(sin(delLambda/2),2))); 5526 indices[i]=alpha/PI*reCast<IssmDouble,int>(M-1); 5527 index=reCast<int,IssmDouble>(indices[i]); 5528 5529 /*Rigid earth gravitational perturbation: */ 5530 if(computerigid){ 5531 G[i]+=G_rigid_precomputed[index]; 5532 } 5533 if(computeelastic){ 5534 G[i]+=G_elastic_precomputed[index]; 5535 } 5536 G[i]=G[i]*constant; 5537 5538 /*Elastic components:*/ 5539 GU[i] = constant * U_elastic_precomputed[index]; 5540 if(horiz){ 5541 /*Compute azimuths, both north and east components: */ 5542 x = xx[i]; y = yy[i]; z = zz[i]; 5543 if(latitude[i]==90){ 5544 x=1e-12; y=1e-12; 5545 } 5546 if(latitude[i]==-90){ 5547 x=1e-12; y=1e-12; 5548 } 5549 dx = x_element-x; dy = y_element-y; dz = z_element-z; 5550 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5551 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5552 5553 GN[i] = constant*H_elastic_precomputed[index]*N_azim; 5554 GE[i] = constant*H_elastic_precomputed[index]*E_azim; 5555 } 5556 } 5557 5558 /*Add in inputs:*/ 5559 this->inputs->SetArrayInput(SealevelriseIndicesEnum,this->lid,indices,gsize); 5560 this->inputs->SetArrayInput(SealevelriseGEnum,this->lid,G,gsize); 5561 this->inputs->SetArrayInput(SealevelriseGUEnum,this->lid,GU,gsize); 5562 if(horiz){ 5563 this->inputs->SetArrayInput(SealevelriseGNEnum,this->lid,GN,gsize); 5564 this->inputs->SetArrayInput(SealevelriseGEEnum,this->lid,GE,gsize); 5565 } 5566 this->inputs->SetDoubleInput(AreaEnum,this->lid,area); 5567 this->AddInput(SealevelAreaEnum,&area,P0Enum); 5568 5569 /*Free allocations:*/ 5570 #ifdef _HAVE_RESTRICT_ 5571 delete GU; 5572 if(horiz){ 5573 delete GN; 5574 delete GE; 5575 } 5576 #else 5577 xDelete(GU); 5578 if(horiz){ 5579 xDelete(GN); 5580 xDelete(GE); 5581 } 5582 #endif 5583 } else { /*computeelastic==false*/ 5584 /* Where is the centroid of this element:*/ 5585 5586 /*retrieve coordinates: */ 5587 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 5588 5589 /*figure out gravity center of our element (Cartesian): */ 5590 x_element=(xyz_list[0][0]+xyz_list[1][0]+xyz_list[2][0])/3.0; 5591 y_element=(xyz_list[0][1]+xyz_list[1][1]+xyz_list[2][1])/3.0; 5592 z_element=(xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2])/3.0; 5593 5594 /*compute gravity center in lat,long: */ 5595 late= asin(z_element/planetradius); 5596 longe = atan2(y_element,x_element); 5597 5598 constant=3/rho_earth*area/planetarea; 5599 for(int i=0;i<gsize;i++){ 5600 IssmDouble alpha; 5601 IssmDouble delPhi,delLambda; 5602 5603 /*Compute alpha angle between centroid and current vertex and index into precomputed tables: */ 5604 lati=latitude[i]/180*PI; longi=longitude[i]/180*PI; 5605 delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>PI)delLambda=2*PI-delLambda; 5606 alpha=2.*asin(sqrt(pow(sin(delPhi/2),2)+cos(lati)*cos(late)*pow(sin(delLambda/2),2))); 5607 indices[i]=alpha/PI*reCast<IssmDouble,int>(M-1); 5608 index=reCast<int,IssmDouble>(indices[i]); 5609 5610 /*Rigid earth gravitational perturbation: */ 5611 G[i]+=G_rigid_precomputed[index]; 5612 G[i]=G[i]*constant; 5613 } 5614 5615 /*Add in inputs:*/ 5616 this->inputs->SetArrayInput(SealevelriseIndicesEnum,this->lid,indices,gsize); 5617 this->inputs->SetArrayInput(SealevelriseGEnum,this->lid,G,gsize); 5618 this->inputs->SetDoubleInput(AreaEnum,this->lid,area); 5619 this->AddInput(SealevelAreaEnum,&area,P0Enum); 5620 5621 /*Free allocations:*/ 5622 #ifdef _HAVE_RESTRICT_ 5623 delete indices; 5624 delete G; 5625 #else 5626 xDelete(indices); 5627 xDelete(G); 5628 #endif 5629 } 5630 } else { /*computerigid==false*/ 5631 // do nothing 5632 } 5586 5633 5587 5634 return; … … 5646 5693 5647 5694 /*retrieve precomputed G:*/ 5648 5649 /* NOTE: May need to remove condition here (from merge) */5650 5695 if(computeelastic)this->inputs->GetArrayPtr(SealevelriseGEnum,this->lid,&G,&gsize); 5651 5696 … … 5752 5797 5753 5798 /*retrieve precomputed G:*/ 5754 5755 /* NOTE: May need to remove condition here (from merge) */5756 5799 if(computeelastic)this->inputs->GetArrayPtr(SealevelriseGEnum,this->lid,&G,&gsize); 5757 5800
Note:
See TracChangeset
for help on using the changeset viewer.