Changeset 23066 for issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
- Timestamp:
- 08/07/18 10:22:46 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r23059 r23066 106 106 } 107 107 else tria->nodes = NULL; 108 108 109 109 tria->vertices = (Vertex**)this->hvertices->deliverp(); 110 110 tria->material = (Material*)this->hmaterial->delivers(); … … 115 115 /*}}}*/ 116 116 void Tria::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 117 117 118 118 MARSHALLING_ENUM(TriaEnum); 119 119 120 120 /*Call parent classes: */ 121 121 ElementHook::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); … … 135 135 /*Call inputs method*/ 136 136 _assert_(this->inputs); 137 137 138 138 int domaintype; 139 139 parameters->FindParam(&domaintype,DomainTypeEnum); … … 185 185 186 186 int tria_vertex_ids[3]; 187 187 188 188 for(int k=0;k<3;k++){ 189 189 tria_vertex_ids[k]=reCast<int>(iomodel->elements[3*this->Sid()+k]); //ids for vertices are in the elements array from Matlab … … 328 328 /*}}}*/ 329 329 void Tria::CalvingCrevasseDepth(){/*{{{*/ 330 330 331 331 IssmDouble xyz_list[NUMVERTICES][3]; 332 332 IssmDouble calvingrate[NUMVERTICES]; … … 340 340 /* Get node coordinates and dof list: */ 341 341 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 342 342 343 343 /*Get the critical fraction of thickness surface and basal crevasses penetrate for calving onset*/ 344 344 this->parameters->FindParam(&critical_fraction,CalvingCrevasseDepthEnum); 345 345 346 346 IssmDouble rho_ice = this->GetMaterialParameter(MaterialsRhoIceEnum); 347 347 IssmDouble rho_seawater = this->GetMaterialParameter(MaterialsRhoSeawaterEnum); … … 361 361 Input* s_xy_input = inputs->GetInput(DeviatoricStressxyEnum); _assert_(s_xy_input); 362 362 Input* s_yy_input = inputs->GetInput(DeviatoricStressyyEnum); _assert_(s_yy_input); 363 363 364 364 /*Loop over all elements of this partition*/ 365 365 GaussTria* gauss=new GaussTria(); 366 366 for (int iv=0;iv<NUMVERTICES;iv++){ 367 367 gauss->GaussVertex(iv); 368 368 369 369 H_input->GetInputValue(&thickness,gauss); 370 370 bed_input->GetInputValue(&bed,gauss); … … 378 378 s_xy_input->GetInputValue(&s_xy,gauss); 379 379 s_yy_input->GetInputValue(&s_yy,gauss); 380 380 381 381 vel=sqrt(vx*vx+vy*vy)+1.e-14; 382 382 … … 384 384 s2=(s_xx+s_yy)/2.-sqrt(pow((s_xx-s_yy)/2.,2)+pow(s_xy,2)); 385 385 if(fabs(s2)>fabs(s1)){stmp=s2; s2=s1; s1=stmp;} 386 386 387 387 Ho = thickness - (rho_seawater/rho_ice) * (-bed); 388 388 if(Ho<0.) Ho=0.; … … 399 399 // water_height = surface_crevasse[iv]; 400 400 //} 401 401 402 402 /*basal crevasse*/ 403 403 //basal_crevasse[iv] = (rho_ice/(rho_seawater-rho_ice)) * (rheology_B * strainparallel * pow(straineffective,((1/rheology_n)-1)) / (rho_ice*constant_g) - Ho); … … 405 405 if (basal_crevasse[iv]<0.) basal_crevasse[iv]=0.; 406 406 if (bed>0.) basal_crevasse[iv] = 0.; 407 407 408 408 H_surf = surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height - critical_fraction*float_depth; 409 409 H_surfbasal = (surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height + basal_crevasse[iv])-(critical_fraction*thickness); 410 410 411 411 crevasse_depth[iv] = max(H_surf,H_surfbasal); 412 412 } 413 413 414 414 this->inputs->AddInput(new TriaInput(SurfaceCrevasseEnum,&surface_crevasse[0],P1Enum)); 415 415 this->inputs->AddInput(new TriaInput(BasalCrevasseEnum,&basal_crevasse[0],P1Enum)); … … 461 461 else 462 462 calvingrate[iv]=0.; 463 463 464 464 calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14); 465 465 calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14); … … 562 562 IssmDouble vorticity_xy[NUMVERTICES]; 563 563 GaussTria* gauss=NULL; 564 564 565 565 /* Get node coordinates and dof list: */ 566 566 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); … … 569 569 Input* vx_input=this->GetInput(EsaXmotionEnum); _assert_(vx_input); 570 570 Input* vy_input=this->GetInput(EsaYmotionEnum); _assert_(vy_input); 571 571 572 572 /* Start looping on the number of vertices: */ 573 573 gauss=new GaussTria(); … … 773 773 } 774 774 775 776 775 }/*}}}*/ 777 776 void Tria::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/ … … 1400 1399 /*}}}*/ 1401 1400 void Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 1402 1401 1403 1402 /* Intermediaries */ 1404 1403 int i, dir,nrfrontnodes; … … 1489 1488 }/*}}}*/ 1490 1489 void Tria::GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/ 1491 1490 1492 1491 /* GetLevelsetIntersection computes: 1493 1492 * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion, … … 1565 1564 /*}}}*/ 1566 1565 void Tria::GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* gl){/*{{{*/ 1567 1566 1568 1567 /*Computeportion of the element that has a positive levelset*/ 1569 1568 … … 1679 1678 1680 1679 parameters->FindParam(&M,NULL,ControlInputSizeMEnum); 1681 1680 1682 1681 /*Cast to Controlinput*/ 1683 1682 if(input->ObjectEnum()!=ControlInputEnum) _error_("input " << EnumToStringx(control_enum) << " is not a ControlInput"); 1684 1683 ControlInput* controlinput = xDynamicCast<ControlInput*>(input); 1685 1684 1686 1685 if(strcmp(data,"value")==0){ 1687 1686 input = controlinput->values; … … 1700 1699 } 1701 1700 /*Check what input we are dealing with*/ 1702 1701 1703 1702 switch(input->ObjectEnum()){ 1704 1703 case TriaInputEnum: … … 1717 1716 break; 1718 1717 } 1719 1718 1720 1719 case TransientInputEnum: 1721 1720 { … … 1982 1981 base_input->GetInputAverage(&bed); 1983 1982 bed_input->GetInputAverage(&bathymetry); 1984 1983 1985 1984 /*Return: */ 1986 1985 return base*(surface-bed+min(rho_water/rho_ice*bathymetry,0.)); … … 2026 2025 if(control_analysis && ad_analysis) iomodel->FindConstant(&num_control_type,"md.autodiff.num_independent_objects"); 2027 2026 if(control_analysis && ad_analysis) iomodel->FindConstant(&num_responses,"md.autodiff.num_dependent_objects"); 2028 2029 2030 2027 2031 2028 /*Recover vertices ids needed to initialize inputs*/ … … 2394 2391 IssmDouble Tria::Masscon(IssmDouble* levelset){ /*{{{*/ 2395 2392 2396 2397 2393 /*intermediary: */ 2398 2394 IssmDouble* values=NULL; … … 2407 2403 IssmDouble fraction1,fraction2; 2408 2404 bool mainlynegative=true; 2409 2405 2410 2406 /*Output:*/ 2411 2407 volume=0; … … 2416 2412 /*Retrieve inputs required:*/ 2417 2413 thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input); 2418 2414 2419 2415 /*Retrieve material parameters: */ 2420 2416 rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum); … … 2425 2421 values[i]=levelset[this->vertices[i]->Sid()]; 2426 2422 } 2427 2423 2428 2424 /*Ok, use the level set values to figure out where we put our gaussian points:*/ 2429 2425 this->GetLevelsetPositivePart(&point1,&fraction1,&fraction2,&mainlynegative,values); … … 2877 2873 dist_cf_input->GetInputValue(&dist_cf,gauss); 2878 2874 delete gauss; 2879 2875 2880 2876 /*Ensure values are positive for floating ice*/ 2881 2877 dist_gl = fabs(dist_gl); … … 3197 3193 } 3198 3194 3199 3200 3195 } 3201 3196 /*}}}*/ … … 3278 3273 int idlist[NUMVERTICES],control_init; 3279 3274 3280 3281 3275 /*Get Domain type*/ 3282 3276 int domaintype; … … 3298 3292 /*Get out if this is not an element input*/ 3299 3293 if(!IsInputEnum(control_enum)) return; 3300 3294 3301 3295 Input* input = (Input*)this->inputs->GetInput(control_enum); _assert_(input); 3302 3296 if(input->ObjectEnum()!=ControlInputEnum){ … … 3330 3324 IssmDouble values[NUMVERTICES]; 3331 3325 int vertexpidlist[NUMVERTICES],control_init; 3332 3333 3326 3334 3327 /*Get Domain type*/ … … 4167 4160 IssmDouble* H_elastic_precomputed = NULL; 4168 4161 int M, hemi; 4169 4162 4170 4163 /*computation of Green functions:*/ 4171 4164 IssmDouble* U_elastic= NULL; … … 4174 4167 IssmDouble* X_elastic= NULL; 4175 4168 IssmDouble* Y_elastic= NULL; 4176 4169 4177 4170 /*optimization:*/ 4178 4171 bool store_green_functions=false; … … 4182 4175 if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!"); 4183 4176 deltathickness_input->GetInputAverage(&I); 4184 4177 4185 4178 /*early return if we are not on the (ice) loading point: */ 4186 4179 if(I==0) return; … … 4195 4188 /*which hemisphere? for north-south, east-west components*/ 4196 4189 this->parameters->FindParam(&hemi,EsaHemisphereEnum); 4197 4190 4198 4191 /*compute area of element:*/ 4199 4192 area=GetArea(); … … 4254 4247 Y_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*Y_elastic[i]; 4255 4248 X_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*X_elastic[i]; 4256 4249 4257 4250 /*North-south, East-west components */ 4258 4251 if (hemi == -1) { … … 4277 4270 pX->SetValues(gsize,indices,X_values,ADD_VAL); 4278 4271 pY->SetValues(gsize,indices,Y_values,ADD_VAL); 4279 4272 4280 4273 /*free ressources:*/ 4281 4274 xDelete<int>(indices); … … 4307 4300 IssmDouble* H_elastic_precomputed = NULL; 4308 4301 int M; 4309 4302 4310 4303 /*computation of Green functions:*/ 4311 4304 IssmDouble* U_elastic= NULL; 4312 4305 IssmDouble* N_elastic= NULL; 4313 4306 IssmDouble* E_elastic= NULL; 4314 4307 4315 4308 /*optimization:*/ 4316 4309 bool store_green_functions=false; … … 4320 4313 if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!"); 4321 4314 deltathickness_input->GetInputAverage(&I); 4322 4315 4323 4316 /*early return if we are not on the (ice) loading point: */ 4324 4317 if(I==0) return; … … 4419 4412 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); 4420 4413 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 4421 4414 4422 4415 /*Elastic component (from Eq 17 in Adhikari et al, GMD 2015): */ 4423 4416 int index=reCast<int,IssmDouble>(alpha/PI*(M-1)); … … 4434 4427 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 4435 4428 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 4436 4429 4437 4430 /*free ressources:*/ 4438 4431 xDelete<int>(indices); … … 4455 4448 4456 4449 if(IsWaterInElement()){ 4457 4450 4458 4451 IssmDouble area; 4459 4452 … … 4528 4521 if(IsWaterInElement()){ 4529 4522 IssmDouble rho_water, S; 4530 4523 4531 4524 /*recover material parameters: */ 4532 4525 rho_water=matpar->GetMaterialParameter(MaterialsRhoFreshwaterEnum); 4533 4526 4534 4527 /*From Sg_old, recover water sea level rise:*/ 4535 4528 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg_old[this->vertices[i]->Sid()]/NUMVERTICES; 4536 4529 4537 4530 /* Perturbation terms for moment of inertia (moi_list): 4538 4531 * computed analytically (see Wu & Peltier, eqs 10 & 32) … … 4546 4539 else if(this->inputs->Max(MaskIceLevelsetEnum)<0){ 4547 4540 IssmDouble rho_ice, I; 4548 4541 4549 4542 /*recover material parameters: */ 4550 4543 rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum); 4551 4544 4552 4545 /*Compute ice thickness change: */ 4553 4546 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 4554 4547 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 4555 4548 deltathickness_input->GetInputAverage(&I); 4556 4549 4557 4550 dI_list[0] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*cos(longe))/eartharea; 4558 4551 dI_list[1] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*sin(longe))/eartharea; 4559 4552 dI_list[2] = +4*PI*(rho_ice*I*area)*pow(re,4)*(1-pow(sin(late),2))/eartharea; 4560 4553 } 4561 4554 4562 4555 return; 4563 4556 }/*}}}*/ … … 4592 4585 bool computeelastic= true; 4593 4586 bool scaleoceanarea= false; 4594 4587 4595 4588 /*early return if we are not on an ice cap:*/ 4596 4589 if(!(this->inputs->Max(MaskIceLevelsetEnum)<=0)){ … … 4606 4599 return; 4607 4600 } 4608 4601 4609 4602 /*If we are here, we are on ice that is fully grounded or half-way to floating: */ 4610 4603 if ((this->inputs->Min(MaskGroundediceLevelsetEnum))<0){ 4611 4604 notfullygrounded=true; //used later on. 4612 4605 } 4613 4606 4614 4607 /*Inform mask: */ 4615 4608 constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); … … 4636 4629 4637 4630 /* Where is the centroid of this element?:{{{*/ 4638 4631 4639 4632 /*retrieve coordinates: */ 4640 4633 ::GetVerticesCoordinates(&llr_list[0][0],this->vertices,NUMVERTICES,spherical); 4641 4634 4642 4635 IssmDouble minlong=400; 4643 4636 IssmDouble maxlong=-20; … … 4653 4646 if (llr_list[2][1]==0)llr_list[2][1]=360; 4654 4647 } 4655 4648 4656 4649 // correction at the north pole 4657 4650 if(llr_list[0][0]==0)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0; 4658 4651 if(llr_list[1][0]==0)llr_list[1][1]=(llr_list[0][1]+llr_list[2][1])/2.0; 4659 4652 if(llr_list[2][0]==0)llr_list[2][1]=(llr_list[0][1]+llr_list[1][1])/2.0; 4660 4653 4661 4654 //correction at the south pole 4662 4655 if(llr_list[0][0]==180)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0; … … 4684 4677 area*=phi; 4685 4678 } 4686 4679 4687 4680 /*Compute ice thickness change: */ 4688 4681 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); … … 4696 4689 int point1; 4697 4690 IssmDouble fraction1,fraction2; 4698 4691 4699 4692 /*Recover portion of element that is grounded*/ 4700 4693 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating); … … 4750 4743 } 4751 4744 pSgi->SetValues(gsize,indices,values,ADD_VAL); 4752 4745 4753 4746 /*free ressources:*/ 4754 4747 xDelete<IssmDouble>(values); 4755 4748 xDelete<int>(indices); 4756 4749 } 4757 4750 4758 4751 /*Assign output pointer:*/ 4759 4752 _assert_(!xIsNan<IssmDouble>(eustatic)); … … 4780 4773 IssmDouble* G_elastic_precomputed = NULL; 4781 4774 int M; 4782 4775 4783 4776 /*computation of Green functions:*/ 4784 4777 IssmDouble* G_elastic= NULL; … … 4857 4850 longe=longe/180*PI; 4858 4851 /*}}}*/ 4859 4852 4860 4853 if(computeelastic){ 4861 4854 4862 4855 /*recover elastic green function:*/ 4863 4856 DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGElasticEnum)); _assert_(parameter); … … 4897 4890 } 4898 4891 } 4899 4892 4900 4893 pSgo->SetValues(gsize,indices,values,ADD_VAL); 4901 4894 … … 4930 4923 IssmDouble* H_elastic_precomputed = NULL; 4931 4924 int M; 4932 4925 4933 4926 /*computation of Green functions:*/ 4934 4927 IssmDouble* U_elastic= NULL; … … 4957 4950 this->parameters->FindParam(&computerigid,SealevelriseRigidEnum); 4958 4951 this->parameters->FindParam(&computeelastic,SealevelriseElasticEnum); 4959 4952 4960 4953 /*early return if elastic not requested:*/ 4961 4954 if(!computeelastic) return; … … 5026 5019 /*From Sg, recover water sea level rise:*/ 5027 5020 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg[this->vertices[i]->Sid()]/NUMVERTICES; 5028 5021 5029 5022 /*Compute ice thickness change: */ 5030 5023 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 5031 5024 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 5032 5025 deltathickness_input->GetInputAverage(&I); 5033 5026 5034 5027 /*initialize: */ 5035 5028 U_elastic=xNewZeroInit<IssmDouble>(gsize); … … 5073 5066 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5074 5067 } 5075 5068 5076 5069 /*Elastic component (from Eq 17 in Adhikari et al, GMD 2015): */ 5077 5070 int index=reCast<int,IssmDouble>(alpha/PI*(M-1));
Note:
See TracChangeset
for help on using the changeset viewer.