Changeset 16982
- Timestamp:
- 11/29/13 20:27:21 (11 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/Elements/Element.h
r16956 r16982 105 105 virtual void SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum)=0; 106 106 virtual ElementMatrix* CreateKMatrix(void)=0; 107 virtual ElementVector* CreatePVector(void)=0;108 107 virtual void CreateDVector(Vector<IssmDouble>* df)=0; 109 108 virtual void CreateJacobianMatrix(Matrix<IssmDouble>* Jff)=0; -
issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
r16974 r16982 540 540 delete De; 541 541 } 542 }543 /*}}}*/544 /*FUNCTION Penta::CreatePVector(void) {{{*/545 ElementVector* Penta::CreatePVector(void){546 547 /*retrieve parameters: */548 int analysis_type;549 parameters->FindParam(&analysis_type,AnalysisTypeEnum);550 551 /*if debugging mode, check that all pointers exist {{{*/552 _assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);553 /*}}}*/554 555 /*Skip if water element*/556 if(NoIceInElement()) return NULL;557 558 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */559 switch(analysis_type){560 #ifdef _HAVE_STRESSBALANCE_561 case StressbalanceAnalysisEnum:562 return CreatePVectorStressbalanceHoriz();563 break;564 case StressbalanceSIAAnalysisEnum:565 return CreatePVectorStressbalanceSIA();566 break;567 case StressbalanceVerticalAnalysisEnum:568 return CreatePVectorStressbalanceVert();569 break;570 #endif571 #ifdef _HAVE_CONTROL_572 case AdjointHorizAnalysisEnum:573 return CreatePVectorAdjointHoriz();574 break;575 #endif576 #ifdef _HAVE_THERMAL_577 case ThermalAnalysisEnum:578 return CreatePVectorThermal();579 break;580 case EnthalpyAnalysisEnum:581 return CreatePVectorEnthalpy();582 break;583 case MeltingAnalysisEnum:584 return CreatePVectorMelting();585 break;586 #endif587 case L2ProjectionBaseAnalysisEnum:588 return CreatePVectorL2ProjectionBase();589 break;590 case MasstransportAnalysisEnum:591 return CreatePVectorMasstransport();592 break;593 case FreeSurfaceTopAnalysisEnum:594 return CreatePVectorFreeSurfaceTop();595 break;596 case FreeSurfaceBaseAnalysisEnum:597 return CreatePVectorFreeSurfaceBase();598 break;599 #ifdef _HAVE_BALANCED_600 case BalancethicknessAnalysisEnum:601 return CreatePVectorBalancethickness();602 break;603 #endif604 #ifdef _HAVE_HYDROLOGY_605 case HydrologyDCInefficientAnalysisEnum:606 return CreatePVectorHydrologyDCInefficient();607 break;608 case HydrologyDCEfficientAnalysisEnum:609 return CreatePVectorHydrologyDCEfficient();610 break;611 case L2ProjectionEPLAnalysisEnum:612 return CreatePVectorL2ProjectionEPL();613 break;614 #endif615 default:616 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");617 }618 619 /*make compiler happy*/620 return NULL;621 }622 /*}}}*/623 /*FUNCTION Penta::CreatePVectorMasstransport {{{*/624 ElementVector* Penta::CreatePVectorMasstransport(void){625 626 if (!IsOnBed()) return NULL;627 628 /*Depth Averaging Vx and Vy*/629 this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);630 this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);631 632 /*Call Tria function*/633 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.634 ElementVector* pe=tria->CreatePVectorMasstransport();635 delete tria->material; delete tria;636 637 /*Delete Vx and Vy averaged*/638 this->inputs->DeleteInput(VxAverageEnum);639 this->inputs->DeleteInput(VyAverageEnum);640 641 /*Clean up and return*/642 return pe;643 }644 /*}}}*/645 /*FUNCTION Penta::CreatePVectorFreeSurfaceTop {{{*/646 ElementVector* Penta::CreatePVectorFreeSurfaceTop(void){647 648 if(!IsOnSurface()) return NULL;649 650 /*Call Tria function*/651 Tria* tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.652 ElementVector* pe=tria->CreatePVectorFreeSurfaceTop();653 delete tria->material; delete tria;654 655 /*Clean up and return*/656 return pe;657 }658 /*}}}*/659 /*FUNCTION Penta::CreatePVectorFreeSurfaceBase {{{*/660 ElementVector* Penta::CreatePVectorFreeSurfaceBase(void){661 662 if(!IsOnBed()) return NULL;663 664 /*Call Tria function*/665 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.666 ElementVector* pe=tria->CreatePVectorFreeSurfaceBase();667 delete tria->material; delete tria;668 669 /*Clean up and return*/670 return pe;671 }672 /*}}}*/673 /*FUNCTION Penta::CreatePVectorL2ProjectionBase {{{*/674 ElementVector* Penta::CreatePVectorL2ProjectionBase(void){675 676 if (!IsOnBed()) return NULL;677 678 /*Call Tria function*/679 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.680 ElementVector* pe=tria->CreatePVectorL2Projection();681 delete tria->material; delete tria;682 683 /*clean up and return*/684 return pe;685 542 } 686 543 /*}}}*/ … … 4031 3888 } 4032 3889 /*}}}*/ 4033 /*FUNCTION Penta::CreatePVectorEnthalpy {{{*/4034 ElementVector* Penta::CreatePVectorEnthalpy(void){4035 4036 /*compute all load vectors for this element*/4037 ElementVector* pe1=CreatePVectorEnthalpyVolume();4038 ElementVector* pe2=CreatePVectorEnthalpySheet();4039 ElementVector* pe3=CreatePVectorEnthalpyShelf();4040 ElementVector* pe =new ElementVector(pe1,pe2,pe3);4041 4042 /*clean-up and return*/4043 delete pe1;4044 delete pe2;4045 delete pe3;4046 return pe;4047 }4048 /*}}}*/4049 /*FUNCTION Penta::CreatePVectorEnthalpyVolume {{{*/4050 ElementVector* Penta::CreatePVectorEnthalpyVolume(void){4051 4052 /*Constants*/4053 const int numdof=NUMVERTICES*NDOF1;4054 4055 /*Intermediaries*/4056 int i;4057 int stabilization;4058 IssmDouble Jdet,phi,dt;4059 IssmDouble rho_ice,heatcapacity;4060 IssmDouble thermalconductivity,kappa;4061 IssmDouble viscosity,pressure,enthalpy;4062 IssmDouble enthalpypicard[NUMVERTICES], pressure_p[NUMVERTICES];4063 IssmDouble tau_parameter,diameter;4064 IssmDouble u,v,w;4065 IssmDouble scalar_def,scalar_transient;4066 IssmDouble xyz_list[NUMVERTICES][3];4067 IssmDouble L[numdof];4068 IssmDouble dbasis[3][6];4069 IssmDouble epsilon[6];4070 GaussPenta *gauss=NULL;4071 4072 /*Initialize Element vector*/4073 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4074 4075 /*Retrieve all inputs and parameters*/4076 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4077 rho_ice=matpar->GetRhoIce();4078 heatcapacity=matpar->GetHeatCapacity();4079 thermalconductivity=matpar->GetThermalConductivity();4080 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4081 this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);4082 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4083 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4084 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);4085 Input* enthalpy_input=NULL;4086 if(reCast<bool,IssmDouble>(dt)){4087 enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);4088 }4089 if (stabilization==2){4090 diameter=MinEdgeLength(&xyz_list[0][0]);4091 }4092 4093 /* Start looping on the number of gaussian points: */4094 gauss=new GaussPenta(3,3);4095 for(int ig=gauss->begin();ig<gauss->end();ig++){4096 4097 gauss->GaussPoint(ig);4098 4099 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);4100 GetNodalFunctionsP1(&L[0], gauss);4101 4102 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);4103 material->GetViscosity3dFS(&viscosity,&epsilon[0]);4104 GetPhi(&phi, &epsilon[0], viscosity);4105 4106 scalar_def=phi/rho_ice*Jdet*gauss->weight;4107 if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt;4108 4109 /*TODO: add -beta*laplace T_m(p)*/4110 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=scalar_def*L[i];4111 4112 /* Build transient now */4113 if(reCast<bool,IssmDouble>(dt)){4114 enthalpy_input->GetInputValue(&enthalpy, gauss);4115 scalar_transient=enthalpy*Jdet*gauss->weight;4116 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=scalar_transient*L[i];4117 }4118 4119 if(stabilization==2){4120 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);4121 4122 vx_input->GetInputValue(&u, gauss);4123 vy_input->GetInputValue(&v, gauss);4124 vz_input->GetInputValue(&w, gauss);4125 GetInputListOnVertices(&enthalpypicard[0],EnthalpyPicardEnum);4126 GetInputListOnVertices(&pressure_p[0],PressureEnum);4127 kappa=matpar->GetEnthalpyDiffusionParameterVolume(NUMVERTICES,enthalpypicard,pressure_p);4128 kappa/=rho_ice;4129 tau_parameter=StabilizationParameter(u,v,w,diameter,kappa);4130 4131 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);4132 if(reCast<bool,IssmDouble>(dt)){4133 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);4134 }4135 }4136 }4137 4138 /*Clean up and return*/4139 delete gauss;4140 return pe;4141 }4142 /*}}}*/4143 /*FUNCTION Penta::CreatePVectorEnthalpyShelf {{{*/4144 ElementVector* Penta::CreatePVectorEnthalpyShelf(void){4145 4146 /*Constants*/4147 const int numdof=NUMVERTICES*NDOF1;4148 4149 /*Intermediaries */4150 int i,j;4151 IssmDouble Jdet2d;4152 IssmDouble heatcapacity,h_pmp;4153 IssmDouble mixed_layer_capacity,thermal_exchange_velocity;4154 IssmDouble rho_ice,rho_water,pressure,dt,scalar_ocean;4155 IssmDouble xyz_list[NUMVERTICES][3];4156 IssmDouble xyz_list_tria[NUMVERTICES2D][3];4157 IssmDouble basis[NUMVERTICES];4158 GaussPenta* gauss=NULL;4159 4160 /* Ice/ocean heat exchange flux on ice shelf base */4161 if (!IsOnBed() || !IsFloating()) return NULL;4162 4163 /*Initialize Element vector*/4164 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4165 4166 /*Retrieve all inputs and parameters*/4167 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4168 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];4169 mixed_layer_capacity=matpar->GetMixedLayerCapacity();4170 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();4171 rho_water=matpar->GetRhoWater();4172 rho_ice=matpar->GetRhoIce();4173 heatcapacity=matpar->GetHeatCapacity();4174 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4175 Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);4176 4177 /* Start looping on the number of gauss 2d (nodes on the bedrock) */4178 gauss=new GaussPenta(0,1,2,2);4179 for(int ig=gauss->begin();ig<gauss->end();ig++){4180 4181 gauss->GaussPoint(ig);4182 4183 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);4184 GetNodalFunctionsP1(&basis[0], gauss);4185 4186 pressure_input->GetInputValue(&pressure,gauss);4187 h_pmp=matpar->PureIceEnthalpy(pressure);4188 4189 scalar_ocean=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(h_pmp)/(rho_ice*heatcapacity);4190 if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;4191 4192 for(i=0;i<numdof;i++) pe->values[i]+=scalar_ocean*basis[i];4193 }4194 4195 /*Clean up and return*/4196 delete gauss;4197 return pe;4198 }4199 /*}}}*/4200 /*FUNCTION Penta::CreatePVectorEnthalpySheet {{{*/4201 ElementVector* Penta::CreatePVectorEnthalpySheet(void){4202 4203 /*Constants*/4204 const int numdof=NUMVERTICES*NDOF1;4205 4206 /*Intermediaries */4207 int i,j;4208 int analysis_type;4209 IssmDouble xyz_list[NUMVERTICES][3];4210 IssmDouble xyz_list_tria[NUMVERTICES2D][3]={0.0};4211 IssmDouble Jdet2d,dt;4212 IssmDouble rho_ice,heatcapacity;4213 IssmDouble geothermalflux_value, heatflux_value;4214 IssmDouble basalfriction,alpha2,vx,vy,vz;4215 IssmDouble scalar,enthalpy,enthalpyup;4216 IssmDouble pressure,pressureup;4217 IssmDouble watercolumn;4218 IssmDouble basis[NUMVERTICES];4219 Friction* friction=NULL;4220 GaussPenta* gauss=NULL;4221 GaussPenta* gaussup=NULL;4222 4223 /* Geothermal flux on ice sheet base and basal friction */4224 if (!IsOnBed() || IsFloating()) return NULL;4225 4226 /*Initialize Element vector*/4227 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4228 4229 /*Retrieve all inputs and parameters*/4230 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4231 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];4232 parameters->FindParam(&analysis_type,AnalysisTypeEnum);4233 rho_ice=matpar->GetRhoIce();4234 heatcapacity=matpar->GetHeatCapacity();4235 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4236 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4237 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4238 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);4239 Input* enthalpy_input=inputs->GetInput(EnthalpyPicardEnum); _assert_(enthalpy_input);4240 Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);4241 Input* geothermalflux_input=inputs->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);4242 Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); _assert_(watercolumn_input);4243 4244 /*Build friction element, needed later: */4245 friction=new Friction(this,3);4246 4247 /* Start looping on the number of gauss 2d (nodes on the bedrock) */4248 gauss=new GaussPenta(0,1,2,2);4249 gaussup=new GaussPenta(3,4,5,2);4250 4251 for(int ig=gauss->begin();ig<gauss->end();ig++){4252 4253 gauss->GaussPoint(ig);4254 gaussup->GaussPoint(ig);4255 4256 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);4257 GetNodalFunctionsP1(&basis[0], gauss);4258 4259 enthalpy_input->GetInputValue(&enthalpy,gauss);4260 pressure_input->GetInputValue(&pressure,gauss);4261 watercolumn_input->GetInputValue(&watercolumn,gauss);4262 4263 if((watercolumn<=0.) && (enthalpy<matpar->PureIceEnthalpy(pressure))){4264 /* the above check is equivalent to4265 NOT ((watercolumn>0.) AND (enthalpy<PIE)) AND (enthalpy<PIE)*/4266 geothermalflux_input->GetInputValue(&geothermalflux_value,gauss);4267 4268 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);4269 vx_input->GetInputValue(&vx,gauss);4270 vy_input->GetInputValue(&vy,gauss);4271 vz_input->GetInputValue(&vz,gauss);4272 basalfriction=alpha2*(pow(vx,2.0)+pow(vy,2.0)+pow(vz,2.0));4273 4274 heatflux_value=(basalfriction+geothermalflux_value)/(rho_ice);4275 scalar=gauss->weight*Jdet2d*heatflux_value;4276 if(reCast<bool,IssmDouble>(dt)) scalar=dt*scalar;4277 for(i=0;i<numdof;i++) pe->values[i]+=scalar*basis[i];4278 }4279 else if(enthalpy>=matpar->PureIceEnthalpy(pressure)){4280 /* check positive thickness of temperate basal ice layer */4281 enthalpy_input->GetInputValue(&enthalpyup,gaussup);4282 pressure_input->GetInputValue(&pressureup,gaussup);4283 if(enthalpyup>=matpar->PureIceEnthalpy(pressureup)){4284 // TODO: temperate ice has positive thickness: grad enthalpy*n=0.4285 }4286 else{4287 // only base temperate, set Dirichlet BCs in Penta::UpdateBasalConstraintsEnthalpy()4288 }4289 }4290 else {4291 // base cold, but watercolumn positive. Set base to h_pmp.4292 }4293 }4294 4295 /*Clean up and return*/4296 delete gauss;4297 delete gaussup;4298 delete friction;4299 return pe;4300 }4301 /*}}}*/4302 /*FUNCTION Penta::CreatePVectorMelting {{{*/4303 ElementVector* Penta::CreatePVectorMelting(void){4304 return NULL;4305 }4306 /*}}}*/4307 /*FUNCTION Penta::CreatePVectorThermal {{{*/4308 ElementVector* Penta::CreatePVectorThermal(void){4309 4310 /*compute all load vectors for this element*/4311 ElementVector* pe1=CreatePVectorThermalVolume();4312 ElementVector* pe2=CreatePVectorThermalSheet();4313 ElementVector* pe3=CreatePVectorThermalShelf();4314 ElementVector* pe =new ElementVector(pe1,pe2,pe3);4315 4316 /*clean-up and return*/4317 delete pe1;4318 delete pe2;4319 delete pe3;4320 return pe;4321 }4322 /*}}}*/4323 /*FUNCTION Penta::CreatePVectorThermalVolume {{{*/4324 ElementVector* Penta::CreatePVectorThermalVolume(void){4325 4326 /*Constants*/4327 const int numdof=NUMVERTICES*NDOF1;4328 4329 /*Intermediaries*/4330 int i;4331 int stabilization;4332 IssmDouble Jdet,phi,dt;4333 IssmDouble rho_ice,heatcapacity;4334 IssmDouble thermalconductivity,kappa;4335 IssmDouble viscosity,temperature;4336 IssmDouble tau_parameter,diameter;4337 IssmDouble u,v,w;4338 IssmDouble scalar_def,scalar_transient;4339 IssmDouble xyz_list[NUMVERTICES][3];4340 IssmDouble L[numdof];4341 IssmDouble dbasis[3][6];4342 IssmDouble epsilon[6];4343 GaussPenta *gauss=NULL;4344 4345 /*Initialize Element vector*/4346 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4347 4348 /*Retrieve all inputs and parameters*/4349 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4350 rho_ice=matpar->GetRhoIce();4351 heatcapacity=matpar->GetHeatCapacity();4352 thermalconductivity=matpar->GetThermalConductivity();4353 kappa=thermalconductivity/(rho_ice*heatcapacity);4354 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4355 this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);4356 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4357 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4358 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);4359 Input* temperature_input=NULL;4360 if(reCast<bool,IssmDouble>(dt)) temperature_input=inputs->GetInput(TemperatureEnum); _assert_(inputs);4361 if(stabilization==2) diameter=MinEdgeLength(&xyz_list[0][0]);4362 4363 /* Start looping on the number of gaussian points: */4364 gauss=new GaussPenta(3,3);4365 for(int ig=gauss->begin();ig<gauss->end();ig++){4366 4367 gauss->GaussPoint(ig);4368 4369 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);4370 GetNodalFunctionsP1(&L[0], gauss);4371 4372 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);4373 material->GetViscosity3dFS(&viscosity,&epsilon[0]);4374 GetPhi(&phi, &epsilon[0], viscosity);4375 4376 scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss->weight;4377 if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt;4378 4379 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=scalar_def*L[i];4380 4381 /* Build transient now */4382 if(reCast<bool,IssmDouble>(dt)){4383 temperature_input->GetInputValue(&temperature, gauss);4384 scalar_transient=temperature*Jdet*gauss->weight;4385 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=scalar_transient*L[i];4386 }4387 4388 if(stabilization==2){4389 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);4390 4391 vx_input->GetInputValue(&u, gauss);4392 vy_input->GetInputValue(&v, gauss);4393 vz_input->GetInputValue(&w, gauss);4394 4395 tau_parameter=StabilizationParameter(u,v,w,diameter,kappa);4396 4397 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);4398 if(reCast<bool,IssmDouble>(dt)){4399 for(i=0;i<NUMVERTICES;i++) pe->values[i]+=tau_parameter*scalar_transient*(u*dbasis[0][i]+v*dbasis[1][i]+w*dbasis[2][i]);4400 }4401 }4402 }4403 4404 /*Clean up and return*/4405 delete gauss;4406 return pe;4407 }4408 /*}}}*/4409 /*FUNCTION Penta::CreatePVectorThermalShelf {{{*/4410 ElementVector* Penta::CreatePVectorThermalShelf(void){4411 4412 /*Constants*/4413 const int numdof=NUMVERTICES*NDOF1;4414 4415 /*Intermediaries */4416 int i,j;4417 IssmDouble Jdet2d;4418 IssmDouble mixed_layer_capacity,thermal_exchange_velocity;4419 IssmDouble rho_ice,rho_water,pressure,dt,scalar_ocean;4420 IssmDouble heatcapacity,t_pmp;4421 IssmDouble xyz_list[NUMVERTICES][3];4422 IssmDouble xyz_list_tria[NUMVERTICES2D][3];4423 IssmDouble basis[NUMVERTICES];4424 GaussPenta* gauss=NULL;4425 4426 /* Ice/ocean heat exchange flux on ice shelf base */4427 if (!IsOnBed() || !IsFloating()) return NULL;4428 4429 /*Initialize Element vector*/4430 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4431 4432 /*Retrieve all inputs and parameters*/4433 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4434 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];4435 mixed_layer_capacity=matpar->GetMixedLayerCapacity();4436 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();4437 rho_water=matpar->GetRhoWater();4438 rho_ice=matpar->GetRhoIce();4439 heatcapacity=matpar->GetHeatCapacity();4440 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4441 Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);4442 4443 /* Start looping on the number of gauss 2d (nodes on the bedrock) */4444 gauss=new GaussPenta(0,1,2,2);4445 for(int ig=gauss->begin();ig<gauss->end();ig++){4446 4447 gauss->GaussPoint(ig);4448 4449 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);4450 GetNodalFunctionsP1(&basis[0], gauss);4451 4452 pressure_input->GetInputValue(&pressure,gauss);4453 t_pmp=matpar->TMeltingPoint(pressure);4454 4455 scalar_ocean=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(t_pmp)/(heatcapacity*rho_ice);4456 if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;4457 4458 for(i=0;i<numdof;i++) pe->values[i]+=scalar_ocean*basis[i];4459 }4460 4461 /*Clean up and return*/4462 delete gauss;4463 return pe;4464 }4465 /*}}}*/4466 /*FUNCTION Penta::CreatePVectorThermalSheet {{{*/4467 ElementVector* Penta::CreatePVectorThermalSheet(void){4468 4469 /*Constants*/4470 const int numdof=NUMVERTICES*NDOF1;4471 4472 /*Intermediaries */4473 int i,j;4474 int analysis_type;4475 IssmDouble xyz_list[NUMVERTICES][3];4476 IssmDouble xyz_list_tria[NUMVERTICES2D][3]={0.0};4477 IssmDouble Jdet2d,dt;4478 IssmDouble rho_ice,heatcapacity,geothermalflux_value;4479 IssmDouble basalfriction,alpha2,vx,vy;4480 IssmDouble basis[NUMVERTICES];4481 IssmDouble scalar;4482 Friction* friction=NULL;4483 GaussPenta* gauss=NULL;4484 4485 /* Geothermal flux on ice sheet base and basal friction */4486 if (!IsOnBed() || IsFloating()) return NULL;4487 4488 /*Initialize Element vector*/4489 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);4490 4491 /*Retrieve all inputs and parameters*/4492 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4493 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];4494 parameters->FindParam(&analysis_type,AnalysisTypeEnum);4495 rho_ice=matpar->GetRhoIce();4496 heatcapacity=matpar->GetHeatCapacity();4497 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);4498 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4499 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4500 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);4501 Input* geothermalflux_input=inputs->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);4502 4503 /*Build frictoin element, needed later: */4504 friction=new Friction(this,3);4505 4506 /* Start looping on the number of gauss 2d (nodes on the bedrock) */4507 gauss=new GaussPenta(0,1,2,2);4508 for(int ig=gauss->begin();ig<gauss->end();ig++){4509 4510 gauss->GaussPoint(ig);4511 4512 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);4513 GetNodalFunctionsP1(&basis[0], gauss);4514 4515 geothermalflux_input->GetInputValue(&geothermalflux_value,gauss);4516 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);4517 vx_input->GetInputValue(&vx,gauss);4518 vy_input->GetInputValue(&vy,gauss);4519 basalfriction=alpha2*(pow(vx,2.0)+pow(vy,2.0));4520 4521 scalar=gauss->weight*Jdet2d*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice);4522 if(reCast<bool,IssmDouble>(dt)) scalar=dt*scalar;4523 4524 for(i=0;i<numdof;i++) pe->values[i]+=scalar*basis[i];4525 }4526 4527 /*Clean up and return*/4528 delete gauss;4529 delete friction;4530 return pe;4531 }4532 /*}}}*/4533 3890 /*FUNCTION Penta::UpdateBasalConstraintsEnthalpy{{{*/ 4534 3891 void Penta::UpdateBasalConstraintsEnthalpy(void){ … … 5118 4475 delete gauss; 5119 4476 return Ke; 5120 }5121 /*}}}*/5122 /*FUNCTION Penta::CreatePVectorAdjointHoriz{{{*/5123 ElementVector* Penta::CreatePVectorAdjointHoriz(void){5124 5125 int approximation;5126 inputs->GetInputValue(&approximation,ApproximationEnum);5127 5128 switch(approximation){5129 case SSAApproximationEnum:5130 return CreatePVectorAdjointSSA();5131 case HOApproximationEnum:5132 return CreatePVectorAdjointHO();5133 case NoneApproximationEnum:5134 return NULL;5135 case FSApproximationEnum:5136 return CreatePVectorAdjointFS();5137 default:5138 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");5139 }5140 }5141 /*}}}*/5142 /*FUNCTION Penta::CreatePVectorAdjointSSA{{{*/5143 ElementVector* Penta::CreatePVectorAdjointSSA(){5144 5145 if (!IsOnBed()) return NULL;5146 5147 /*Call Tria function*/5148 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.5149 ElementVector* pe=tria->CreatePVectorAdjointHoriz();5150 delete tria->material; delete tria;5151 5152 /*clean up and return*/5153 return pe;5154 }5155 /*}}}*/5156 /*FUNCTION Penta::CreatePVectorAdjointHO{{{*/5157 ElementVector* Penta::CreatePVectorAdjointHO(void){5158 5159 /*Nothing to be done if not on surface*/5160 if (!IsOnSurface()) return NULL;5161 5162 /*Intermediaries */5163 int i,j,resp;5164 int *responses=NULL;5165 int num_responses;5166 IssmDouble Jdet2d;5167 IssmDouble obs_velocity_mag,velocity_mag;5168 IssmDouble dux,duy;5169 IssmDouble epsvel=2.220446049250313e-16;5170 IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/5171 IssmDouble scalex=0.,scaley=0.,scale=0.,S=0.;5172 IssmDouble vx,vy,vxobs,vyobs,weight;5173 IssmDouble xyz_list[NUMVERTICES][3];5174 IssmDouble xyz_list_tria[NUMVERTICES2D][3];5175 5176 /*Fetch number of nodes and dof for this finite element*/5177 int numnodes = this->NumberofNodes();5178 5179 /*Initialize Element vector*/5180 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);5181 IssmDouble* basis = xNew<IssmDouble>(numnodes);5182 5183 /*Retrieve all inputs and parameters*/5184 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5185 this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);5186 this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);5187 Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);5188 Input* vx_input =inputs->GetInput(VxEnum); _assert_(vx_input);5189 Input* vy_input =inputs->GetInput(VyEnum); _assert_(vy_input);5190 Input* vxobs_input =inputs->GetInput(InversionVxObsEnum); _assert_(vxobs_input);5191 Input* vyobs_input =inputs->GetInput(InversionVyObsEnum); _assert_(vyobs_input);5192 5193 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];5194 5195 /*Get Surface if required by one response*/5196 for(resp=0;resp<num_responses;resp++){5197 if(responses[resp]==SurfaceAverageVelMisfitEnum){5198 inputs->GetInputValue(&S,SurfaceAreaEnum); break;5199 }5200 }5201 5202 /* Start looping on the number of gaussian points: */5203 GaussPenta* gauss=new GaussPenta(3,4,5,4);5204 for(int ig=gauss->begin();ig<gauss->end();ig++){5205 5206 gauss->GaussPoint(ig);5207 5208 /* Get Jacobian determinant: */5209 GetTriaJacobianDeterminant(&Jdet2d,&xyz_list_tria[0][0],gauss);5210 5211 /*Get all parameters at gaussian point*/5212 vx_input->GetInputValue(&vx,gauss);5213 vy_input->GetInputValue(&vy,gauss);5214 vxobs_input->GetInputValue(&vxobs,gauss);5215 vyobs_input->GetInputValue(&vyobs,gauss);5216 GetNodalFunctions(basis, gauss);5217 5218 /*Loop over all requested responses*/5219 for(resp=0;resp<num_responses;resp++){5220 5221 weights_input->GetInputValue(&weight,gauss,responses[resp]);5222 5223 switch(responses[resp]){5224 case SurfaceAbsVelMisfitEnum:5225 /*5226 * 1 [ 2 2 ]5227 * J = --- | (u - u ) + (v - v ) |5228 * 2 [ obs obs ]5229 *5230 * dJ5231 * DU = - -- = (u - u )5232 * du obs5233 */5234 for(i=0;i<numnodes;i++){5235 dux=vxobs-vx;5236 duy=vyobs-vy;5237 pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i];5238 pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i];5239 }5240 break;5241 case SurfaceRelVelMisfitEnum:5242 /*5243 * 1 [ \bar{v}^2 2 \bar{v}^2 2 ]5244 * J = --- | ------------- (u - u ) + ------------- (v - v ) |5245 * 2 [ (u + eps)^2 obs (v + eps)^2 obs ]5246 * obs obs5247 *5248 * dJ \bar{v}^25249 * DU = - -- = ------------- (u - u )5250 * du (u + eps)^2 obs5251 * obs5252 */5253 for(i=0;i<numnodes;i++){5254 scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;5255 scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;5256 dux=scalex*(vxobs-vx);5257 duy=scaley*(vyobs-vy);5258 pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i];5259 pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i];5260 }5261 break;5262 case SurfaceLogVelMisfitEnum:5263 /*5264 * [ vel + eps ] 25265 * J = 4 \bar{v}^2 | log ( ----------- ) |5266 * [ vel + eps ]5267 * obs5268 *5269 * dJ 2 * log(...)5270 * DU = - -- = - 4 \bar{v}^2 ------------- u5271 * du vel^2 + eps5272 *5273 */5274 for(i=0;i<numnodes;i++){5275 velocity_mag =sqrt(pow(vx, 2)+pow(vy, 2))+epsvel;5276 obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;5277 scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);5278 dux=scale*vx;5279 duy=scale*vy;5280 pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i];5281 pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i];5282 }5283 break;5284 case SurfaceAverageVelMisfitEnum:5285 /*5286 * 1 2 25287 * J = --- sqrt( (u - u ) + (v - v ) )5288 * S obs obs5289 *5290 * dJ 1 15291 * DU = - -- = - --- ----------- * 2 (u - u )5292 * du S 2 sqrt(...) obs5293 */5294 for(i=0;i<numnodes;i++){5295 scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);5296 dux=scale*(vxobs-vx);5297 duy=scale*(vyobs-vy);5298 pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i];5299 pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i];5300 }5301 break;5302 case SurfaceLogVxVyMisfitEnum:5303 /*5304 * 1 [ |u| + eps 2 |v| + eps 2 ]5305 * J = --- \bar{v}^2 | log ( ----------- ) + log ( ----------- ) |5306 * 2 [ |u |+ eps |v |+ eps ]5307 * obs obs5308 * dJ 1 u 15309 * DU = - -- = - \bar{v}^2 log(u...) --------- ---- ~ - \bar{v}^2 log(u...) ------5310 * du |u| + eps |u| u + eps5311 */5312 for(i=0;i<numnodes;i++){5313 dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);5314 duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);5315 pe->values[i*NDOF2+0]+=dux*weight*Jdet2d*gauss->weight*basis[i];5316 pe->values[i*NDOF2+1]+=duy*weight*Jdet2d*gauss->weight*basis[i];5317 }5318 break;5319 case DragCoefficientAbsGradientEnum:5320 /*Nothing in P vector*/5321 break;5322 case ThicknessAbsGradientEnum:5323 /*Nothing in P vector*/5324 break;5325 case ThicknessAlongGradientEnum:5326 /*Nothing in P vector*/5327 break;5328 case ThicknessAcrossGradientEnum:5329 /*Nothing in P vector*/5330 break;5331 case RheologyBbarAbsGradientEnum:5332 /*Nothing in P vector*/5333 break;5334 default:5335 _error_("response " << EnumToStringx(responses[resp]) << " not supported yet");5336 }5337 }5338 }5339 5340 /*Clean up and return*/5341 xDelete<IssmDouble>(basis);5342 xDelete<int>(responses);5343 delete gauss;5344 return pe;5345 }5346 /*}}}*/5347 /*FUNCTION Penta::CreatePVectorAdjointFS{{{*/5348 ElementVector* Penta::CreatePVectorAdjointFS(void){5349 5350 if(!IsOnSurface()) return NULL;5351 5352 /*Intermediaries */5353 int i,j,resp;5354 int *responses= NULL;5355 int num_responses;5356 IssmDouble Jdet2d;5357 IssmDouble obs_velocity_mag,velocity_mag;5358 IssmDouble dux,duy;5359 IssmDouble epsvel = 2.220446049250313e-16;5360 IssmDouble meanvel = 3.170979198376458e-05; /*1000 m/yr */5361 IssmDouble scalex = 0,scaley=0,scale=0,S=0;5362 IssmDouble vx,vy,vxobs,vyobs,weight;5363 IssmDouble xyz_list[NUMVERTICES][3];5364 IssmDouble xyz_list_tria[NUMVERTICES2D][3];5365 5366 /*Fetch number of nodes and dof for this finite element*/5367 int vnumnodes = this->NumberofNodesVelocity();5368 int pnumnodes = this->NumberofNodesPressure();5369 5370 /*Prepare coordinate system list*/5371 int* cs_list = xNew<int>(vnumnodes+pnumnodes);5372 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;5373 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;5374 5375 /*Initialize Element matrix and vectors*/5376 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSApproximationEnum);5377 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);5378 5379 /*Retrieve all inputs and parameters*/5380 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5381 this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);5382 this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);5383 Input* weights_input = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);5384 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input);5385 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input);5386 Input* vxobs_input = inputs->GetInput(InversionVxObsEnum); _assert_(vxobs_input);5387 Input* vyobs_input = inputs->GetInput(InversionVyObsEnum); _assert_(vyobs_input);5388 5389 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];5390 5391 /*Get Surface if required by one response*/5392 for(resp=0;resp<num_responses;resp++){5393 if(responses[resp]==SurfaceAverageVelMisfitEnum){5394 inputs->GetInputValue(&S,SurfaceAreaEnum); break;5395 }5396 }5397 5398 /* Start looping on the number of gaussian points: */5399 GaussPenta* gauss=new GaussPenta(3,4,5,4);5400 for(int ig=gauss->begin();ig<gauss->end();ig++){5401 5402 gauss->GaussPoint(ig);5403 5404 /* Get Jacobian determinant: */5405 GetTriaJacobianDeterminant(&Jdet2d,&xyz_list_tria[0][0],gauss);5406 5407 /*Get all parameters at gaussian point*/5408 vx_input->GetInputValue(&vx,gauss);5409 vy_input->GetInputValue(&vy,gauss);5410 vxobs_input->GetInputValue(&vxobs,gauss);5411 vyobs_input->GetInputValue(&vyobs,gauss);5412 GetNodalFunctionsVelocity(vbasis,gauss);5413 5414 /*Loop over all requested responses*/5415 for(resp=0;resp<num_responses;resp++){5416 5417 weights_input->GetInputValue(&weight,gauss,responses[resp]);5418 5419 switch(responses[resp]){5420 5421 case SurfaceAbsVelMisfitEnum:5422 /*5423 * 1 [ 2 2 ]5424 * J = --- | (u - u ) + (v - v ) |5425 * 2 [ obs obs ]5426 *5427 * dJ5428 * DU = - -- = (u - u )5429 * du obs5430 */5431 for(i=0;i<vnumnodes;i++){5432 dux=vxobs-vx;5433 duy=vyobs-vy;5434 pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i];5435 pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i];5436 }5437 break;5438 case SurfaceRelVelMisfitEnum:5439 /*5440 * 1 [ \bar{v}^2 2 \bar{v}^2 2 ]5441 * J = --- | ------------- (u - u ) + ------------- (v - v ) |5442 * 2 [ (u + eps)^2 obs (v + eps)^2 obs ]5443 * obs obs5444 *5445 * dJ \bar{v}^25446 * DU = - -- = ------------- (u - u )5447 * du (u + eps)^2 obs5448 * obs5449 */5450 for(i=0;i<vnumnodes;i++){5451 scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;5452 scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;5453 dux=scalex*(vxobs-vx);5454 duy=scaley*(vyobs-vy);5455 pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i];5456 pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i];5457 }5458 break;5459 case SurfaceLogVelMisfitEnum:5460 /*5461 * [ vel + eps ] 25462 * J = 4 \bar{v}^2 | log ( ----------- ) |5463 * [ vel + eps ]5464 * obs5465 *5466 * dJ 2 * log(...)5467 * DU = - -- = - 4 \bar{v}^2 ------------- u5468 * du vel^2 + eps5469 *5470 */5471 for(i=0;i<vnumnodes;i++){5472 velocity_mag =sqrt(pow(vx, 2)+pow(vy, 2))+epsvel;5473 obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;5474 scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);5475 dux=scale*vx;5476 duy=scale*vy;5477 pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i];5478 pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i];5479 }5480 break;5481 case SurfaceAverageVelMisfitEnum:5482 /*5483 * 1 2 25484 * J = --- sqrt( (u - u ) + (v - v ) )5485 * S obs obs5486 *5487 * dJ 1 15488 * DU = - -- = - --- ----------- * 2 (u - u )5489 * du S 2 sqrt(...) obs5490 */5491 for(i=0;i<vnumnodes;i++){5492 scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);5493 dux=scale*(vxobs-vx);5494 duy=scale*(vyobs-vy);5495 pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i];5496 pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i];5497 }5498 break;5499 case SurfaceLogVxVyMisfitEnum:5500 /*5501 * 1 [ |u| + eps 2 |v| + eps 2 ]5502 * J = --- \bar{v}^2 | log ( ----------- ) + log ( ----------- ) |5503 * 2 [ |u |+ eps |v |+ eps ]5504 * obs obs5505 * dJ 1 u 15506 * DU = - -- = - \bar{v}^2 log(u...) --------- ---- ~ - \bar{v}^2 log(u...) ------5507 * du |u| + eps |u| u + eps5508 */5509 for(i=0;i<vnumnodes;i++){5510 dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);5511 duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);5512 pe->values[i*NDOF3+0]+=dux*weight*Jdet2d*gauss->weight*vbasis[i];5513 pe->values[i*NDOF3+1]+=duy*weight*Jdet2d*gauss->weight*vbasis[i];5514 }5515 break;5516 case DragCoefficientAbsGradientEnum:5517 /*Nothing in P vector*/5518 break;5519 case ThicknessAbsGradientEnum:5520 /*Nothing in P vector*/5521 break;5522 case ThicknessAcrossGradientEnum:5523 /*Nothing in P vector*/5524 break;5525 case ThicknessAlongGradientEnum:5526 /*Nothing in P vector*/5527 break;5528 case RheologyBbarAbsGradientEnum:5529 /*Nothing in P vector*/5530 break;5531 default:5532 _error_("response " << EnumToStringx(responses[resp]) << " not supported yet");5533 }5534 }5535 }5536 5537 /*Clean up and return*/5538 xDelete<int>(responses);5539 xDelete<int>(cs_list);5540 xDelete<IssmDouble>(vbasis);5541 delete gauss;5542 return pe;5543 4477 } 5544 4478 /*}}}*/ … … 7867 6801 } 7868 6802 /*}}}*/ 7869 /*FUNCTION Penta::CreatePVectorCouplingSSAFS {{{*/7870 ElementVector* Penta::CreatePVectorCouplingSSAFS(void){7871 7872 /*compute all load vectors for this element*/7873 ElementVector* pe1=CreatePVectorCouplingSSAFSViscous();7874 ElementVector* pe2=CreatePVectorCouplingSSAFSFriction();7875 ElementVector* pe =new ElementVector(pe1,pe2);7876 7877 /*clean-up and return*/7878 delete pe1;7879 delete pe2;7880 return pe;7881 }7882 /*}}}*/7883 /*FUNCTION Penta::CreatePVectorCouplingSSAFSViscous {{{*/7884 ElementVector* Penta::CreatePVectorCouplingSSAFSViscous(void){7885 7886 /*Intermediaries */7887 int i,approximation;7888 IssmDouble viscosity,Jdet;7889 IssmDouble FSreconditioning;7890 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/7891 IssmDouble dw[3];7892 IssmDouble xyz_list[NUMVERTICES][3];7893 IssmDouble basis[6]; //for the six nodes of the penta7894 IssmDouble dbasis[3][6]; //for the six nodes of the penta7895 GaussPenta *gauss=NULL;7896 7897 /*Initialize Element vector and return if necessary*/7898 inputs->GetInputValue(&approximation,ApproximationEnum);7899 if(approximation!=SSAFSApproximationEnum) return NULL;7900 int vnumnodes = this->NumberofNodesVelocity();7901 int pnumnodes = this->NumberofNodesPressure();7902 7903 /*Prepare coordinate system list*/7904 int* cs_list = xNew<int>(vnumnodes+pnumnodes);7905 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;7906 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;7907 ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);7908 7909 /*Retrieve all inputs and parameters*/7910 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7911 this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);7912 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);7913 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);7914 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);7915 Input* vzSSA_input=inputs->GetInput(VzSSAEnum); _assert_(vzSSA_input);7916 7917 /* Start looping on the number of gaussian points: */7918 gauss=new GaussPenta(5,5);7919 for(int ig=gauss->begin();ig<gauss->end();ig++){7920 7921 gauss->GaussPoint(ig);7922 7923 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7924 GetNodalFunctionsP1(&basis[0], gauss);7925 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);7926 7927 vzSSA_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);7928 7929 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);7930 material->GetViscosity3dFS(&viscosity,&epsilon[0]);7931 7932 for(i=0;i<NUMVERTICES;i++){7933 pe->values[i*NDOF3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];7934 pe->values[i*NDOF3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];7935 pe->values[i*NDOF3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);7936 pe->values[NDOF3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];7937 }7938 }7939 7940 /*Transform coordinate system*/7941 ::TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);7942 7943 /*Clean up and return*/7944 xDelete<int>(cs_list);7945 delete gauss;7946 return pe;7947 }7948 /*}}}*/7949 /*FUNCTION Penta::CreatePVectorCouplingSSAFSFriction{{{*/7950 ElementVector* Penta::CreatePVectorCouplingSSAFSFriction(void){7951 7952 /*Intermediaries*/7953 int i,j;7954 int approximation,analysis_type;7955 IssmDouble Jdet,Jdet2d;7956 IssmDouble FSreconditioning;7957 IssmDouble bed_normal[3];7958 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/7959 IssmDouble viscosity, w, alpha2_gauss;7960 IssmDouble dw[3];7961 IssmDouble xyz_list_tria[NUMVERTICES2D][3];7962 IssmDouble xyz_list[NUMVERTICES][3];7963 IssmDouble basis[6]; //for the six nodes of the penta7964 Friction* friction=NULL;7965 GaussPenta *gauss=NULL;7966 7967 /*Initialize Element vector and return if necessary*/7968 if(!IsOnBed() || IsFloating()) return NULL;7969 inputs->GetInputValue(&approximation,ApproximationEnum);7970 if(approximation!=SSAFSApproximationEnum) return NULL;7971 int vnumnodes = this->NumberofNodesVelocity();7972 int pnumnodes = this->NumberofNodesPressure();7973 7974 /*Prepare coordinate system list*/7975 int* cs_list = xNew<int>(vnumnodes+pnumnodes);7976 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;7977 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;7978 ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);7979 7980 /*Retrieve all inputs and parameters*/7981 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7982 parameters->FindParam(&analysis_type,AnalysisTypeEnum);7983 this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);7984 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);7985 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);7986 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);7987 Input* vzSSA_input=inputs->GetInput(VzSSAEnum); _assert_(vzSSA_input);7988 7989 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];7990 7991 /*build friction object, used later on: */7992 friction=new Friction(this,3);7993 7994 /* Start looping on the number of gauss 2d (nodes on the bedrock) */7995 gauss=new GaussPenta(0,1,2,2);7996 for(int ig=gauss->begin();ig<gauss->end();ig++){7997 7998 gauss->GaussPoint(ig);7999 8000 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);8001 GetNodalFunctionsP1(basis, gauss);8002 8003 vzSSA_input->GetInputValue(&w, gauss);8004 vzSSA_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);8005 8006 NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);8007 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);8008 material->GetViscosity3dFS(&viscosity,&epsilon[0]);8009 friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);8010 8011 for(i=0;i<NUMVERTICES2D;i++){8012 pe->values[i*NDOF3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];8013 pe->values[i*NDOF3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];8014 pe->values[i*NDOF3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];8015 }8016 }8017 8018 /*Transform coordinate system*/8019 ::TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);8020 8021 /*Clean up and return*/8022 xDelete<int>(cs_list);8023 delete gauss;8024 delete friction;8025 return pe;8026 }8027 /*}}}*/8028 /*FUNCTION Penta::CreatePVectorCouplingHOFS {{{*/8029 ElementVector* Penta::CreatePVectorCouplingHOFS(void){8030 8031 /*compute all load vectors for this element*/8032 ElementVector* pe1=CreatePVectorCouplingHOFSViscous();8033 ElementVector* pe2=CreatePVectorCouplingHOFSFriction();8034 ElementVector* pe =new ElementVector(pe1,pe2);8035 8036 /*clean-up and return*/8037 delete pe1;8038 delete pe2;8039 return pe;8040 }8041 /*}}}*/8042 /*FUNCTION Penta::CreatePVectorCouplingHOFSViscous {{{*/8043 ElementVector* Penta::CreatePVectorCouplingHOFSViscous(void){8044 8045 /*Intermediaries */8046 int i;8047 int approximation;8048 IssmDouble viscosity,Jdet;8049 IssmDouble FSreconditioning;8050 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/8051 IssmDouble dw[3];8052 IssmDouble xyz_list[NUMVERTICES][3];8053 IssmDouble basis[6]; //for the six nodes of the penta8054 IssmDouble dbasis[3][6]; //for the six nodes of the penta8055 GaussPenta *gauss=NULL;8056 8057 /*Initialize Element vector and return if necessary*/8058 inputs->GetInputValue(&approximation,ApproximationEnum);8059 if(approximation!=HOFSApproximationEnum) return NULL;8060 int vnumnodes = this->NumberofNodesVelocity();8061 int pnumnodes = this->NumberofNodesPressure();8062 8063 /*Prepare coordinate system list*/8064 int* cs_list = xNew<int>(vnumnodes+pnumnodes);8065 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;8066 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;8067 8068 /*Initialize Element matrix and vectors*/8069 ElementVector* pe=new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);8070 8071 /*Retrieve all inputs and parameters*/8072 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8073 this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);8074 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8075 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8076 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);8077 Input* vzHO_input=inputs->GetInput(VzHOEnum); _assert_(vzHO_input);8078 8079 /* Start looping on the number of gaussian points: */8080 gauss=new GaussPenta(5,5);8081 for(int ig=gauss->begin();ig<gauss->end();ig++){8082 8083 gauss->GaussPoint(ig);8084 8085 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8086 GetNodalFunctionsP1(&basis[0], gauss);8087 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);8088 8089 vzHO_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);8090 8091 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);8092 material->GetViscosity3dFS(&viscosity,&epsilon[0]);8093 8094 for(i=0;i<NUMVERTICES;i++){8095 pe->values[i*NDOF3+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];8096 pe->values[i*NDOF3+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];8097 pe->values[i*NDOF3+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);8098 pe->values[NDOF3*vnumnodes+i]+=Jdet*gauss->weight*FSreconditioning*dw[2]*basis[i];8099 }8100 }8101 8102 /*Transform coordinate system*/8103 ::TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);8104 8105 /*Clean up and return*/8106 xDelete<int>(cs_list);8107 delete gauss;8108 return pe;8109 }8110 /*}}}*/8111 /*FUNCTION Penta::CreatePVectorCouplingHOFSFriction{{{*/8112 ElementVector* Penta::CreatePVectorCouplingHOFSFriction(void){8113 8114 /*Intermediaries*/8115 int i,j;8116 int approximation,analysis_type;8117 IssmDouble Jdet,Jdet2d;8118 IssmDouble FSreconditioning;8119 IssmDouble bed_normal[3];8120 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/8121 IssmDouble viscosity, w, alpha2_gauss;8122 IssmDouble dw[3];8123 IssmDouble xyz_list_tria[NUMVERTICES2D][3];8124 IssmDouble xyz_list[NUMVERTICES][3];8125 IssmDouble basis[6]; //for the six nodes of the penta8126 Friction* friction=NULL;8127 GaussPenta *gauss=NULL;8128 8129 /*Initialize Element vector and return if necessary*/8130 if(!IsOnBed() || IsFloating()) return NULL;8131 inputs->GetInputValue(&approximation,ApproximationEnum);8132 if(approximation!=HOFSApproximationEnum) return NULL;8133 8134 int vnumnodes = this->NumberofNodesVelocity();8135 int pnumnodes = this->NumberofNodesPressure();8136 int numnodes = vnumnodes+pnumnodes;8137 8138 /*Prepare coordinate system list*/8139 int* cs_list = xNew<int>(vnumnodes+pnumnodes);8140 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;8141 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;8142 8143 ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters,FSvelocityEnum);8144 8145 /*Retrieve all inputs and parameters*/8146 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8147 parameters->FindParam(&analysis_type,AnalysisTypeEnum);8148 this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);8149 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8150 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8151 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);8152 Input* vzHO_input=inputs->GetInput(VzHOEnum); _assert_(vzHO_input);8153 8154 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];8155 8156 /*build friction object, used later on: */8157 friction=new Friction(this,3);8158 8159 /* Start looping on the number of gauss 2d (nodes on the bedrock) */8160 gauss=new GaussPenta(0,1,2,2);8161 for(int ig=gauss->begin();ig<gauss->end();ig++){8162 8163 gauss->GaussPoint(ig);8164 8165 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);8166 GetNodalFunctionsP1(basis, gauss);8167 8168 vzHO_input->GetInputValue(&w, gauss);8169 vzHO_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);8170 8171 NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);8172 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);8173 material->GetViscosity3dFS(&viscosity,&epsilon[0]);8174 friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);8175 8176 for(i=0;i<NUMVERTICES2D;i++){8177 pe->values[i*NDOF3+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];8178 pe->values[i*NDOF3+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];8179 pe->values[i*NDOF3+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];8180 }8181 }8182 8183 /*Transform coordinate system*/8184 ::TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);8185 8186 /*Clean up and return*/8187 xDelete<int>(cs_list);8188 delete gauss;8189 delete friction;8190 return pe;8191 }8192 /*}}}*/8193 /*FUNCTION Penta::CreatePVectorStressbalanceHoriz{{{*/8194 ElementVector* Penta::CreatePVectorStressbalanceHoriz(void){8195 8196 int approximation;8197 inputs->GetInputValue(&approximation,ApproximationEnum);8198 8199 switch(approximation){8200 case SSAApproximationEnum:8201 return CreatePVectorStressbalanceSSA();8202 case HOApproximationEnum:8203 return CreatePVectorStressbalanceHO();8204 case L1L2ApproximationEnum:8205 return CreatePVectorStressbalanceL1L2();8206 case SIAApproximationEnum:8207 return NULL;8208 case NoneApproximationEnum:8209 return NULL;8210 case FSApproximationEnum:8211 return CreatePVectorStressbalanceFS();8212 case SSAHOApproximationEnum:8213 return CreatePVectorStressbalanceSSAHO();8214 case SSAFSApproximationEnum:8215 return CreatePVectorStressbalanceSSAFS();8216 case HOFSApproximationEnum:8217 return CreatePVectorStressbalanceHOFS();8218 default:8219 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");8220 }8221 }8222 /*}}}*/8223 /*FUNCTION Penta::CreatePVectorStressbalanceSSAHO{{{*/8224 ElementVector* Penta::CreatePVectorStressbalanceSSAHO(void){8225 8226 /*compute all load vectors for this element*/8227 ElementVector* pe1=CreatePVectorStressbalanceSSA();8228 ElementVector* pe2=CreatePVectorStressbalanceHO();8229 ElementVector* pe =new ElementVector(pe1,pe2);8230 8231 /*clean-up and return*/8232 delete pe1;8233 delete pe2;8234 return pe;8235 }8236 /*}}}*/8237 /*FUNCTION Penta::CreatePVectorStressbalanceSSAFS{{{*/8238 ElementVector* Penta::CreatePVectorStressbalanceSSAFS(void){8239 8240 /*compute all load vectors for this element*/8241 int init = this->element_type;8242 this->element_type=P1Enum;8243 ElementVector* pe1=CreatePVectorStressbalanceSSA();8244 this->element_type=init;8245 ElementVector* pe2=CreatePVectorStressbalanceFS();8246 int indices[3]={18,19,20};8247 this->element_type=MINIcondensedEnum;8248 ElementMatrix* Ke = CreateKMatrixStressbalanceFS();8249 this->element_type=init;8250 pe2->StaticCondensation(Ke,3,&indices[0]);8251 delete Ke;8252 ElementVector* pe3=CreatePVectorCouplingSSAFS();8253 ElementVector* pe =new ElementVector(pe1,pe2,pe3);8254 8255 /*clean-up and return*/8256 delete pe1;8257 delete pe2;8258 delete pe3;8259 return pe;8260 }8261 /*}}}*/8262 /*FUNCTION Penta::CreatePVectorStressbalanceHOFS{{{*/8263 ElementVector* Penta::CreatePVectorStressbalanceHOFS(void){8264 8265 /*compute all load vectors for this element*/8266 int init = this->element_type;8267 this->element_type=P1Enum;8268 ElementVector* pe1=CreatePVectorStressbalanceHO();8269 this->element_type=init;8270 ElementVector* pe2=CreatePVectorStressbalanceFS();8271 int indices[3]={18,19,20};8272 this->element_type=MINIcondensedEnum;8273 ElementMatrix* Ke = CreateKMatrixStressbalanceFS();8274 this->element_type=init;8275 pe2->StaticCondensation(Ke,3,&indices[0]);8276 delete Ke;8277 ElementVector* pe3=CreatePVectorCouplingHOFS();8278 ElementVector* pe =new ElementVector(pe1,pe2,pe3);8279 8280 /*clean-up and return*/8281 delete pe1;8282 delete pe2;8283 delete pe3;8284 return pe;8285 }8286 /*}}}*/8287 /*FUNCTION Penta::CreatePVectorStressbalanceSIA{{{*/8288 ElementVector* Penta::CreatePVectorStressbalanceSIA(void){8289 8290 /*Intermediaries*/8291 int i,j;8292 int node0,node1;8293 IssmDouble connectivity[2];8294 IssmDouble Jdet;8295 IssmDouble xyz_list[NUMVERTICES][3];8296 IssmDouble xyz_list_segment[2][3];8297 IssmDouble z_list[NUMVERTICES];8298 IssmDouble slope[2];8299 IssmDouble slope2,constant_part,drag;8300 IssmDouble rho_ice,gravity,n,B;8301 IssmDouble ub,vb,z_g,surface,thickness;8302 GaussPenta* gauss=NULL;8303 8304 /*Fetch number of nodes and dof for this finite element*/8305 int numnodes = this->NumberofNodes(); _assert_(numnodes==6);8306 8307 /*Initialize Element vector*/8308 ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);8309 8310 /*Retrieve all inputs and parameters*/8311 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8312 rho_ice=matpar->GetRhoIce();8313 gravity=matpar->GetG();8314 n=material->GetN();8315 B=material->GetB();8316 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);8317 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);8318 Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);8319 Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);8320 Input* drag_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(drag_input);8321 for(i=0;i<NUMVERTICES;i++)z_list[i]=xyz_list[i][2];8322 8323 /*Loop on the three segments*/8324 for(i=0;i<3;i++){8325 8326 node0=i; node1=i+3;8327 8328 for(j=0;j<3;j++){8329 xyz_list_segment[0][j]=xyz_list[node0][j];8330 xyz_list_segment[1][j]=xyz_list[node1][j];8331 }8332 8333 connectivity[0]=(IssmDouble)vertices[node0]->Connectivity();8334 connectivity[1]=(IssmDouble)vertices[node1]->Connectivity();8335 8336 /*Loop on the Gauss points: */8337 gauss=new GaussPenta(node0,node1,3);8338 for(int ig=gauss->begin();ig<gauss->end();ig++){8339 gauss->GaussPoint(ig);8340 8341 slopex_input->GetInputValue(&slope[0],gauss);8342 slopey_input->GetInputValue(&slope[1],gauss);8343 surface_input->GetInputValue(&surface,gauss);8344 thickness_input->GetInputValue(&thickness,gauss);8345 8346 slope2=pow(slope[0],2)+pow(slope[1],2);8347 constant_part=-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.));8348 8349 PentaRef::GetInputValue(&z_g,&z_list[0],gauss);8350 GetSegmentJacobianDeterminant(&Jdet,&xyz_list_segment[0][0],gauss);8351 8352 if(IsOnSurface()){8353 pe->values[2*node1+0]+=constant_part*pow((surface-z_g)/B,n)*slope[0]*Jdet*gauss->weight/connectivity[1];8354 pe->values[2*node1+1]+=constant_part*pow((surface-z_g)/B,n)*slope[1]*Jdet*gauss->weight/connectivity[1];8355 }8356 else{/*connectivity is too large, should take only half on it*/8357 pe->values[2*node1+0]+=constant_part*pow((surface-z_g)/B,n)*slope[0]*Jdet*gauss->weight*2./connectivity[1];8358 pe->values[2*node1+1]+=constant_part*pow((surface-z_g)/B,n)*slope[1]*Jdet*gauss->weight*2./connectivity[1];8359 }8360 }8361 8362 /*Deal with lower surface*/8363 if(IsOnBed()){8364 drag_input->GetInputValue(&drag,gauss);8365 8366 /*Payne 1995 (m = 1, B = 5e-3/yts = 1.58e-10 m/s/Pa*/8367 ub=-1.58*1.e-10*rho_ice*gravity*thickness*slope[0];8368 vb=-1.58*1.e-10*rho_ice*gravity*thickness*slope[1];8369 ///*Ritz et al. 1996*/8370 //ub=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[0]/sqrt(slope2);8371 //vb=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[1]/sqrt(slope2);8372 ///*Rutt et al. 2009*/8373 //ub=-drag*rho_ice*gravity*thickness*slope[0];8374 //vb=-drag*rho_ice*gravity*thickness*slope[1];8375 8376 pe->values[2*node0+0]+=ub/connectivity[0];8377 pe->values[2*node0+1]+=vb/connectivity[0];8378 }8379 delete gauss;8380 }8381 8382 /*Clean up and return*/8383 return pe;8384 }8385 /*}}}*/8386 /*FUNCTION Penta::CreatePVectorStressbalanceSSA{{{*/8387 ElementVector* Penta::CreatePVectorStressbalanceSSA(void){8388 8389 if (!IsOnBed()) return NULL;8390 8391 /*Call Tria function*/8392 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.8393 ElementVector* pe=tria->CreatePVectorStressbalanceSSA();8394 delete tria->material; delete tria;8395 8396 /*Clean up and return*/8397 return pe;8398 }8399 /*}}}*/8400 /*FUNCTION Penta::CreatePVectorStressbalanceL1L2{{{*/8401 ElementVector* Penta::CreatePVectorStressbalanceL1L2(void){8402 8403 if (!IsOnBed()) return NULL;8404 8405 /*Call Tria function*/8406 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.8407 ElementVector* pe=tria->CreatePVectorStressbalanceSSA();8408 delete tria->material; delete tria;8409 8410 /*Clean up and return*/8411 return pe;8412 }8413 /*}}}*/8414 /*FUNCTION Penta::CreatePVectorStressbalanceHO{{{*/8415 ElementVector* Penta::CreatePVectorStressbalanceHO(void){8416 8417 /*compute all load vectors for this element*/8418 ElementVector* pe1=CreatePVectorStressbalanceHODrivingStress();8419 ElementVector* pe2=CreatePVectorStressbalanceHOFront();8420 ElementVector* pe =new ElementVector(pe1,pe2);8421 8422 /*clean-up and return*/8423 delete pe1;8424 delete pe2;8425 return pe;8426 }8427 /*}}}*/8428 /*FUNCTION Penta::CreatePVectorStressbalanceHODrivingStress{{{*/8429 ElementVector* Penta::CreatePVectorStressbalanceHODrivingStress(void){8430 8431 /*Intermediaries*/8432 IssmDouble Jdet;8433 IssmDouble slope[3]; //do not put 2! this goes into GetInputDerivativeValue, which addresses slope[3] also!8434 IssmDouble driving_stress_baseline,thickness;8435 IssmDouble xyz_list[NUMVERTICES][3];8436 GaussPenta *gauss=NULL;8437 8438 /*Fetch number of nodes and dof for this finite element*/8439 int numnodes = this->NumberofNodes();8440 8441 /*Initialize vector*/8442 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters,HOApproximationEnum);8443 IssmDouble* basis = xNewZeroInit<IssmDouble>(numnodes);8444 8445 /*Retrieve all inputs and parameters*/8446 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8447 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);8448 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);8449 8450 /* Start looping on the number of gaussian points: */8451 gauss=new GaussPenta(3,3);8452 for(int ig=gauss->begin();ig<gauss->end();ig++){8453 8454 gauss->GaussPoint(ig);8455 8456 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8457 GetNodalFunctions(basis,gauss);8458 8459 thickness_input->GetInputValue(&thickness, gauss);8460 surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);8461 8462 driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG();8463 8464 for(int i=0;i<numnodes;i++){8465 pe->values[i*NDOF2+0]+= -driving_stress_baseline*slope[0]*Jdet*gauss->weight*basis[i];8466 pe->values[i*NDOF2+1]+= -driving_stress_baseline*slope[1]*Jdet*gauss->weight*basis[i];8467 }8468 }8469 8470 /*Transform coordinate system*/8471 ::TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);8472 8473 /*Clean up and return*/8474 xDelete<IssmDouble>(basis);8475 delete gauss;8476 return pe;8477 }8478 /*}}}*/8479 /*FUNCTION Penta::CreatePVectorStressbalanceHOFront{{{*/8480 ElementVector* Penta::CreatePVectorStressbalanceHOFront(void){8481 8482 /*If no front, return NULL*/8483 if(!IsZeroLevelset(MaskIceLevelsetEnum)) return NULL;8484 8485 /*Intermediaries*/8486 IssmDouble rho_ice,rho_water,gravity;8487 IssmDouble Jdet,surface,z_g,water_pressure,ice_pressure,air_pressure;8488 IssmDouble surface_under_water,base_under_water,pressure;8489 IssmDouble xyz_list[NUMVERTICES][3];8490 IssmDouble* xyz_list_front = NULL;8491 IssmDouble area_coordinates[4][3];8492 IssmDouble normal[3];8493 GaussPenta* gauss;8494 8495 /*Fetch number of nodes and dof for this finite element*/8496 int numnodes = this->NumberofNodes();8497 8498 /*Initialize Element vector and other vectors*/8499 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8500 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters,HOApproximationEnum);8501 IssmDouble* basis = xNew<IssmDouble>(numnodes);8502 8503 /*Retrieve all inputs and parameters*/8504 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);8505 rho_water=matpar->GetRhoWater();8506 rho_ice =matpar->GetRhoIce();8507 gravity =matpar->GetG();8508 ZeroLevelsetCoordinates(&xyz_list_front,&xyz_list[0][0],MaskIceLevelsetEnum);8509 GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,&xyz_list[0][0],4);8510 NormalSection(&normal[0],xyz_list_front);8511 8512 /*Initialize gauss points*/8513 IssmDouble zmax=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];8514 IssmDouble zmin=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];8515 if(zmax>0 && zmin<0) gauss=new GaussPenta(area_coordinates,3,10); //refined in vertical because of the sea level discontinuity8516 else gauss=new GaussPenta(area_coordinates,3,3);8517 8518 /* Start looping on the number of gaussian points: */8519 for(int ig=gauss->begin();ig<gauss->end();ig++){8520 8521 gauss->GaussPoint(ig);8522 surface_input->GetInputValue(&surface,gauss);8523 z_g=GetZcoord(gauss);8524 GetNodalFunctions(basis,gauss);8525 GetQuadJacobianDeterminant(&Jdet,xyz_list_front,gauss);8526 8527 water_pressure = rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level8528 ice_pressure = rho_ice*gravity*(surface-z_g);8529 air_pressure = 0;8530 pressure = ice_pressure + water_pressure + air_pressure;8531 8532 for (int i=0;i<numnodes;i++){8533 pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];8534 pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];8535 }8536 }8537 8538 /*Transform coordinate system*/8539 ::TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);8540 8541 /*Clean up and return*/8542 xDelete<IssmDouble>(basis);8543 xDelete<IssmDouble>(xyz_list_front);8544 delete gauss;8545 return pe;8546 }8547 /*}}}*/8548 /*FUNCTION Penta::CreatePVectorStressbalanceFS {{{*/8549 ElementVector* Penta::CreatePVectorStressbalanceFS(void){8550 8551 ElementVector* pe1;8552 ElementVector* pe2;8553 ElementVector* pe3;8554 ElementVector* pe;8555 8556 /*compute all stiffness matrices for this element*/8557 pe1=CreatePVectorStressbalanceFSViscous();8558 pe2=CreatePVectorStressbalanceFSShelf();8559 pe3=CreatePVectorStressbalanceFSFront();8560 pe =new ElementVector(pe1,pe2,pe3);8561 8562 /*clean-up and return*/8563 delete pe1;8564 delete pe2;8565 delete pe3;8566 return pe;8567 }8568 /*}}}*/8569 /*FUNCTION Penta::CreatePVectorStressbalanceFSFront{{{*/8570 ElementVector* Penta::CreatePVectorStressbalanceFSFront(void){8571 8572 /*If no front, return NULL*/8573 if(!IsZeroLevelset(MaskIceLevelsetEnum)) return NULL;8574 8575 /*Fetch number of nodes and dof for this finite element*/8576 int i;8577 IssmDouble rho_ice,rho_water,gravity;8578 IssmDouble Jdet,z_g,water_pressure,air_pressure;8579 IssmDouble surface_under_water,base_under_water,pressure;8580 IssmDouble xyz_list[NUMVERTICES][3];8581 IssmDouble* xyz_list_front = NULL;8582 IssmDouble area_coordinates[4][3];8583 IssmDouble normal[3];8584 GaussPenta* gauss;8585 8586 /*Fetch number of nodes and dof for this finite element*/8587 int vnumnodes = this->NumberofNodesVelocity();8588 int pnumnodes = this->NumberofNodesPressure();8589 8590 /*Prepare coordinate system list*/8591 int* cs_list = xNew<int>(vnumnodes+pnumnodes);8592 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;8593 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;8594 8595 /*Initialize Element matrix and vectors*/8596 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8597 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);8598 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);8599 8600 /*Retrieve all inputs and parameters*/8601 rho_water=matpar->GetRhoWater();8602 rho_ice =matpar->GetRhoIce();8603 gravity =matpar->GetG();8604 ZeroLevelsetCoordinates(&xyz_list_front,&xyz_list[0][0],MaskIceLevelsetEnum);8605 GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,&xyz_list[0][0],4);8606 NormalSection(&normal[0],xyz_list_front);8607 8608 /*Start looping on Gaussian points*/8609 IssmDouble zmax=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];8610 IssmDouble zmin=xyz_list[0][2]; for(int i=1;i<6;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];8611 if(zmax>0 && zmin<0) gauss=new GaussPenta(area_coordinates,3,30); //refined in vertical because of the sea level discontinuity8612 else gauss=new GaussPenta(area_coordinates,3,3);8613 8614 for(int ig=gauss->begin();ig<gauss->end();ig++){8615 8616 gauss->GaussPoint(ig);8617 z_g=GetZcoord(gauss);8618 GetNodalFunctionsVelocity(vbasis,gauss);8619 GetQuadJacobianDeterminant(&Jdet,xyz_list_front,gauss);8620 8621 water_pressure=rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level8622 air_pressure=0;8623 pressure = water_pressure + air_pressure;8624 8625 for(i=0;i<vnumnodes;i++){8626 pe->values[3*i+0]+= pressure*Jdet*gauss->weight*normal[0]*vbasis[i];8627 pe->values[3*i+1]+= pressure*Jdet*gauss->weight*normal[1]*vbasis[i];8628 pe->values[3*i+2]+= pressure*Jdet*gauss->weight*normal[2]*vbasis[i];8629 }8630 }8631 8632 /*Transform coordinate system*/8633 ::TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);8634 8635 /*Clean up and return*/8636 xDelete<int>(cs_list);8637 xDelete<IssmDouble>(xyz_list_front);8638 xDelete<IssmDouble>(vbasis);8639 delete gauss;8640 return pe;8641 }8642 /*}}}*/8643 /*FUNCTION Penta::PVectorGLSstabilization{{{*/8644 void Penta::PVectorGLSstabilization(ElementVector* pe){8645 8646 /*Intermediaries*/8647 int i,j;8648 IssmDouble Jdet,gravity,rho_ice,B,D_scalar_stab,viscosity;8649 IssmDouble forcex,forcey,forcez,diameter,FSreconditioning;8650 IssmDouble xyz_list[NUMVERTICES][3];8651 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/8652 GaussPenta *gauss=NULL;8653 8654 /*Stabilization*/8655 IssmDouble dbasis[3][6];8656 IssmDouble dmu[3];8657 IssmDouble mu;8658 IssmDouble dnodalbasis[6][6][3];8659 IssmDouble SW[6][4][4];8660 int p,ii;8661 int c=3; //index of pressure8662 8663 /*Retrieve all inputs and parameters*/8664 rho_ice=matpar->GetRhoIce();8665 gravity=matpar->GetG();8666 B=material->GetB();8667 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8668 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8669 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8670 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);8671 8672 /*Find minimal length*/8673 diameter=MinEdgeLength(&xyz_list[0][0]);8674 8675 gauss=new GaussPenta();8676 for(int iv=0;iv<6;iv++){8677 gauss->GaussVertex(iv);8678 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);8679 for(i=0;i<6;i++){8680 for(j=0;j<3;j++){8681 dnodalbasis[i][iv][j] = dbasis[j][i];8682 }8683 }8684 }8685 delete gauss;8686 8687 /* Start looping on the number of gaussian points: */8688 gauss=new GaussPenta(5,5);8689 for(int ig=gauss->begin();ig<gauss->end();ig++){8690 8691 gauss->GaussPoint(ig);8692 8693 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8694 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);8695 material->GetViscosity3dFS(&viscosity,&epsilon[0]);8696 8697 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0],gauss);8698 dmu[0]=0.; dmu[1]=0.; dmu[2]=0.;8699 mu = 2.*viscosity;8700 for(p=0;p<6;p++) for(i=0;i<4;i++) for(j=0;j<4;j++){8701 SW[p][i][j]=0.;8702 }8703 for(p=0;p<6;p++){8704 for(i=0;i<3;i++){8705 SW[p][c][i] += dbasis[i][p];8706 for(j=0;j<3;j++){8707 SW[p][i][i] += -dmu[j]*dbasis[j][p];8708 SW[p][j][i] += -dmu[j]*dbasis[i][p];8709 for(ii=0;ii<6;ii++){8710 SW[p][i][i] += -mu*dnodalbasis[p][ii][j]*dbasis[j][ii];8711 SW[p][j][i] += -mu*dnodalbasis[p][ii][i]*dbasis[j][ii];8712 }8713 }8714 }8715 }8716 IssmDouble tau = 1./3.*pow(diameter,2)/(8.*2.*viscosity);8717 for(p=0;p<6;p++){8718 for(j=0;j<4;j++){8719 pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*forcex*SW[p][j][0];8720 pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*forcey*SW[p][j][1];8721 pe->values[p*4+j] += gauss->weight*Jdet*tau*rho_ice*(forcez-gravity)*SW[p][j][2];8722 }8723 }8724 }8725 8726 /*Clean up*/8727 delete gauss;8728 }8729 /*}}}*/8730 /*FUNCTION Penta::CreatePVectorStressbalanceFSViscous {{{*/8731 ElementVector* Penta::CreatePVectorStressbalanceFSViscous(void){8732 8733 /*Intermediaries*/8734 int i;8735 int approximation;8736 IssmDouble Jdet,gravity,rho_ice;8737 IssmDouble forcex,forcey,forcez;8738 IssmDouble xyz_list[NUMVERTICES][3];8739 GaussPenta *gauss=NULL;8740 8741 /*Initialize Element vector and return if necessary*/8742 inputs->GetInputValue(&approximation,ApproximationEnum);8743 if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;8744 8745 /*Fetch number of nodes and dof for this finite element*/8746 int vnumnodes = this->NumberofNodesVelocity();8747 int pnumnodes = this->NumberofNodesPressure();8748 8749 /*Prepare coordinate system list*/8750 int* cs_list = xNew<int>(vnumnodes+pnumnodes);8751 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;8752 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;8753 8754 /*Initialize Element matrix and vectors*/8755 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);8756 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);8757 8758 /*Retrieve all inputs and parameters*/8759 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8760 Input* loadingforcex_input=inputs->GetInput(LoadingforceXEnum); _assert_(loadingforcex_input);8761 Input* loadingforcey_input=inputs->GetInput(LoadingforceYEnum); _assert_(loadingforcey_input);8762 Input* loadingforcez_input=inputs->GetInput(LoadingforceZEnum); _assert_(loadingforcez_input);8763 rho_ice = matpar->GetRhoIce();8764 gravity = matpar->GetG();8765 8766 /* Start looping on the number of gaussian points: */8767 gauss=new GaussPenta(5,5);8768 for(int ig=gauss->begin();ig<gauss->end();ig++){8769 8770 gauss->GaussPoint(ig);8771 8772 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8773 GetNodalFunctionsVelocity(vbasis, gauss);8774 8775 loadingforcex_input->GetInputValue(&forcex,gauss);8776 loadingforcey_input->GetInputValue(&forcey,gauss);8777 loadingforcez_input->GetInputValue(&forcez,gauss);8778 8779 for(i=0;i<vnumnodes;i++){8780 pe->values[i*NDOF3+2] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];8781 pe->values[i*NDOF3+0] += +rho_ice*forcex *Jdet*gauss->weight*vbasis[i];8782 pe->values[i*NDOF3+1] += +rho_ice*forcey *Jdet*gauss->weight*vbasis[i];8783 pe->values[i*NDOF3+2] += +rho_ice*forcez *Jdet*gauss->weight*vbasis[i];8784 }8785 }8786 8787 /*Transform coordinate system*/8788 ::TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);8789 8790 /*Clean up and return*/8791 delete gauss;8792 xDelete<int>(cs_list);8793 xDelete<IssmDouble>(vbasis);8794 return pe;8795 }8796 /*}}}*/8797 /*FUNCTION Penta::CreatePVectorStressbalanceFSShelf{{{*/8798 ElementVector* Penta::CreatePVectorStressbalanceFSShelf(void){8799 8800 /*Intermediaries*/8801 int i,j;8802 int approximation,shelf_dampening;8803 IssmDouble gravity,rho_water,bed,water_pressure;8804 IssmDouble damper,normal_vel,vx,vy,vz,dt;8805 IssmDouble xyz_list_tria[NUMVERTICES2D][3];8806 IssmDouble xyz_list[NUMVERTICES][3];8807 IssmDouble bed_normal[3];8808 IssmDouble dz[3];8809 IssmDouble Jdet2d;8810 GaussPenta *gauss=NULL;8811 8812 /*Initialize Element vector and return if necessary*/8813 if(!IsOnBed() || !IsFloating()) return NULL;8814 inputs->GetInputValue(&approximation,ApproximationEnum);8815 if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;8816 8817 /*Fetch number of nodes and dof for this finite element*/8818 int vnumnodes = this->NumberofNodesVelocity();8819 int pnumnodes = this->NumberofNodesPressure();8820 8821 /*Prepare coordinate system list*/8822 int* cs_list = xNew<int>(vnumnodes+pnumnodes);8823 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;8824 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;8825 8826 /*Initialize Element matrix and vectors*/8827 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);8828 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);8829 8830 /*Retrieve all inputs and parameters*/8831 this->parameters->FindParam(&shelf_dampening,StressbalanceShelfDampeningEnum);8832 rho_water=matpar->GetRhoWater();8833 gravity=matpar->GetG();8834 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8835 Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);8836 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8837 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8838 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);8839 8840 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];8841 8842 /* Start looping on the number of gauss 2d (nodes on the bedrock) */8843 gauss=new GaussPenta(0,1,2,5);8844 for(int ig=gauss->begin();ig<gauss->end();ig++){8845 8846 gauss->GaussPoint(ig);8847 8848 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);8849 GetNodalFunctionsVelocity(vbasis, gauss);8850 8851 NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);8852 bed_input->GetInputValue(&bed, gauss);8853 if(shelf_dampening){ //add dampening to avoid too high vertical velocities when not in hydrostatic equilibrium8854 bed_input->GetInputDerivativeValue(&dz[0],&xyz_list[0][0],gauss);8855 vx_input->GetInputValue(&vx, gauss);8856 vy_input->GetInputValue(&vy, gauss);8857 vz_input->GetInputValue(&vz, gauss);8858 dt=0.;8859 normal_vel=bed_normal[0]*vx+bed_normal[1]*vy+bed_normal[2]*vz;8860 damper=gravity*rho_water*pow(1+pow(dz[0],2)+pow(dz[1],2),0.5)*normal_vel*dt;8861 }8862 else damper=0.;8863 water_pressure=gravity*rho_water*bed;8864 8865 for(i=0;i<vnumnodes;i++){8866 pe->values[3*i+0]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[0];8867 pe->values[3*i+1]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[1];8868 pe->values[3*i+2]+=(water_pressure+damper)*gauss->weight*Jdet2d*vbasis[i]*bed_normal[2];8869 }8870 }8871 8872 /*Transform coordinate system*/8873 ::TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);8874 8875 /*Clean up and return*/8876 delete gauss;8877 xDelete<int>(cs_list);8878 xDelete<IssmDouble>(vbasis);8879 return pe;8880 }8881 /*}}}*/8882 /*FUNCTION Penta::CreatePVectorStressbalanceVert {{{*/8883 ElementVector* Penta::CreatePVectorStressbalanceVert(void){8884 8885 /*compute all load vectors for this element*/8886 ElementVector* pe1=CreatePVectorStressbalanceVertVolume();8887 ElementVector* pe2=CreatePVectorStressbalanceVertBase();8888 ElementVector* pe =new ElementVector(pe1,pe2);8889 8890 /*clean-up and return*/8891 delete pe1;8892 delete pe2;8893 return pe;8894 }8895 /*}}}*/8896 /*FUNCTION Penta::CreatePVectorStressbalanceVertVolume {{{*/8897 ElementVector* Penta::CreatePVectorStressbalanceVertVolume(void){8898 8899 /*Constants*/8900 const int numdof=NDOF1*NUMVERTICES;8901 8902 /*Intermediaries*/8903 int approximation;8904 IssmDouble Jdet;8905 IssmDouble xyz_list[NUMVERTICES][3];8906 IssmDouble dudx,dvdy,dwdz;8907 IssmDouble du[3],dv[3],dw[3];8908 IssmDouble basis[6];8909 GaussPenta *gauss=NULL;8910 8911 /*Initialize Element vector*/8912 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);8913 8914 /*Retrieve all inputs and parameters*/8915 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8916 inputs->GetInputValue(&approximation,ApproximationEnum);8917 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8918 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8919 Input* vzFS_input=NULL;8920 if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){8921 vzFS_input=inputs->GetInput(VzFSEnum); _assert_(vzFS_input);8922 }8923 8924 /* Start looping on the number of gaussian points: */8925 gauss=new GaussPenta(2,2);8926 for(int ig=gauss->begin();ig<gauss->end();ig++){8927 8928 gauss->GaussPoint(ig);8929 8930 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8931 GetNodalFunctionsP1(basis, gauss);8932 8933 vx_input->GetInputDerivativeValue(&du[0],&xyz_list[0][0],gauss);8934 vy_input->GetInputDerivativeValue(&dv[0],&xyz_list[0][0],gauss);8935 if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){8936 vzFS_input->GetInputDerivativeValue(&dw[0],&xyz_list[0][0],gauss);8937 dwdz=dw[2];8938 }8939 else dwdz=0;8940 dudx=du[0];8941 dvdy=dv[1];8942 8943 for(int i=0;i<numdof;i++) pe->values[i] += (dudx+dvdy+dwdz)*Jdet*gauss->weight*basis[i];8944 }8945 8946 /*Clean up and return*/8947 delete gauss;8948 return pe;8949 }8950 /*}}}*/8951 /*FUNCTION Penta::CreatePVectorStressbalanceVertBase {{{*/8952 ElementVector* Penta::CreatePVectorStressbalanceVertBase(void){8953 8954 /*Constants*/8955 const int numdof=NDOF1*NUMVERTICES;8956 8957 /*Intermediaries */8958 int i,j;8959 int approximation;8960 IssmDouble xyz_list[NUMVERTICES][3];8961 IssmDouble xyz_list_tria[NUMVERTICES2D][3];8962 IssmDouble Jdet2d;8963 IssmDouble vx,vy,vz,dbdx,dbdy,basalmeltingvalue;8964 IssmDouble slope[3];8965 IssmDouble basis[NUMVERTICES];8966 GaussPenta* gauss=NULL;8967 8968 if (!IsOnBed()) return NULL;8969 8970 /*Initialize Element vector*/8971 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);8972 8973 /*Retrieve all inputs and parameters*/8974 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8975 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];8976 inputs->GetInputValue(&approximation,ApproximationEnum);8977 Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);8978 Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);8979 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);8980 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);8981 Input* vzFS_input=NULL;8982 if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){8983 vzFS_input=inputs->GetInput(VzFSEnum); _assert_(vzFS_input);8984 }8985 8986 /* Start looping on the number of gaussian points: */8987 gauss=new GaussPenta(0,1,2,2);8988 for(int ig=gauss->begin();ig<gauss->end();ig++){8989 8990 gauss->GaussPoint(ig);8991 8992 basal_melting_input->GetInputValue(&basalmeltingvalue, gauss);8993 bed_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);8994 vx_input->GetInputValue(&vx, gauss);8995 vy_input->GetInputValue(&vy, gauss);8996 if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){8997 vzFS_input->GetInputValue(&vz, gauss);8998 }8999 else vz=0;9000 9001 dbdx=slope[0];9002 dbdy=slope[1];9003 9004 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);9005 GetNodalFunctionsP1(&basis[0], gauss);9006 9007 for(i=0;i<numdof;i++) pe->values[i]+=-Jdet2d*gauss->weight*(vx*dbdx+vy*dbdy-vz-basalmeltingvalue)*basis[i];9008 }9009 9010 /*Clean up and return*/9011 delete gauss;9012 return pe;9013 }9014 /*}}}*/9015 6803 /*FUNCTION Penta::CreateJacobianStressbalanceHoriz{{{*/ 9016 6804 ElementMatrix* Penta::CreateJacobianStressbalanceHoriz(void){ … … 9246 7034 } 9247 7035 /*}}}*/ 9248 /*FUNCTION Penta::CreatePVectorBalancethickness {{{*/9249 ElementVector* Penta::CreatePVectorBalancethickness(void){9250 9251 if (!IsOnBed()) return NULL;9252 9253 /*Depth Averaging Vx and Vy*/9254 this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);9255 this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);9256 9257 /*Call Tria function*/9258 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.9259 ElementVector* pe=tria->CreatePVectorBalancethickness();9260 delete tria->material; delete tria;9261 9262 /*Delete Vx and Vy averaged*/9263 this->inputs->DeleteInput(VxAverageEnum);9264 this->inputs->DeleteInput(VyAverageEnum);9265 9266 /*Clean up and return*/9267 return pe;9268 }9269 /*}}}*/9270 7036 #endif 9271 7037 … … 9308 7074 /*clean up and return*/ 9309 7075 return Ke; 9310 }9311 /*}}}*/9312 /*FUNCTION Penta::CreatePVectorHydrologyDCInefficient {{{*/9313 ElementVector* Penta::CreatePVectorHydrologyDCInefficient(void){9314 9315 if (!IsOnBed()) return NULL;9316 9317 /*Call Tria function*/9318 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.9319 ElementVector* pe=tria->CreatePVectorHydrologyDCInefficient();9320 delete tria->material; delete tria;9321 9322 /*Clean up and return*/9323 return pe;9324 }9325 /*}}}*/9326 /*FUNCTION Penta::CreatePVectorHydrologyDCEfficient {{{*/9327 ElementVector* Penta::CreatePVectorHydrologyDCEfficient(void){9328 9329 if (!IsOnBed()) return NULL;9330 9331 /*Call Tria function*/9332 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.9333 ElementVector* pe=tria->CreatePVectorHydrologyDCEfficient();9334 delete tria->material; delete tria;9335 9336 /*Clean up and return*/9337 return pe;9338 }9339 /*}}}*/9340 /*FUNCTION Penta::CreatePVectorL@ProjectionEPL {{{*/9341 ElementVector* Penta::CreatePVectorL2ProjectionEPL(void){9342 9343 if (!IsOnBed()) return NULL;9344 9345 /*Call Tria function*/9346 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.9347 ElementVector* pe=tria->CreatePVectorL2ProjectionEPL();9348 delete tria->material; delete tria;9349 9350 /*Clean up and return*/9351 return pe;9352 7076 } 9353 7077 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r16956 r16982 199 199 ElementMatrix* CreateKMatrixFreeSurfaceTop(void); 200 200 ElementMatrix* CreateKMatrixFreeSurfaceBase(void); 201 ElementVector* CreatePVector(void);202 ElementVector* CreatePVectorMasstransport(void);203 ElementVector* CreatePVectorFreeSurfaceTop(void);204 ElementVector* CreatePVectorFreeSurfaceBase(void);205 ElementVector* CreatePVectorL2ProjectionBase(void);206 201 IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure); 207 202 IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure); … … 301 296 ElementMatrix* CreateJacobianStressbalanceHO(void); 302 297 ElementMatrix* CreateJacobianStressbalanceFS(void); 303 ElementVector* CreatePVectorCouplingSSAFS(void);304 ElementVector* CreatePVectorCouplingSSAFSViscous(void);305 ElementVector* CreatePVectorCouplingSSAFSFriction(void);306 ElementVector* CreatePVectorCouplingHOFS(void);307 ElementVector* CreatePVectorCouplingHOFSViscous(void);308 ElementVector* CreatePVectorCouplingHOFSFriction(void);309 ElementVector* CreatePVectorStressbalanceHoriz(void);310 ElementVector* CreatePVectorStressbalanceSIA(void);311 ElementVector* CreatePVectorStressbalanceSSA(void);312 ElementVector* CreatePVectorStressbalanceSSAHO(void);313 ElementVector* CreatePVectorStressbalanceSSAFS(void);314 ElementVector* CreatePVectorStressbalanceL1L2(void);315 ElementVector* CreatePVectorStressbalanceHO(void);316 ElementVector* CreatePVectorStressbalanceHODrivingStress(void);317 ElementVector* CreatePVectorStressbalanceHOFront(void);318 ElementVector* CreatePVectorStressbalanceHOFS(void);319 ElementVector* CreatePVectorStressbalanceFS(void);320 ElementVector* CreatePVectorStressbalanceFSFront(void);321 ElementVector* CreatePVectorStressbalanceFSViscous(void);322 void PVectorGLSstabilization(ElementVector* pe);323 ElementVector* CreatePVectorStressbalanceFSShelf(void);324 ElementVector* CreatePVectorStressbalanceVert(void);325 ElementVector* CreatePVectorStressbalanceVertVolume(void);326 ElementVector* CreatePVectorStressbalanceVertBase(void);327 298 #endif 328 299 329 300 #ifdef _HAVE_CONTROL_ 330 ElementVector* CreatePVectorAdjointHoriz(void);331 301 ElementMatrix* CreateKMatrixAdjointSSA2d(void); 332 302 ElementMatrix* CreateKMatrixAdjointHO(void); 333 303 ElementMatrix* CreateKMatrixAdjointFS(void); 334 ElementVector* CreatePVectorAdjointSSA(void);335 ElementVector* CreatePVectorAdjointHO(void);336 ElementVector* CreatePVectorAdjointFS(void);337 304 #endif 338 305 … … 341 308 ElementMatrix* CreateKMatrixHydrologyDCEfficient(void); 342 309 ElementMatrix* CreateEPLDomainMassMatrix(void); 343 ElementVector* CreatePVectorHydrologyDCInefficient(void);344 ElementVector* CreatePVectorHydrologyDCEfficient(void);345 ElementVector* CreatePVectorL2ProjectionEPL(void);346 310 void GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode); 347 311 void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,int index){_error_("not implemented yet");}; … … 362 326 ElementMatrix* CreateKMatrixThermalVolume(void); 363 327 ElementMatrix* CreateKMatrixThermalShelf(void); 364 ElementVector* CreatePVectorEnthalpy(void);365 ElementVector* CreatePVectorEnthalpyVolume(void);366 ElementVector* CreatePVectorEnthalpyShelf(void);367 ElementVector* CreatePVectorEnthalpySheet(void);368 ElementVector* CreatePVectorMelting(void);369 ElementVector* CreatePVectorThermal(void);370 ElementVector* CreatePVectorThermalVolume(void);371 ElementVector* CreatePVectorThermalShelf(void);372 ElementVector* CreatePVectorThermalSheet(void);373 328 void UpdateBasalConstraintsEnthalpy(void); 374 329 void ComputeBasalMeltingrate(void); … … 378 333 #ifdef _HAVE_BALANCED_ 379 334 ElementMatrix* CreateKMatrixBalancethickness(void); 380 ElementVector* CreatePVectorBalancethickness(void);381 335 #endif 382 336 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Seg.cpp
r16913 r16982 333 333 } 334 334 /*}}}*/ 335 /*FUNCTION Seg::CreatePVectorL2Projection {{{*/336 ElementVector* Seg::CreatePVectorL2Projection(void){337 338 /*Intermediaries */339 int i,input_enum;340 IssmDouble Jdet;341 IssmDouble xyz_list[NUMVERTICES][3];342 IssmDouble value;343 Input* input = NULL;344 Input* input2 = NULL;345 346 /*Fetch number of nodes and dof for this finite element*/347 int numnodes = this->NumberofNodes();348 349 /*Initialize Element vector*/350 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);351 IssmDouble* basis = xNew<IssmDouble>(numnodes);352 353 /*Retrieve all inputs and parameters*/354 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);355 this->parameters->FindParam(&input_enum,InputToL2ProjectEnum);356 switch(input_enum){357 case SurfaceSlopeXEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;358 case BedSlopeXEnum: input2 = inputs->GetInput(BedEnum); _assert_(input2); break;359 default: input = inputs->GetInput(input_enum);360 }361 362 /* Start looping on the number of gaussian points: */363 GaussSeg* gauss=new GaussSeg(2);364 for(int ig=gauss->begin();ig<gauss->end();ig++){365 366 gauss->GaussPoint(ig);367 368 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);369 GetNodalFunctions(basis,gauss);370 371 if(input2){372 input2->GetInputDerivativeValue(&value,&xyz_list[0][0],gauss);373 }374 else{375 input->GetInputValue(&value,gauss);376 }377 378 for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];379 }380 381 /*Clean up and return*/382 xDelete<IssmDouble>(basis);383 delete gauss;384 return pe;385 }386 /*}}}*/387 /*FUNCTION Seg::CreatePVectorFreeSurfaceTop {{{*/388 ElementVector* Seg::CreatePVectorFreeSurfaceTop(void){389 390 /*Intermediaries */391 IssmDouble Jdet,dt;392 IssmDouble ms,surface,vy;393 IssmDouble xyz_list[NUMVERTICES][3];394 395 /*Fetch number of nodes and dof for this finite element*/396 int numnodes = this->NumberofNodes();397 398 /*Initialize Element vector and other vectors*/399 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);400 IssmDouble* basis = xNew<IssmDouble>(numnodes);401 402 /*Retrieve all inputs and parameters*/403 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);404 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);405 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input);406 Input* ms_input = inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);407 Input* surface_input= inputs->GetInput(SurfaceEnum); _assert_(surface_input);408 409 /*Initialize mb_correction to 0, do not forget!:*/410 /* Start looping on the number of gaussian points: */411 GaussSeg* gauss=new GaussSeg(2);412 for(int ig=gauss->begin();ig<gauss->end();ig++){413 414 gauss->GaussPoint(ig);415 416 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);417 GetNodalFunctions(basis,gauss);418 419 vy_input->GetInputValue(&vy,gauss);420 ms_input->GetInputValue(&ms,gauss);421 surface_input->GetInputValue(&surface,gauss);422 423 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(surface + dt*ms + dt*vy)*basis[i];424 }425 426 /*Clean up and return*/427 xDelete<IssmDouble>(basis);428 delete gauss;429 return pe;430 }431 /*}}}*/432 /*FUNCTION Seg::CreatePVectorFreeSurfaceBase {{{*/433 ElementVector* Seg::CreatePVectorFreeSurfaceBase(void){434 435 /*Intermediaries */436 IssmDouble Jdet,dt;437 IssmDouble mb,mb_correction,bed,vy;438 IssmDouble xyz_list[NUMVERTICES][3];439 440 /*Fetch number of nodes and dof for this finite element*/441 int numnodes = this->NumberofNodes();442 443 /*Initialize Element vector and other vectors*/444 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);445 IssmDouble* basis = xNew<IssmDouble>(numnodes);446 447 /*Retrieve all inputs and parameters*/448 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);449 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);450 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input);451 Input* mb_input = inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);452 Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);453 Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input);454 455 /*Initialize mb_correction to 0, do not forget!:*/456 /* Start looping on the number of gaussian points: */457 GaussSeg* gauss=new GaussSeg(2);458 for(int ig=gauss->begin();ig<gauss->end();ig++){459 460 gauss->GaussPoint(ig);461 462 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);463 GetNodalFunctions(basis,gauss);464 465 vy_input->GetInputValue(&vy,gauss);466 mb_input->GetInputValue(&mb,gauss);467 bed_input->GetInputValue(&bed,gauss);468 if(mb_correction_input)469 mb_correction_input->GetInputValue(&mb_correction,gauss);470 else471 mb_correction=0.;472 473 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(bed+dt*(mb-mb_correction) + dt*vy)*basis[i];474 }475 476 /*Clean up and return*/477 xDelete<IssmDouble>(basis);478 delete gauss;479 return pe;480 }481 /*}}}*/482 335 /*FUNCTION Seg::GetNumberOfNodes;{{{*/ 483 336 int Seg::GetNumberOfNodes(void){ -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r16956 r16982 71 71 ElementMatrix* CreateKMatrix(void){_error_("not implemented yet");}; 72 72 void CreateDVector(Vector<IssmDouble>* df){_error_("not implemented yet");}; 73 ElementVector* CreatePVector(void){_error_("not implemented yet");};74 ElementVector* CreatePVectorL2Projection(void);75 73 void CreateJacobianMatrix(Matrix<IssmDouble>* Jff){_error_("not implemented yet");}; 76 74 void Delta18oParameterization(void){_error_("not implemented yet");}; … … 262 260 ElementMatrix* CreateKMatrixFreeSurfaceTop(void); 263 261 ElementMatrix* CreateKMatrixFreeSurfaceBase(void); 264 ElementVector* CreatePVectorFreeSurfaceTop(void);265 ElementVector* CreatePVectorFreeSurfaceBase(void);266 262 IssmDouble GetSize(void); 267 263 }; -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r16974 r16982 374 374 } 375 375 /*}}}*/ 376 /*FUNCTION Tria::CreatePVector(void){{{*/377 ElementVector* Tria::CreatePVector(void){378 379 /*retrive parameters: */380 int meshtype;381 int analysis_type;382 parameters->FindParam(&analysis_type,AnalysisTypeEnum);383 384 /*asserts: {{{*/385 /*if debugging mode, check that all pointers exist*/386 _assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);387 /*}}}*/388 389 /*Skip if water element*/390 if(NoIceInElement()) return NULL;391 392 /*Just branch to the correct load generator, according to the type of analysis we are carrying out: */393 switch(analysis_type){394 #ifdef _HAVE_STRESSBALANCE_395 case StressbalanceAnalysisEnum:396 int approximation;397 inputs->GetInputValue(&approximation,ApproximationEnum);398 switch(approximation){399 case SSAApproximationEnum:400 return CreatePVectorStressbalanceSSA();401 case FSApproximationEnum:402 return CreatePVectorStressbalanceFS();403 case SIAApproximationEnum:404 return NULL;405 case NoneApproximationEnum:406 return NULL;407 default:408 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");409 }410 break;411 case StressbalanceSIAAnalysisEnum:412 return CreatePVectorStressbalanceSIA();413 break;414 #endif415 #ifdef _HAVE_DAMAGE_416 case DamageEvolutionAnalysisEnum:417 return CreatePVectorDamageEvolution();418 break;419 #endif420 case L2ProjectionBaseAnalysisEnum:421 parameters->FindParam(&meshtype,MeshTypeEnum);422 if(meshtype==Mesh2DverticalEnum){423 return CreatePVectorL2ProjectionBase();424 }425 else{426 return CreatePVectorL2Projection();427 }428 break;429 #ifdef _HAVE_MASSTRANSPORT_430 case MasstransportAnalysisEnum:431 return CreatePVectorMasstransport();432 break;433 case FreeSurfaceTopAnalysisEnum:434 parameters->FindParam(&meshtype,MeshTypeEnum);435 switch(meshtype){436 case Mesh2DverticalEnum:437 return CreatePVectorFreeSurfaceTop1D();438 case Mesh3DEnum:439 return CreatePVectorFreeSurfaceTop();440 default:441 _error_("Mesh not supported yet");442 }443 break;444 case FreeSurfaceBaseAnalysisEnum:445 parameters->FindParam(&meshtype,MeshTypeEnum);446 switch(meshtype){447 case Mesh2DverticalEnum:448 return CreatePVectorFreeSurfaceBase1D();449 case Mesh3DEnum:450 return CreatePVectorFreeSurfaceBase();451 default:452 _error_("Mesh not supported yet");453 }454 break;455 case ExtrudeFromBaseAnalysisEnum: case ExtrudeFromTopAnalysisEnum:456 return NULL;457 break;458 #endif459 #ifdef _HAVE_HYDROLOGY_460 case HydrologyShreveAnalysisEnum:461 return CreatePVectorHydrologyShreve();462 break;463 case HydrologyDCInefficientAnalysisEnum:464 return CreatePVectorHydrologyDCInefficient();465 break;466 case HydrologyDCEfficientAnalysisEnum:467 return CreatePVectorHydrologyDCEfficient();468 break;469 case L2ProjectionEPLAnalysisEnum:470 return CreatePVectorL2ProjectionEPL();471 break;472 #endif473 #ifdef _HAVE_BALANCED_474 case BalancethicknessAnalysisEnum:475 return CreatePVectorBalancethickness();476 break;477 case BalancevelocityAnalysisEnum:478 return CreatePVectorBalancevelocity();479 break;480 case SmoothedSurfaceSlopeXAnalysisEnum:481 return CreatePVectorSmoothedSlopeX();482 break;483 case SmoothedSurfaceSlopeYAnalysisEnum:484 return CreatePVectorSmoothedSlopeY();485 break;486 #endif487 #ifdef _HAVE_CONTROL_488 case AdjointBalancethicknessAnalysisEnum:489 return CreatePVectorAdjointBalancethickness();490 break;491 case AdjointHorizAnalysisEnum:492 return CreatePVectorAdjointHoriz();493 break;494 #endif495 default:496 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");497 }498 499 /*make compiler happy*/500 return NULL;501 }502 /*}}}*/503 /*FUNCTION Tria::CreatePVectorL2ProjectionBase{{{*/504 ElementVector* Tria::CreatePVectorL2ProjectionBase(void){505 506 if(!HasEdgeOnBed()) return NULL;507 508 int index1,index2;509 this->EdgeOnBedIndices(&index1,&index2);510 511 Seg* seg=(Seg*)SpawnSeg(index1,index2);512 ElementVector* pe=seg->CreatePVectorL2Projection();513 delete seg->material; delete seg;514 515 /*clean up and return*/516 return pe;517 }518 /*}}}*/519 /*FUNCTION Tria::CreatePVectorL2Projection {{{*/520 ElementVector* Tria::CreatePVectorL2Projection(void){521 522 /*Intermediaries */523 int i,input_enum;524 IssmDouble Jdet,value;525 IssmDouble xyz_list[NUMVERTICES][3];526 IssmDouble slopes[2];527 Input* input = NULL;528 Input* input2 = NULL;529 530 /*Fetch number of nodes and dof for this finite element*/531 int numnodes = this->NumberofNodes();532 533 /*Initialize Element vector*/534 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);535 IssmDouble* basis = xNew<IssmDouble>(numnodes);536 537 /*Retrieve all inputs and parameters*/538 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);539 this->parameters->FindParam(&input_enum,InputToL2ProjectEnum);540 switch(input_enum){541 case SurfaceSlopeXEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;542 case SurfaceSlopeYEnum: input2 = inputs->GetInput(SurfaceEnum); _assert_(input2); break;543 case BedSlopeXEnum: input2 = inputs->GetInput(BedEnum); _assert_(input2); break;544 case BedSlopeYEnum: input2 = inputs->GetInput(BedEnum); _assert_(input2); break;545 default: input = inputs->GetInput(input_enum);546 }547 548 /* Start looping on the number of gaussian points: */549 GaussTria* gauss=new GaussTria(2);550 for(int ig=gauss->begin();ig<gauss->end();ig++){551 552 gauss->GaussPoint(ig);553 554 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);555 GetNodalFunctions(basis,gauss);556 557 if(input2) input2->GetInputDerivativeValue(&slopes[0],&xyz_list[0][0],gauss);558 switch(input_enum){559 case SurfaceSlopeXEnum: case BedSlopeXEnum: value = slopes[0]; break;560 case SurfaceSlopeYEnum: case BedSlopeYEnum: value = slopes[1]; break;561 default: input->GetInputValue(&value,gauss);562 }563 564 for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];565 }566 567 /*Clean up and return*/568 xDelete<IssmDouble>(basis);569 delete gauss;570 return pe;571 }572 /*}}}*/573 376 /*FUNCTION Tria::CreateJacobianMatrix{{{*/ 574 377 void Tria::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){ … … 3817 3620 } 3818 3621 /*}}}*/ 3819 /*FUNCTION Tria::CreatePVectorStressbalanceFS {{{*/3820 ElementVector* Tria::CreatePVectorStressbalanceFS(void){3821 3822 ElementVector* pe1;3823 ElementVector* pe2;3824 ElementVector* pe3;3825 ElementVector* pe;3826 3827 /*compute all stiffness matrices for this element*/3828 pe1=CreatePVectorStressbalanceFSViscous();3829 pe2=CreatePVectorStressbalanceFSShelf();3830 pe3=CreatePVectorStressbalanceFSFront();3831 pe =new ElementVector(pe1,pe2,pe3);3832 3833 /*clean-up and return*/3834 delete pe1;3835 delete pe2;3836 delete pe3;3837 return pe;3838 }3839 /*}}}*/3840 /*FUNCTION Tria::CreatePVectorStressbalanceFSFront{{{*/3841 ElementVector* Tria::CreatePVectorStressbalanceFSFront(void){3842 3843 /*If no front, return NULL*/3844 if(!IsZeroLevelset(MaskIceLevelsetEnum)) return NULL;3845 3846 /*Intermediaries*/3847 int i;3848 IssmDouble rho_ice,rho_water,gravity,y_g;3849 IssmDouble Jdet,water_pressure,air_pressure,pressure;3850 IssmDouble xyz_list[NUMVERTICES][3];3851 IssmDouble* xyz_list_front = NULL;3852 IssmDouble area_coordinates[2][3];3853 IssmDouble normal[2];3854 GaussTria* gauss = NULL;3855 3856 /*Fetch number of nodes and dof for this finite element*/3857 int vnumnodes = this->NumberofNodesVelocity();3858 int pnumnodes = this->NumberofNodesPressure();3859 3860 /*Prepare coordinate system list*/3861 int* cs_list = xNew<int>(vnumnodes+pnumnodes);3862 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;3863 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;3864 3865 /*Initialize Element matrix and vectors*/3866 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3867 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);3868 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);3869 3870 /*Retrieve all inputs and parameters*/3871 rho_water = matpar->GetRhoWater();3872 rho_ice = matpar->GetRhoIce();3873 gravity = matpar->GetG();3874 ZeroLevelsetCoordinates(&xyz_list_front,&xyz_list[0][0],MaskIceLevelsetEnum);3875 GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,&xyz_list[0][0],2);3876 NormalSection(&normal[0],xyz_list_front);3877 3878 /*Start looping on Gaussian points*/3879 IssmDouble ymax=max(xyz_list_front[0*3+1],xyz_list_front[1*3+1]);3880 IssmDouble ymin=min(xyz_list_front[0*3+1],xyz_list_front[1*3+1]);3881 if(ymax>0. && ymin<0.) gauss=new GaussTria(area_coordinates,30); //refined in vertical because of the sea level discontinuity3882 else gauss=new GaussTria(area_coordinates,3);3883 3884 for(int ig=gauss->begin();ig<gauss->end();ig++){3885 3886 gauss->GaussPoint(ig);3887 y_g=GetYcoord(gauss);3888 GetNodalFunctionsVelocity(vbasis,gauss);3889 GetSegmentJacobianDeterminant(&Jdet,xyz_list_front,gauss);3890 3891 water_pressure = rho_water*gravity*min(0.,y_g); //0 if the gaussian point is above water level3892 air_pressure = 0.;3893 pressure = water_pressure + air_pressure;3894 3895 for(i=0;i<vnumnodes;i++){3896 pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*vbasis[i];3897 pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*vbasis[i];3898 }3899 }3900 3901 /*Transform coordinate system*/3902 ::TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);3903 3904 /*Clean up and return*/3905 xDelete<int>(cs_list);3906 xDelete<IssmDouble>(xyz_list_front);3907 xDelete<IssmDouble>(vbasis);3908 delete gauss;3909 return pe;3910 3911 }3912 /*}}}*/3913 /*FUNCTION Tria::CreatePVectorStressbalanceFSViscous {{{*/3914 ElementVector* Tria::CreatePVectorStressbalanceFSViscous(void){3915 3916 /*Intermediaries*/3917 int i;3918 int approximation;3919 IssmDouble Jdet,gravity,rho_ice;3920 IssmDouble forcex,forcey;3921 IssmDouble xyz_list[NUMVERTICES][3];3922 GaussTria *gauss=NULL;3923 3924 /*Fetch number of nodes and dof for this finite element*/3925 int vnumnodes = this->NumberofNodesVelocity();3926 int pnumnodes = this->NumberofNodesPressure();3927 3928 /*Prepare coordinate system list*/3929 int* cs_list = xNew<int>(vnumnodes+pnumnodes);3930 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;3931 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;3932 3933 /*Initialize Element matrix and vectors*/3934 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);3935 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);3936 3937 /*Retrieve all inputs and parameters*/3938 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3939 Input* loadingforcex_input=inputs->GetInput(LoadingforceXEnum); _assert_(loadingforcex_input);3940 Input* loadingforcey_input=inputs->GetInput(LoadingforceYEnum); _assert_(loadingforcey_input);3941 rho_ice = matpar->GetRhoIce();3942 gravity = matpar->GetG();3943 3944 /* Start looping on the number of gaussian points: */3945 gauss=new GaussTria(5);3946 for(int ig=gauss->begin();ig<gauss->end();ig++){3947 3948 gauss->GaussPoint(ig);3949 3950 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3951 GetNodalFunctionsVelocity(vbasis, gauss);3952 3953 loadingforcex_input->GetInputValue(&forcex,gauss);3954 loadingforcey_input->GetInputValue(&forcey,gauss);3955 3956 for(i=0;i<vnumnodes;i++){3957 pe->values[i*NDOF2+1] += -rho_ice*gravity*Jdet*gauss->weight*vbasis[i];3958 pe->values[i*NDOF2+0] += +rho_ice*forcex *Jdet*gauss->weight*vbasis[i];3959 pe->values[i*NDOF2+1] += +rho_ice*forcey *Jdet*gauss->weight*vbasis[i];3960 }3961 }3962 3963 /*Transform coordinate system*/3964 ::TransformLoadVectorCoord(pe,nodes,vnumnodes+pnumnodes,cs_list);3965 3966 /*Clean up and return*/3967 delete gauss;3968 xDelete<int>(cs_list);3969 xDelete<IssmDouble>(vbasis);3970 return pe;3971 }3972 /*}}}*/3973 /*FUNCTION Tria::CreatePVectorStressbalanceFSShelf{{{*/3974 ElementVector* Tria::CreatePVectorStressbalanceFSShelf(void){3975 3976 /*Intermediaries*/3977 int i,j;3978 int indices[2];3979 IssmDouble gravity,rho_water,bed,water_pressure;3980 IssmDouble normal_vel,vx,vy,dt;3981 IssmDouble xyz_list_seg[NUMVERTICES1D][3];3982 IssmDouble xyz_list[NUMVERTICES][3];3983 IssmDouble normal[2];3984 IssmDouble Jdet;3985 3986 /*Initialize Element vector and return if necessary*/3987 if(!HasEdgeOnBed() || !IsFloating()) return NULL;3988 3989 /*Fetch number of nodes and dof for this finite element*/3990 int vnumnodes = this->NumberofNodesVelocity();3991 int pnumnodes = this->NumberofNodesPressure();3992 3993 /*Prepare coordinate system list*/3994 int* cs_list = xNew<int>(vnumnodes+pnumnodes);3995 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;3996 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;3997 3998 /*Initialize Element matrix and vectors*/3999 ElementVector* pe = new ElementVector(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);4000 IssmDouble* vbasis = xNew<IssmDouble>(vnumnodes);4001 4002 /*Retrieve all inputs and parameters*/4003 rho_water=matpar->GetRhoWater();4004 gravity=matpar->GetG();4005 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4006 Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);4007 4008 /*Get vertex indices that lie on bed*/4009 this->EdgeOnBedIndices(&indices[0],&indices[1]);4010 4011 for(i=0;i<NUMVERTICES1D;i++) for(j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];4012 4013 /* Start looping on the number of gauss 1d (nodes on the bedrock) */4014 GaussTria* gauss=new GaussTria(indices[0],indices[1],5);4015 for(int ig=gauss->begin();ig<gauss->end();ig++){4016 4017 gauss->GaussPoint(ig);4018 4019 GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);4020 GetNodalFunctionsVelocity(vbasis, gauss);4021 4022 NormalSection(&normal[0],&xyz_list_seg[0][0]);4023 _assert_(normal[1]<0.);4024 bed_input->GetInputValue(&bed, gauss);4025 water_pressure=gravity*rho_water*bed;4026 4027 for(i=0;i<vnumnodes;i++){4028 pe->values[2*i+0]+=(water_pressure)*gauss->weight*Jdet*vbasis[i]*normal[0];4029 pe->values[2*i+1]+=(water_pressure)*gauss->weight*Jdet*vbasis[i]*normal[1];4030 }4031 }4032 4033 /*Transform coordinate system*/4034 ::TransformLoadVectorCoord(pe,nodes,(vnumnodes+pnumnodes),cs_list);4035 4036 /*Clean up and return*/4037 delete gauss;4038 xDelete<int>(cs_list);4039 xDelete<IssmDouble>(vbasis);4040 return pe;4041 }4042 /*}}}*/4043 /*FUNCTION Tria::CreatePVectorStressbalanceSSA {{{*/4044 ElementVector* Tria::CreatePVectorStressbalanceSSA(){4045 4046 /*compute all load vectors for this element*/4047 ElementVector* pe1=CreatePVectorStressbalanceSSADrivingStress();4048 ElementVector* pe2=CreatePVectorStressbalanceSSAFront();4049 ElementVector* pe =new ElementVector(pe1,pe2);4050 4051 /*clean-up and return*/4052 delete pe1;4053 delete pe2;4054 return pe;4055 }4056 /*}}}*/4057 /*FUNCTION Tria::CreatePVectorStressbalanceSSADrivingStress {{{*/4058 ElementVector* Tria::CreatePVectorStressbalanceSSADrivingStress(){4059 4060 /*Intermediaries */4061 int i;4062 IssmDouble driving_stress_baseline,thickness;4063 IssmDouble Jdet;4064 IssmDouble xyz_list[NUMVERTICES][3];4065 IssmDouble slope[2];4066 IssmDouble icefrontlevel[3];4067 4068 /*Fetch number of nodes and dof for this finite element*/4069 int numnodes = this->NumberofNodes();4070 4071 /*Initialize Element vector and vectors*/4072 ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters,SSAApproximationEnum);4073 IssmDouble* basis = xNew<IssmDouble>(numnodes);4074 4075 /*Retrieve all inputs and parameters*/4076 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4077 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);4078 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);4079 Input* drag_input=inputs->GetInput(FrictionCoefficientEnum);_assert_(drag_input);4080 GetInputListOnVertices(&icefrontlevel[0],BedEnum);4081 4082 /* Start looping on the number of gaussian points: */4083 GaussTria* gauss = new GaussTria(2);4084 for(int ig=gauss->begin();ig<gauss->end();ig++){4085 4086 gauss->GaussPoint(ig);4087 4088 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);4089 GetNodalFunctions(basis, gauss);4090 4091 thickness_input->GetInputValue(&thickness,gauss);4092 surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);4093 driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG()*thickness;4094 4095 /*Build load vector: */4096 for(i=0;i<numnodes;i++){4097 pe->values[i*NDOF2+0]+=-driving_stress_baseline*slope[0]*Jdet*gauss->weight*basis[i];4098 pe->values[i*NDOF2+1]+=-driving_stress_baseline*slope[1]*Jdet*gauss->weight*basis[i];4099 }4100 }4101 4102 /*Transform coordinate system*/4103 ::TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);4104 4105 /*Clean up and return*/4106 xDelete<IssmDouble>(basis);4107 delete gauss;4108 return pe;4109 }4110 /*}}}*/4111 /*FUNCTION Tria::CreatePVectorStressbalanceSSAFront {{{*/4112 ElementVector* Tria::CreatePVectorStressbalanceSSAFront(){4113 4114 /*If no front, return NULL*/4115 if(!IsZeroLevelset(MaskIceLevelsetEnum)) return NULL;4116 4117 /*Intermediaries*/4118 IssmDouble rho_ice,rho_water,gravity;4119 IssmDouble Jdet,thickness,bed,water_pressure,ice_pressure,air_pressure;4120 IssmDouble surface_under_water,base_under_water,pressure;4121 IssmDouble xyz_list[NUMVERTICES][3];4122 IssmDouble *xyz_list_front = NULL;4123 IssmDouble area_coordinates[2][3];4124 IssmDouble normal[2];4125 4126 /*Fetch number of nodes for this finite element*/4127 int numnodes = this->NumberofNodes();4128 4129 /*Initialize Element vector and other vectors*/4130 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4131 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters,SSAApproximationEnum);4132 IssmDouble* basis = xNew<IssmDouble>(numnodes);4133 4134 /*Retrieve all inputs and parameters*/4135 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);4136 Input* bed_input =inputs->GetInput(BedEnum); _assert_(bed_input);4137 rho_water = matpar->GetRhoWater();4138 rho_ice = matpar->GetRhoIce();4139 gravity = matpar->GetG();4140 ZeroLevelsetCoordinates(&xyz_list_front,&xyz_list[0][0],MaskIceLevelsetEnum);4141 GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,&xyz_list[0][0],2);4142 NormalSection(&normal[0],xyz_list_front);4143 4144 /*Start looping on Gaussian points*/4145 GaussTria* gauss=new GaussTria(area_coordinates,3);4146 for(int ig=gauss->begin();ig<gauss->end();ig++){4147 4148 gauss->GaussPoint(ig);4149 thickness_input->GetInputValue(&thickness,gauss);4150 bed_input->GetInputValue(&bed,gauss);4151 GetSegmentJacobianDeterminant(&Jdet,xyz_list_front,gauss);4152 GetNodalFunctions(basis,gauss);4153 4154 surface_under_water = min(0.,thickness+bed); // 0 if the top of the glacier is above water level4155 base_under_water = min(0.,bed); // 0 if the bottom of the glacier is above water level4156 water_pressure = 1.0/2.0*gravity*rho_water*(pow(surface_under_water,2) - pow(base_under_water,2));4157 ice_pressure = 1.0/2.0*gravity*rho_ice*pow(thickness,2);4158 air_pressure = 0;4159 pressure = ice_pressure + water_pressure + air_pressure;4160 4161 for (int i=0;i<numnodes;i++){4162 pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];4163 pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];4164 }4165 }4166 4167 /*Transform coordinate system*/4168 ::TransformLoadVectorCoord(pe,nodes,numnodes,XYEnum);4169 4170 /*Clean up and return*/4171 xDelete<IssmDouble>(basis);4172 xDelete<IssmDouble>(xyz_list_front);4173 delete gauss;4174 return pe;4175 }4176 /*}}}*/4177 /*FUNCTION Tria::CreatePVectorStressbalanceSIA{{{*/4178 ElementVector* Tria::CreatePVectorStressbalanceSIA(void){4179 4180 /*Intermediaries */4181 IssmDouble ub,vb;4182 IssmDouble rho_ice,gravity,n,B,drag;4183 IssmDouble slope2,thickness,connectivity;4184 IssmDouble slope[2];4185 4186 /*Fetch number of nodes and dof for this finite element*/4187 int numnodes = this->NumberofNodes(); _assert_(numnodes==3);4188 4189 /*Initialize Element vector*/4190 ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);4191 4192 /*Retrieve all inputs and parameters*/4193 rho_ice=matpar->GetRhoIce();4194 gravity=matpar->GetG();4195 n=material->GetN();4196 B=material->GetBbar();4197 Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);4198 Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);4199 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);4200 Input* drag_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(drag_input);4201 4202 /*Spawn 3 sing elements: */4203 GaussTria* gauss=new GaussTria();4204 for(int i=0;i<numnodes;i++){4205 4206 gauss->GaussVertex(i);4207 4208 connectivity=(IssmDouble)vertices[i]->Connectivity();4209 4210 thickness_input->GetInputValue(&thickness,gauss);4211 drag_input->GetInputValue(&drag,gauss);4212 slopex_input->GetInputValue(&slope[0],gauss);4213 slopey_input->GetInputValue(&slope[1],gauss);4214 slope2=slope[0]*slope[0]+slope[1]*slope[1];4215 4216 /*Payne 1995 (m = 1, B = 5e-3/yts = 1.58e-10 m/s/Pa*/4217 ub=-1.58*1.e-10*rho_ice*gravity*thickness*slope[0];4218 vb=-1.58*1.e-10*rho_ice*gravity*thickness*slope[1];4219 ///*Ritz et al. 1996*/4220 //ub=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[0]/sqrt(slope2);4221 //vb=drag*(rho_ice*gravity*thickness)*(rho_ice*gravity*thickness)*slope[1]/sqrt(slope2);4222 ///*Rutt et al. 2009*/4223 //ub=-drag*rho_ice*gravity*thickness*slope[0];4224 //vb=-drag*rho_ice*gravity*thickness*slope[1];4225 4226 pe->values[2*i+0]=(ub-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0])/connectivity;4227 pe->values[2*i+1]=(vb-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1])/connectivity;4228 }4229 4230 /*Clean up and return*/4231 delete gauss;4232 return pe;4233 }4234 /*}}}*/4235 3622 /*FUNCTION Tria::CreateJacobianStressbalanceSSA{{{*/ 4236 3623 ElementMatrix* Tria::CreateJacobianStressbalanceSSA(void){ … … 5607 4994 } 5608 4995 /*}}}*/ 5609 /*FUNCTION Tria::CreatePVectorAdjointBalancethickness{{{*/5610 ElementVector* Tria::CreatePVectorAdjointBalancethickness(void){5611 5612 /*Intermediaries */5613 int i,resp;5614 IssmDouble Jdet;5615 IssmDouble thickness,thicknessobs,weight;5616 int num_responses;5617 IssmDouble xyz_list[NUMVERTICES][3];5618 IssmDouble dH[2];5619 IssmDouble vx,vy,vel;5620 int *responses = NULL;5621 5622 /*Fetch number of nodes and dof for this finite element*/5623 int numnodes = this->NumberofNodes();5624 5625 /*Initialize Element vector and vectors*/5626 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);5627 IssmDouble* basis = xNew<IssmDouble>(numnodes);5628 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);5629 5630 /*Retrieve all inputs and parameters*/5631 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5632 this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);5633 this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);5634 Input* thickness_input = inputs->GetInput(ThicknessEnum); _assert_(thickness_input);5635 Input* thicknessobs_input = inputs->GetInput(InversionThicknessObsEnum); _assert_(thicknessobs_input);5636 Input* weights_input = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);5637 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input);5638 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input);5639 5640 /* Start looping on the number of gaussian points: */5641 GaussTria* gauss=new GaussTria(2);5642 for(int ig=gauss->begin();ig<gauss->end();ig++){5643 5644 gauss->GaussPoint(ig);5645 5646 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5647 GetNodalFunctions(basis, gauss);5648 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);5649 5650 thickness_input->GetInputValue(&thickness, gauss);5651 thickness_input->GetInputDerivativeValue(&dH[0],&xyz_list[0][0],gauss);5652 thicknessobs_input->GetInputValue(&thicknessobs, gauss);5653 5654 /*Loop over all requested responses*/5655 for(resp=0;resp<num_responses;resp++){5656 5657 weights_input->GetInputValue(&weight,gauss,responses[resp]);5658 5659 switch(responses[resp]){5660 case ThicknessAbsMisfitEnum:5661 for(i=0;i<numnodes;i++) pe->values[i]+=(thicknessobs-thickness)*weight*Jdet*gauss->weight*basis[i];5662 break;5663 case ThicknessAbsGradientEnum:5664 for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[0]*dbasis[0*numnodes+i]*Jdet*gauss->weight;5665 for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[1]*dbasis[1*numnodes+i]*Jdet*gauss->weight;5666 break;5667 case ThicknessAlongGradientEnum:5668 vx_input->GetInputValue(&vx,gauss);5669 vy_input->GetInputValue(&vy,gauss);5670 vel = sqrt(vx*vx+vy*vy);5671 vx = vx/(vel+1.e-9);5672 vy = vy/(vel+1.e-9);5673 for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*vx+dH[1]*vy)*(dbasis[0*numnodes+i]*vx+dbasis[1*numnodes+i]*vy)*Jdet*gauss->weight;5674 break;5675 case ThicknessAcrossGradientEnum:5676 vx_input->GetInputValue(&vx,gauss);5677 vy_input->GetInputValue(&vy,gauss);5678 vel = sqrt(vx*vx+vy*vy);5679 vx = vx/(vel+1.e-9);5680 vy = vy/(vel+1.e-9);5681 for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*(-vy)+dH[1]*vx)*(dbasis[0*numnodes+i]*(-vy)+dbasis[1*numnodes+i]*vx)*Jdet*gauss->weight;5682 break;5683 default:5684 _error_("response " << EnumToStringx(responses[resp]) << " not supported yet");5685 }5686 }5687 }5688 5689 /*Clean up and return*/5690 xDelete<IssmDouble>(basis);5691 xDelete<IssmDouble>(dbasis);5692 xDelete<int>(responses);5693 delete gauss;5694 return pe;5695 }5696 /*}}}*/5697 /*FUNCTION Tria::CreatePVectorAdjointHoriz{{{*/5698 ElementVector* Tria::CreatePVectorAdjointHoriz(void){5699 5700 /*Intermediaries */5701 int i,resp;5702 int *responses=NULL;5703 int num_responses;5704 IssmDouble Jdet;5705 IssmDouble obs_velocity_mag,velocity_mag;5706 IssmDouble dux,duy;5707 IssmDouble epsvel=2.220446049250313e-16;5708 IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/5709 IssmDouble scalex=0.,scaley=0.,scale=0.,S=0.;5710 IssmDouble vx,vy,vxobs,vyobs,weight;5711 IssmDouble xyz_list[NUMVERTICES][3];5712 5713 /*Fetch number of nodes and dof for this finite element*/5714 int numnodes = this->NumberofNodes();5715 5716 /*Initialize Element vector*/5717 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);5718 IssmDouble* basis = xNew<IssmDouble>(numnodes);5719 5720 /*Retrieve all inputs and parameters*/5721 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5722 this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);5723 this->parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);5724 Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);5725 Input* vx_input =inputs->GetInput(VxEnum); _assert_(vx_input);5726 Input* vy_input =inputs->GetInput(VyEnum); _assert_(vy_input);5727 Input* vxobs_input =inputs->GetInput(InversionVxObsEnum); _assert_(vxobs_input);5728 Input* vyobs_input =inputs->GetInput(InversionVyObsEnum); _assert_(vyobs_input);5729 5730 /*Get Surface if required by one response*/5731 for(resp=0;resp<num_responses;resp++){5732 if(responses[resp]==SurfaceAverageVelMisfitEnum){5733 inputs->GetInputValue(&S,SurfaceAreaEnum); break;5734 }5735 }5736 5737 /* Start looping on the number of gaussian points: */5738 GaussTria* gauss=new GaussTria(4);5739 for(int ig=gauss->begin();ig<gauss->end();ig++){5740 5741 gauss->GaussPoint(ig);5742 5743 /* Get Jacobian determinant: */5744 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5745 5746 /*Get all parameters at gaussian point*/5747 vx_input->GetInputValue(&vx,gauss);5748 vy_input->GetInputValue(&vy,gauss);5749 vxobs_input->GetInputValue(&vxobs,gauss);5750 vyobs_input->GetInputValue(&vyobs,gauss);5751 GetNodalFunctions(basis, gauss);5752 5753 /*Loop over all requested responses*/5754 for(resp=0;resp<num_responses;resp++){5755 5756 weights_input->GetInputValue(&weight,gauss,responses[resp]);5757 5758 switch(responses[resp]){5759 case SurfaceAbsVelMisfitEnum:5760 /*5761 * 1 [ 2 2 ]5762 * J = --- | (u - u ) + (v - v ) |5763 * 2 [ obs obs ]5764 *5765 * dJ5766 * DU = - -- = (u - u )5767 * du obs5768 */5769 for(i=0;i<numnodes;i++){5770 dux=vxobs-vx;5771 duy=vyobs-vy;5772 pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i];5773 pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i];5774 }5775 break;5776 case SurfaceRelVelMisfitEnum:5777 /*5778 * 1 [ \bar{v}^2 2 \bar{v}^2 2 ]5779 * J = --- | ------------- (u - u ) + ------------- (v - v ) |5780 * 2 [ (u + eps)^2 obs (v + eps)^2 obs ]5781 * obs obs5782 *5783 * dJ \bar{v}^25784 * DU = - -- = ------------- (u - u )5785 * du (u + eps)^2 obs5786 * obs5787 */5788 for(i=0;i<numnodes;i++){5789 scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;5790 scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;5791 dux=scalex*(vxobs-vx);5792 duy=scaley*(vyobs-vy);5793 pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i];5794 pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i];5795 }5796 break;5797 case SurfaceLogVelMisfitEnum:5798 /*5799 * [ vel + eps ] 25800 * J = 4 \bar{v}^2 | log ( ----------- ) |5801 * [ vel + eps ]5802 * obs5803 *5804 * dJ 2 * log(...)5805 * DU = - -- = - 4 \bar{v}^2 ------------- u5806 * du vel^2 + eps5807 *5808 */5809 for(i=0;i<numnodes;i++){5810 velocity_mag =sqrt(pow(vx, 2)+pow(vy, 2))+epsvel;5811 obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;5812 scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);5813 dux=scale*vx;5814 duy=scale*vy;5815 pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i];5816 pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i];5817 }5818 break;5819 case SurfaceAverageVelMisfitEnum:5820 /*5821 * 1 2 25822 * J = --- sqrt( (u - u ) + (v - v ) )5823 * S obs obs5824 *5825 * dJ 1 15826 * DU = - -- = - --- ----------- * 2 (u - u )5827 * du S 2 sqrt(...) obs5828 */5829 for(i=0;i<numnodes;i++){5830 scale=1./(S*2*sqrt(pow(vx-vxobs,2)+pow(vy-vyobs,2))+epsvel);5831 dux=scale*(vxobs-vx);5832 duy=scale*(vyobs-vy);5833 pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i];5834 pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i];5835 }5836 break;5837 case SurfaceLogVxVyMisfitEnum:5838 /*5839 * 1 [ |u| + eps 2 |v| + eps 2 ]5840 * J = --- \bar{v}^2 | log ( ----------- ) + log ( ----------- ) |5841 * 2 [ |u |+ eps |v |+ eps ]5842 * obs obs5843 * dJ 1 u 15844 * DU = - -- = - \bar{v}^2 log(u...) --------- ---- ~ - \bar{v}^2 log(u...) ------5845 * du |u| + eps |u| u + eps5846 */5847 for(i=0;i<numnodes;i++){5848 dux = - meanvel*meanvel * log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)) / (vx+epsvel);5849 duy = - meanvel*meanvel * log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)) / (vy+epsvel);5850 pe->values[i*NDOF2+0]+=dux*weight*Jdet*gauss->weight*basis[i];5851 pe->values[i*NDOF2+1]+=duy*weight*Jdet*gauss->weight*basis[i];5852 }5853 break;5854 case DragCoefficientAbsGradientEnum:5855 /*Nothing in P vector*/5856 break;5857 case ThicknessAbsGradientEnum:5858 /*Nothing in P vector*/5859 break;5860 case ThicknessAlongGradientEnum:5861 /*Nothing in P vector*/5862 break;5863 case ThicknessAcrossGradientEnum:5864 /*Nothing in P vector*/5865 break;5866 case RheologyBbarAbsGradientEnum:5867 /*Nothing in P vector*/5868 break;5869 default:5870 _error_("response " << EnumToStringx(responses[resp]) << " not supported yet");5871 }5872 }5873 }5874 5875 /*Clean up and return*/5876 xDelete<IssmDouble>(basis);5877 xDelete<int>(responses);5878 delete gauss;5879 return pe;5880 }5881 /*}}}*/5882 4996 /*FUNCTION Tria::DragCoefficientAbsGradient{{{*/ 5883 4997 IssmDouble Tria::DragCoefficientAbsGradient(void){ … … 6449 5563 xDelete<IssmDouble>(basis); 6450 5564 return Ke; 6451 }6452 /*}}}*/6453 /*FUNCTION Tria::CreatePVectorHydrologyShreve {{{*/6454 ElementVector* Tria::CreatePVectorHydrologyShreve(void){6455 6456 /*Intermediaries */6457 int i;6458 IssmDouble Jdet,dt;6459 IssmDouble basal_melting_g;6460 IssmDouble old_watercolumn_g;6461 IssmDouble xyz_list[NUMVERTICES][3];6462 6463 /*Skip if water or ice shelf element*/6464 if(NoIceInElement() || IsFloating()) return NULL;6465 6466 /*Fetch number of nodes and dof for this finite element*/6467 int numnodes = this->NumberofNodes();6468 6469 /*Initialize Element vector*/6470 ElementVector* pe=new ElementVector(nodes,numnodes,this->parameters);6471 IssmDouble* basis = xNewZeroInit<IssmDouble>(numnodes);6472 6473 /*Retrieve all inputs and parameters*/6474 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6475 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6476 Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);6477 Input* old_watercolumn_input=inputs->GetInput(WaterColumnOldEnum); _assert_(old_watercolumn_input);6478 /*Initialize basal_melting_correction_g to 0, do not forget!:*/6479 /* Start looping on the number of gaussian points: */6480 GaussTria* gauss=new GaussTria(2);6481 for(int ig=gauss->begin();ig<gauss->end();ig++){6482 6483 gauss->GaussPoint(ig);6484 6485 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6486 GetNodalFunctions(basis, gauss);6487 6488 basal_melting_input->GetInputValue(&basal_melting_g,gauss);6489 old_watercolumn_input->GetInputValue(&old_watercolumn_g,gauss);6490 6491 if(reCast<int,IssmDouble>(dt)){6492 for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(old_watercolumn_g+dt*basal_melting_g)*basis[i];6493 }6494 else{6495 for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*basal_melting_g*basis[i];6496 }6497 }6498 6499 /*Clean up and return*/6500 xDelete<IssmDouble>(basis);6501 delete gauss;6502 return pe;6503 }6504 /*}}}*/6505 /*FUNCTION Tria::CreatePVectorHydrologyDCInefficient {{{*/6506 ElementVector* Tria::CreatePVectorHydrologyDCInefficient(void){6507 6508 /*Intermediaries */6509 IssmDouble Jdet;6510 IssmDouble xyz_list[NUMVERTICES][3];6511 IssmDouble dt,scalar,water_head;6512 IssmDouble water_load,transfer;6513 IssmDouble sediment_storing;6514 6515 /*Fetch number of nodes and dof for this finite element*/6516 int numnodes = this->NumberofNodes();6517 6518 /*Initialize Element vector and other vectors*/6519 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);6520 IssmDouble* basis = xNew<IssmDouble>(numnodes);6521 6522 /*Retrieve all inputs and parameters*/6523 sediment_storing = matpar->GetSedimentStoring();6524 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6525 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6526 Input* water_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(water_input);6527 Input* transfer_input=inputs->GetInput(WaterTransferEnum); _assert_(transfer_input);6528 Input* old_wh_input=NULL;6529 6530 if(reCast<bool,IssmDouble>(dt)){6531 old_wh_input=inputs->GetInput(SedimentHeadOldEnum); _assert_(old_wh_input);6532 }6533 6534 /* Start looping on the number of gaussian points: */6535 GaussTria* gauss=new GaussTria(2);6536 for(int ig=gauss->begin();ig<gauss->end();ig++){6537 6538 gauss->GaussPoint(ig);6539 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6540 GetNodalFunctions(basis, gauss);6541 6542 /*Loading term*/6543 water_input->GetInputValue(&water_load,gauss);6544 transfer_input->GetInputValue(&transfer,gauss);6545 scalar = Jdet*gauss->weight*(water_load+transfer);6546 if(reCast<bool,IssmDouble>(dt)) scalar = scalar*dt;6547 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];6548 6549 /*Transient term*/6550 if(reCast<bool,IssmDouble>(dt)){6551 old_wh_input->GetInputValue(&water_head,gauss);6552 scalar = Jdet*gauss->weight*water_head*sediment_storing;6553 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];6554 }6555 }6556 6557 /*Clean up and return*/6558 xDelete<IssmDouble>(basis);6559 delete gauss;6560 return pe;6561 }6562 /*}}}*/6563 /*FUNCTION Tria::CreatePVectorHydrologyDCEfficient {{{*/6564 ElementVector* Tria::CreatePVectorHydrologyDCEfficient(void){6565 6566 /*Intermediaries */6567 IssmDouble connectivity;6568 IssmDouble Jdet;6569 IssmDouble xyz_list[NUMVERTICES][3];6570 IssmDouble dt,scalar,water_head;6571 IssmDouble transfer,residual;6572 IssmDouble epl_thickness;6573 IssmDouble epl_specificstoring;6574 GaussTria* gauss = NULL;6575 6576 /*Check that all nodes are active, else return empty matrix*/6577 if(!this->AllActive()){6578 return NULL;6579 }6580 6581 /*Fetch number of nodes and dof for this finite element*/6582 int numnodes = this->NumberofNodes();6583 6584 /*Initialize Element vector and other vectors*/6585 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);6586 IssmDouble* basis = xNew<IssmDouble>(numnodes);6587 6588 /*Retrieve all inputs and parameters*/6589 epl_specificstoring = matpar->GetEplSpecificStoring();6590 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6591 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6592 Input* residual_input=inputs->GetInput(SedimentHeadResidualEnum); _assert_(residual_input);6593 Input* transfer_input=inputs->GetInput(WaterTransferEnum); _assert_(transfer_input);6594 Input* thickness_input=inputs->GetInput(HydrologydcEplThicknessEnum); _assert_(thickness_input);6595 Input* old_wh_input=NULL;6596 6597 if(reCast<bool,IssmDouble>(dt)){6598 old_wh_input=inputs->GetInput(EplHeadOldEnum); _assert_(old_wh_input);6599 }6600 6601 /* Start looping on the number of gaussian points: */6602 gauss=new GaussTria(2);6603 for(int ig=gauss->begin();ig<gauss->end();ig++){6604 6605 gauss->GaussPoint(ig);6606 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6607 GetNodalFunctions(basis,gauss);6608 6609 /*Loading term*/6610 transfer_input->GetInputValue(&transfer,gauss);6611 scalar = Jdet*gauss->weight*(-transfer);6612 if(reCast<bool,IssmDouble>(dt)) scalar = scalar*dt;6613 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];6614 6615 /*Transient term*/6616 if(reCast<bool,IssmDouble>(dt)){6617 thickness_input->GetInputValue(&epl_thickness,gauss);6618 old_wh_input->GetInputValue(&water_head,gauss);6619 scalar = Jdet*gauss->weight*water_head*epl_specificstoring*epl_thickness;6620 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];6621 }6622 }6623 delete gauss;6624 6625 /* Add residual if necessary*/6626 gauss=new GaussTria();6627 for(int iv=0;iv<NUMVERTICES;iv++){6628 gauss->GaussVertex(iv);6629 6630 connectivity = IssmDouble(vertices[iv]->Connectivity());6631 residual_input->GetInputValue(&residual,gauss);6632 pe->values[iv]+=residual/connectivity;6633 }6634 6635 /*Clean up and return*/6636 xDelete<IssmDouble>(basis);6637 delete gauss;6638 return pe;6639 }6640 /*}}}*/6641 /*FUNCTION Tria::CreatePVectorL2ProjectionEPL {{{*/6642 ElementVector* Tria::CreatePVectorL2ProjectionEPL(void){6643 6644 /*Intermediaries */6645 int i,input_enum;6646 IssmDouble Jdet,value;6647 IssmDouble xyz_list[NUMVERTICES][3];6648 IssmDouble slopes[2];6649 Input* input = NULL;6650 Input* input2 = NULL;6651 6652 /*Fetch number of nodes and dof for this finite element*/6653 int numnodes = this->NumberofNodes();6654 6655 /*Initialize Element vector*/6656 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);6657 IssmDouble* basis = xNew<IssmDouble>(numnodes);6658 6659 /*Retrieve all inputs and parameters*/6660 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6661 this->parameters->FindParam(&input_enum,InputToL2ProjectEnum);6662 switch(input_enum){6663 case EplHeadSlopeXEnum: input2 = inputs->GetInput(EplHeadEnum); _assert_(input2); break;6664 case EplHeadSlopeYEnum: input2 = inputs->GetInput(EplHeadEnum); _assert_(input2); break;6665 default: input = inputs->GetInput(input_enum);6666 }6667 6668 /* Start looping on the number of gaussian points: */6669 GaussTria* gauss=new GaussTria(2);6670 for(int ig=gauss->begin();ig<gauss->end();ig++){6671 6672 gauss->GaussPoint(ig);6673 6674 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6675 GetNodalFunctions(basis,gauss);6676 6677 if(input2) input2->GetInputDerivativeValue(&slopes[0],&xyz_list[0][0],gauss);6678 switch(input_enum){6679 case EplHeadSlopeXEnum: value = slopes[0]; break;6680 case EplHeadSlopeYEnum: value = slopes[1]; break;6681 default: input->GetInputValue(&value,gauss);6682 }6683 6684 for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*value*basis[i];6685 }6686 6687 /*Clean up and return*/6688 xDelete<IssmDouble>(basis);6689 delete gauss;6690 return pe;6691 5565 } 6692 5566 /*}}}*/ … … 7616 6490 } 7617 6491 /*}}}*/ 7618 /*FUNCTION Tria::CreatePVectorMasstransport{{{*/7619 ElementVector* Tria::CreatePVectorMasstransport(void){7620 7621 switch(GetElementType()){7622 case P1Enum: case P2Enum:7623 return CreatePVectorMasstransport_CG();7624 case P1DGEnum:7625 return CreatePVectorMasstransport_DG();7626 default:7627 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");7628 }7629 }7630 /*}}}*/7631 /*FUNCTION Tria::CreatePVectorMasstransport_CG {{{*/7632 ElementVector* Tria::CreatePVectorMasstransport_CG(void){7633 7634 /*Intermediaries */7635 IssmDouble Jdet,dt;7636 IssmDouble ms,mb,mb_correction,thickness;7637 IssmDouble xyz_list[NUMVERTICES][3];7638 7639 /*Fetch number of nodes and dof for this finite element*/7640 int numnodes = this->NumberofNodes();7641 7642 /*Initialize Element vector and other vectors*/7643 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);7644 IssmDouble* basis = xNew<IssmDouble>(numnodes);7645 7646 /*Retrieve all inputs and parameters*/7647 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7648 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);7649 Input* ms_input = inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);7650 Input* mb_input = inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);7651 Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);7652 Input* thickness_input = inputs->GetInput(ThicknessEnum); _assert_(thickness_input);7653 7654 /*Initialize mb_correction to 0, do not forget!:*/7655 /* Start looping on the number of gaussian points: */7656 GaussTria* gauss=new GaussTria(2);7657 for(int ig=gauss->begin();ig<gauss->end();ig++){7658 7659 gauss->GaussPoint(ig);7660 7661 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7662 GetNodalFunctions(basis,gauss);7663 7664 ms_input->GetInputValue(&ms,gauss);7665 mb_input->GetInputValue(&mb,gauss);7666 thickness_input->GetInputValue(&thickness,gauss);7667 if(mb_correction_input)7668 mb_correction_input->GetInputValue(&mb_correction,gauss);7669 else7670 mb_correction=0.;7671 7672 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb-mb_correction))*basis[i];7673 }7674 7675 /*Clean up and return*/7676 xDelete<IssmDouble>(basis);7677 delete gauss;7678 return pe;7679 }7680 /*}}}*/7681 /*FUNCTION Tria::CreatePVectorMasstransport_DG {{{*/7682 ElementVector* Tria::CreatePVectorMasstransport_DG(void){7683 7684 /*Intermediaries */7685 IssmDouble Jdet,dt;7686 IssmDouble ms,mb,thickness;7687 IssmDouble xyz_list[NUMVERTICES][3];7688 7689 /*Fetch number of nodes and dof for this finite element*/7690 int numnodes = this->NumberofNodes();7691 7692 /*Initialize Element vector and other vectors*/7693 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);7694 IssmDouble* basis = xNew<IssmDouble>(numnodes);7695 7696 /*Retrieve all inputs and parameters*/7697 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);7698 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7699 Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);7700 Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);7701 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);7702 7703 /* Start looping on the number of gaussian points: */7704 GaussTria* gauss=new GaussTria(2);7705 for(int ig=gauss->begin();ig<gauss->end();ig++){7706 7707 gauss->GaussPoint(ig);7708 7709 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7710 GetNodalFunctions(basis,gauss);7711 7712 ms_input->GetInputValue(&ms,gauss);7713 mb_input->GetInputValue(&mb,gauss);7714 thickness_input->GetInputValue(&thickness,gauss);7715 7716 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(thickness+dt*(ms-mb))*basis[i];7717 }7718 7719 /*Clean up and return*/7720 xDelete<IssmDouble>(basis);7721 delete gauss;7722 return pe;7723 }7724 /*}}}*/7725 /*FUNCTION Tria::CreatePVectorFreeSurfaceTop {{{*/7726 ElementVector* Tria::CreatePVectorFreeSurfaceTop(void){7727 7728 /*Intermediaries */7729 IssmDouble Jdet,dt;7730 IssmDouble ms,surface,vz;7731 IssmDouble xyz_list[NUMVERTICES][3];7732 7733 /*Fetch number of nodes and dof for this finite element*/7734 int numnodes = this->NumberofNodes();7735 7736 /*Initialize Element vector and other vectors*/7737 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);7738 IssmDouble* basis = xNew<IssmDouble>(numnodes);7739 7740 /*Retrieve all inputs and parameters*/7741 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7742 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);7743 Input* vz_input = inputs->GetInput(VzEnum); _assert_(vz_input);7744 Input* ms_input = inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);7745 Input* surface_input= inputs->GetInput(SurfaceEnum); _assert_(surface_input);7746 7747 /*Initialize mb_correction to 0, do not forget!:*/7748 /* Start looping on the number of gaussian points: */7749 GaussTria* gauss=new GaussTria(2);7750 for(int ig=gauss->begin();ig<gauss->end();ig++){7751 7752 gauss->GaussPoint(ig);7753 7754 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7755 GetNodalFunctions(basis,gauss);7756 7757 vz_input->GetInputValue(&vz,gauss);7758 ms_input->GetInputValue(&ms,gauss);7759 surface_input->GetInputValue(&surface,gauss);7760 7761 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(surface + dt*ms + dt*vz)*basis[i];7762 }7763 7764 /*Clean up and return*/7765 xDelete<IssmDouble>(basis);7766 delete gauss;7767 return pe;7768 }7769 /*}}}*/7770 /*FUNCTION Tria::CreatePVectorFreeSurfaceTop1D {{{*/7771 ElementVector* Tria::CreatePVectorFreeSurfaceTop1D(void){7772 7773 if(!HasEdgeOnSurface()) return NULL;7774 7775 int index1,index2;7776 this->EdgeOnSurfaceIndices(&index1,&index2);7777 7778 Seg* seg=(Seg*)SpawnSeg(index1,index2);7779 ElementVector* pe=seg->CreatePVectorFreeSurfaceTop();7780 delete seg->material; delete seg;7781 7782 /*clean up and return*/7783 return pe;7784 }7785 /*}}}*/7786 /*FUNCTION Tria::CreatePVectorFreeSurfaceBase {{{*/7787 ElementVector* Tria::CreatePVectorFreeSurfaceBase(void){7788 7789 /*Intermediaries */7790 IssmDouble Jdet,dt;7791 IssmDouble mb,mb_correction,bed,vz;7792 IssmDouble xyz_list[NUMVERTICES][3];7793 7794 /*Fetch number of nodes and dof for this finite element*/7795 int numnodes = this->NumberofNodes();7796 7797 /*Initialize Element vector and other vectors*/7798 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);7799 IssmDouble* basis = xNew<IssmDouble>(numnodes);7800 7801 /*Retrieve all inputs and parameters*/7802 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7803 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);7804 Input* vz_input = inputs->GetInput(VzEnum); _assert_(vz_input);7805 Input* mb_input = inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);7806 Input* mb_correction_input = inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);7807 Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input);7808 7809 /*Initialize mb_correction to 0, do not forget!:*/7810 /* Start looping on the number of gaussian points: */7811 GaussTria* gauss=new GaussTria(2);7812 for(int ig=gauss->begin();ig<gauss->end();ig++){7813 7814 gauss->GaussPoint(ig);7815 7816 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7817 GetNodalFunctions(basis,gauss);7818 7819 vz_input->GetInputValue(&vz,gauss);7820 mb_input->GetInputValue(&mb,gauss);7821 bed_input->GetInputValue(&bed,gauss);7822 if(mb_correction_input)7823 mb_correction_input->GetInputValue(&mb_correction,gauss);7824 else7825 mb_correction=0.;7826 7827 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(bed+dt*(mb-mb_correction) + dt*vz)*basis[i];7828 }7829 7830 /*Clean up and return*/7831 xDelete<IssmDouble>(basis);7832 delete gauss;7833 return pe;7834 }7835 /*}}}*/7836 /*FUNCTION Tria::CreatePVectorFreeSurfaceBase1D {{{*/7837 ElementVector* Tria::CreatePVectorFreeSurfaceBase1D(void){7838 7839 if(!HasEdgeOnBed()) return NULL;7840 7841 int index1,index2;7842 this->EdgeOnBedIndices(&index1,&index2);7843 7844 Seg* seg=(Seg*)SpawnSeg(index1,index2);7845 ElementVector* pe=seg->CreatePVectorFreeSurfaceBase();7846 delete seg->material; delete seg;7847 7848 /*clean up and return*/7849 return pe;7850 }7851 /*}}}*/7852 6492 #endif 7853 6493 … … 7982 6622 delete gauss; 7983 6623 return Ke; 7984 }7985 /*}}}*/7986 /*FUNCTION Tria::CreatePVectorDamageEvolution{{{*/7987 ElementVector* Tria::CreatePVectorDamageEvolution(void){7988 7989 switch(GetElementType()){7990 case P1Enum: case P2Enum:7991 return CreatePVectorDamageEvolution_CG();7992 case P1DGEnum:7993 _error_("DG not implemented yet");7994 default:7995 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");7996 }7997 }7998 /*}}}*/7999 /*FUNCTION Tria::CreatePVectorDamageEvolution_CG {{{*/8000 ElementVector* Tria::CreatePVectorDamageEvolution_CG(void){8001 8002 /*Intermediaries */8003 IssmDouble Jdet ,dt;8004 IssmDouble f,damage;8005 IssmDouble xyz_list[NUMVERTICES][3];8006 IssmDouble f_list[NUMVERTICES];8007 Input *damage_input = NULL;8008 8009 /*Fetch number of nodes and dof for this finite element*/8010 int numnodes = this->NumberofNodes();8011 8012 /*Initialize Element vector and other vectors*/8013 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8014 IssmDouble* basis = xNew<IssmDouble>(numnodes);8015 8016 /*Retrieve all inputs and parameters*/8017 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8018 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);8019 damage_input = this->material->inputs->GetInput(DamageDbarEnum); _assert_(damage_input);8020 8021 /*retrieve damage evolution forcing function: */8022 this->DamageEvolutionF(&f_list[0]);8023 8024 /*Initialize forcing function f to 0, do not forget!:*/8025 /* Start looping on the number of gaussian points: */8026 GaussTria* gauss=new GaussTria(2);8027 for(int ig=gauss->begin();ig<gauss->end();ig++){8028 8029 gauss->GaussPoint(ig);8030 8031 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8032 GetNodalFunctions(basis,gauss);8033 8034 TriaRef::GetInputValue(&f,f_list,gauss);8035 damage_input->GetInputValue(&damage,gauss);8036 8037 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(damage+dt*f)*basis[i];8038 }8039 8040 /*Clean up and return*/8041 xDelete<IssmDouble>(basis);8042 delete gauss;8043 return pe;8044 6624 } 8045 6625 /*}}}*/ … … 8550 7130 xDelete<IssmDouble>(basis); 8551 7131 return Ke; 8552 }8553 /*}}}*/8554 /*FUNCTION Tria::CreatePVectorBalancethickness{{{*/8555 ElementVector* Tria::CreatePVectorBalancethickness(void){8556 8557 switch(GetElementType()){8558 case P1Enum:8559 return CreatePVectorBalancethickness_CG();8560 break;8561 case P1DGEnum:8562 return CreatePVectorBalancethickness_DG();8563 default:8564 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");8565 }8566 }8567 /*}}}*/8568 /*FUNCTION Tria::CreatePVectorBalancethickness_CG{{{*/8569 ElementVector* Tria::CreatePVectorBalancethickness_CG(void){8570 8571 /*Intermediaries */8572 IssmDouble xyz_list[NUMVERTICES][3];8573 IssmDouble dhdt_g,mb_g,ms_g,Jdet;8574 8575 /*Fetch number of nodes and dof for this finite element*/8576 int numnodes = this->NumberofNodes();8577 8578 /*Initialize Element vector and other vectors*/8579 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8580 IssmDouble* basis = xNew<IssmDouble>(numnodes);8581 8582 /*Retrieve all inputs and parameters*/8583 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8584 Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);8585 Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);8586 Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);8587 8588 /* Start looping on the number of gaussian points: */8589 GaussTria* gauss=new GaussTria(2);8590 for(int ig=gauss->begin();ig<gauss->end();ig++){8591 8592 gauss->GaussPoint(ig);8593 8594 ms_input->GetInputValue(&ms_g,gauss);8595 mb_input->GetInputValue(&mb_g,gauss);8596 dhdt_input->GetInputValue(&dhdt_g,gauss);8597 8598 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8599 GetNodalFunctions(basis,gauss);8600 8601 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*basis[i];8602 }8603 8604 /*Clean up and return*/8605 xDelete<IssmDouble>(basis);8606 delete gauss;8607 return pe;8608 }8609 /*}}}*/8610 /*FUNCTION Tria::CreatePVectorBalancethickness_DG {{{*/8611 ElementVector* Tria::CreatePVectorBalancethickness_DG(void){8612 8613 /*Intermediaries */8614 IssmDouble xyz_list[NUMVERTICES][3];8615 IssmDouble mb_g,ms_g,dhdt_g,Jdet;8616 8617 /*Fetch number of nodes and dof for this finite element*/8618 int numnodes = this->NumberofNodes();8619 8620 /*Initialize Element vector and other vectors*/8621 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8622 IssmDouble* basis = xNew<IssmDouble>(numnodes);8623 8624 /*Retrieve all inputs and parameters*/8625 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8626 Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);8627 Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);8628 Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum);_assert_(dhdt_input);8629 8630 /* Start looping on the number of gaussian points: */8631 GaussTria* gauss=new GaussTria(2);8632 for(int ig=gauss->begin();ig<gauss->end();ig++){8633 8634 gauss->GaussPoint(ig);8635 8636 ms_input->GetInputValue(&ms_g,gauss);8637 mb_input->GetInputValue(&mb_g,gauss);8638 dhdt_input->GetInputValue(&dhdt_g,gauss);8639 8640 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8641 GetNodalFunctions(basis,gauss);8642 8643 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*basis[i];8644 }8645 8646 /*Clean up and return*/8647 xDelete<IssmDouble>(basis);8648 delete gauss;8649 return pe;8650 }8651 /*}}}*/8652 /*FUNCTION Tria::CreatePVectorBalancevelocity{{{*/8653 ElementVector* Tria::CreatePVectorBalancevelocity(void){8654 8655 /*Intermediaries */8656 IssmDouble xyz_list[NUMVERTICES][3];8657 IssmDouble dhdt_g,mb_g,ms_g,Jdet;8658 IssmDouble h,gamma,thickness;8659 IssmDouble hnx,hny,dhnx[2],dhny[2];8660 8661 /*Fetch number of nodes and dof for this finite element*/8662 int numnodes = this->NumberofNodes();8663 8664 /*Initialize Element vector and other vectors*/8665 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8666 IssmDouble* basis = xNew<IssmDouble>(numnodes);8667 IssmDouble* dbasis = xNew<IssmDouble>(numnodes*2);8668 IssmDouble* H = xNew<IssmDouble>(numnodes);8669 IssmDouble* Nx = xNew<IssmDouble>(numnodes);8670 IssmDouble* Ny = xNew<IssmDouble>(numnodes);8671 8672 /*Retrieve all inputs and parameters*/8673 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8674 Input* ms_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(ms_input);8675 Input* mb_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);8676 Input* dhdt_input=inputs->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);8677 Input* H_input=inputs->GetInput(ThicknessEnum); _assert_(H_input);8678 h=sqrt(2.*this->GetArea());8679 8680 /*Get vector N for all nodes*/8681 GetInputListOnNodes(Nx,SurfaceSlopeXEnum);8682 GetInputListOnNodes(Ny,SurfaceSlopeYEnum);8683 GetInputListOnNodes(H,ThicknessEnum);8684 for(int i=0;i<numnodes;i++){8685 IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);8686 Nx[i] = -H[i]*Nx[i]/norm;8687 Ny[i] = -H[i]*Ny[i]/norm;8688 }8689 8690 /* Start looping on the number of gaussian points: */8691 GaussTria* gauss=new GaussTria(2);8692 for(int ig=gauss->begin();ig<gauss->end();ig++){8693 8694 gauss->GaussPoint(ig);8695 8696 ms_input->GetInputValue(&ms_g,gauss);8697 mb_input->GetInputValue(&mb_g,gauss);8698 dhdt_input->GetInputValue(&dhdt_g,gauss);8699 H_input->GetInputValue(&thickness,gauss);8700 if(thickness<50.) thickness=50.;8701 8702 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8703 GetNodalFunctions(basis,gauss);8704 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);8705 8706 TriaRef::GetInputDerivativeValue(&dhnx[0],Nx,&xyz_list[0][0],gauss);8707 TriaRef::GetInputDerivativeValue(&dhny[0],Ny,&xyz_list[0][0],gauss);8708 TriaRef::GetInputValue(&hnx,Nx,gauss);8709 TriaRef::GetInputValue(&hny,Ny,gauss);8710 8711 gamma=h/(2.*thickness+1.e-10);8712 8713 for(int i=0;i<numnodes;i++){8714 pe->values[i]+=Jdet*gauss->weight*(ms_g-mb_g-dhdt_g)*(8715 basis[i] + gamma*(basis[i]*(dhnx[0]+dhny[1])+hnx*dbasis[0*numnodes+i] + hny*dbasis[1*numnodes+i])8716 );8717 }8718 }8719 8720 /*Clean up and return*/8721 xDelete<IssmDouble>(basis);8722 xDelete<IssmDouble>(dbasis);8723 xDelete<IssmDouble>(H);8724 xDelete<IssmDouble>(Nx);8725 xDelete<IssmDouble>(Ny);8726 delete gauss;8727 return pe;8728 }8729 /*}}}*/8730 /*FUNCTION Tria::CreatePVectorSmoothedSlopeX{{{*/8731 ElementVector* Tria::CreatePVectorSmoothedSlopeX(void){8732 8733 /*Intermediaries */8734 IssmDouble xyz_list[NUMVERTICES][3];8735 IssmDouble Jdet;8736 IssmDouble thickness,slope[2];8737 IssmDouble taud_x,norms,normv,vx,vy;8738 8739 /*Fetch number of nodes and dof for this finite element*/8740 int numnodes = this->NumberofNodes();8741 8742 /*Initialize Element vector and other vectors*/8743 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8744 IssmDouble* basis = xNew<IssmDouble>(numnodes);8745 8746 /*Retrieve all inputs and parameters*/8747 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8748 Input* H_input = inputs->GetInput(ThicknessEnum); _assert_(H_input);8749 Input* surface_input = inputs->GetInput(SurfaceEnum); _assert_(surface_input);8750 Input* vx_input = inputs->GetInput(VxEnum);8751 Input* vy_input = inputs->GetInput(VyEnum);8752 8753 /* Start looping on the number of gaussian points: */8754 GaussTria* gauss=new GaussTria(2);8755 for(int ig=gauss->begin();ig<gauss->end();ig++){8756 8757 gauss->GaussPoint(ig);8758 8759 H_input->GetInputValue(&thickness,gauss);8760 surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);8761 if(vx_input && vy_input){8762 vx_input->GetInputValue(&vx,gauss);8763 vy_input->GetInputValue(&vy,gauss);8764 norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);8765 normv = sqrt(vx*vx + vy*vy);8766 if(normv>15./(365.*24.*3600.)) slope[0] = -vx/normv*norms;8767 }8768 taud_x = matpar->GetRhoIce()*matpar->GetG()*thickness*slope[0];8769 8770 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8771 GetNodalFunctions(basis,gauss);8772 8773 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_x*basis[i];8774 }8775 8776 /*Clean up and return*/8777 xDelete<IssmDouble>(basis);8778 delete gauss;8779 return pe;8780 }8781 /*}}}*/8782 /*FUNCTION Tria::CreatePVectorSmoothedSlopeY{{{*/8783 ElementVector* Tria::CreatePVectorSmoothedSlopeY(void){8784 8785 /*Intermediaries */8786 IssmDouble xyz_list[NUMVERTICES][3];8787 IssmDouble Jdet;8788 IssmDouble thickness,slope[2];8789 IssmDouble taud_y,norms,normv,vx,vy;8790 8791 /*Fetch number of nodes and dof for this finite element*/8792 int numnodes = this->NumberofNodes();8793 8794 /*Initialize Element vector and other vectors*/8795 ElementVector* pe = new ElementVector(nodes,numnodes,this->parameters);8796 IssmDouble* basis = xNew<IssmDouble>(numnodes);8797 8798 /*Retrieve all inputs and parameters*/8799 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);8800 Input* H_input = inputs->GetInput(ThicknessEnum); _assert_(H_input);8801 Input* surface_input = inputs->GetInput(SurfaceEnum); _assert_(surface_input);8802 Input* vx_input = inputs->GetInput(VxEnum);8803 Input* vy_input = inputs->GetInput(VyEnum);8804 8805 /* Start looping on the number of gaussian points: */8806 GaussTria* gauss=new GaussTria(2);8807 for(int ig=gauss->begin();ig<gauss->end();ig++){8808 8809 gauss->GaussPoint(ig);8810 8811 H_input->GetInputValue(&thickness,gauss);8812 surface_input->GetInputDerivativeValue(&slope[0],&xyz_list[0][0],gauss);8813 if(vx_input && vy_input){8814 vx_input->GetInputValue(&vx,gauss);8815 vy_input->GetInputValue(&vy,gauss);8816 norms = sqrt(slope[0]*slope[0]+slope[1]*slope[1]+1.e-10);8817 normv = sqrt(vx*vx + vy*vy);8818 if(normv>15./(365.*24.*3600.)) slope[1] = -vy/normv*norms;8819 }8820 taud_y = matpar->GetRhoIce()*matpar->GetG()*thickness*slope[1];8821 8822 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);8823 GetNodalFunctions(basis,gauss);8824 8825 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*taud_y*basis[i];8826 }8827 8828 /*Clean up and return*/8829 xDelete<IssmDouble>(basis);8830 delete gauss;8831 return pe;8832 7132 } 8833 7133 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r16956 r16982 222 222 ElementMatrix* CreateMassMatrix(void); 223 223 ElementMatrix* CreateBasalMassMatrix(void); 224 ElementVector* CreatePVector(void);225 ElementVector* CreatePVectorBalancethickness(void);226 ElementVector* CreatePVectorBalancethickness_DG(void);227 ElementVector* CreatePVectorBalancethickness_CG(void);228 ElementVector* CreatePVectorBalancevelocity(void);229 ElementVector* CreatePVectorSmoothedSlopeX(void);230 ElementVector* CreatePVectorSmoothedSlopeY(void);231 ElementVector* CreatePVectorMasstransport(void);232 ElementVector* CreatePVectorMasstransport_CG(void);233 ElementVector* CreatePVectorMasstransport_DG(void);234 ElementVector* CreatePVectorFreeSurfaceTop(void);235 ElementVector* CreatePVectorFreeSurfaceTop1D(void);236 ElementVector* CreatePVectorFreeSurfaceBase(void);237 ElementVector* CreatePVectorFreeSurfaceBase1D(void);238 ElementVector* CreatePVectorL2Projection(void);239 ElementVector* CreatePVectorL2ProjectionBase(void);240 224 IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){_error_("not implemented");}; 241 225 IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){_error_("not implemented");}; … … 306 290 ElementMatrix* CreateKMatrixStressbalanceFSViscous(void); 307 291 ElementMatrix* CreateKMatrixStressbalanceFSFriction(void); 308 ElementVector* CreatePVectorStressbalanceSSA(void);309 ElementVector* CreatePVectorStressbalanceSSADrivingStress(void);310 ElementVector* CreatePVectorStressbalanceSSAFront(void);311 ElementVector* CreatePVectorStressbalanceSIA(void);312 ElementVector* CreatePVectorStressbalanceFS(void);313 ElementVector* CreatePVectorStressbalanceFSFront(void);314 ElementVector* CreatePVectorStressbalanceFSViscous(void);315 292 void PVectorGLSstabilization(ElementVector* pe); 316 ElementVector* CreatePVectorStressbalanceFSShelf(void);317 293 ElementMatrix* CreateJacobianStressbalanceSSA(void); 318 294 IssmDouble GetYcoord(GaussTria* gauss); … … 322 298 ElementMatrix* CreateKMatrixAdjointBalancethickness(void); 323 299 ElementMatrix* CreateKMatrixAdjointSSA(void); 324 ElementVector* CreatePVectorAdjointHoriz(void);325 ElementVector* CreatePVectorAdjointBalancethickness(void);326 300 #endif 327 301 … … 339 313 ElementMatrix* CreateKMatrixHydrologyDCEfficient(void); 340 314 ElementMatrix* CreateEPLDomainMassMatrix(void); 341 ElementVector* CreatePVectorHydrologyShreve(void);342 ElementVector* CreatePVectorHydrologyDCInefficient(void);343 ElementVector* CreatePVectorHydrologyDCEfficient(void);344 ElementVector* CreatePVectorL2ProjectionEPL(void);345 315 void CreateHydrologyWaterVelocityInput(void); 346 316 void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,int index); … … 356 326 ElementMatrix* CreateKMatrixDamageEvolution(void); 357 327 ElementMatrix* CreateKMatrixDamageEvolution_CG(void); 358 ElementVector* CreatePVectorDamageEvolution(void);359 ElementVector* CreatePVectorDamageEvolution_CG(void);360 328 void DamageEvolutionF(IssmDouble* flist); 361 329 #endif -
issm/trunk-jpl/src/c/modules/SystemMatricesx/SystemMatricesx.cpp
r16819 r16982 42 42 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 43 43 ElementMatrix* Ke = element->CreateKMatrix(); 44 ElementVector* pe = element->CreatePVector(); 44 //ElementVector* pe = element->CreatePVector(); 45 ElementVector* pe = analysis->CreatePVector(element); 45 46 element->ReduceMatrices(Ke,pe); 46 47 if(Ke) Ke->AddToGlobal(Kff_temp,NULL); … … 72 73 for (i=0;i<femmodel->elements->Size();i++){ 73 74 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 74 //ElementVector* pe = analysis->CreatePVector(element);75 ElementMatrix* Ke = element->CreateKMatrix(); 75 76 //ElementMatrix* Ke = analysis->CreateKMatrix(element); 76 ElementVector* pe = element->CreatePVector();77 Element Matrix* Ke = element->CreateKMatrix();77 //ElementVector* pe = element->CreatePVector(); 78 ElementVector* pe = analysis->CreatePVector(element); 78 79 element->ReduceMatrices(Ke,pe); 79 80 if(Ke) Ke->AddToGlobal(Kff,Kfs);
Note:
See TracChangeset
for help on using the changeset viewer.