Changeset 27572
- Timestamp:
- 02/14/23 05:09:07 (2 years ago)
- Location:
- issm/trunk-jpl/src/c/analyses
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/AgeAnalysis.cpp
r27154 r27572 92 92 }/*}}}*/ 93 93 ElementMatrix* AgeAnalysis::CreateKMatrix(Element* element){/*{{{*/ 94 95 _error_("STOP");96 /* Check if ice in element */97 if(!element->IsIceInElement()) return NULL;98 99 /*compute all stiffness matrices for this element*/100 ElementMatrix* Ke1=CreateKMatrixVolume(element);101 ElementMatrix* Ke2=CreateKMatrixShelf(element);102 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);103 104 /*clean-up and return*/105 delete Ke1;106 delete Ke2;107 return Ke;108 }/*}}}*/109 ElementMatrix* AgeAnalysis::CreateKMatrixShelf(Element* element){/*{{{*/110 111 /* Check if ice in element */112 if(!element->IsIceInElement()) return NULL;113 114 /*Initialize Element matrix and return if necessary*/115 if(!element->IsOnBase() || !element->IsAllFloating()) return NULL;116 117 IssmDouble dt,Jdet,D;118 IssmDouble *xyz_list_base = NULL;119 120 /*Get basal element*/121 if(!element->IsOnBase() || !element->IsAllFloating()) return NULL;122 123 /*Fetch number of nodes for this finite element*/124 int numnodes = element->GetNumberOfNodes();125 126 /*Initialize vectors*/127 ElementMatrix* Ke = element->NewElementMatrix();128 IssmDouble* basis = xNew<IssmDouble>(numnodes);129 130 /*Retrieve all inputs and parameters*/131 element->GetVerticesCoordinatesBase(&xyz_list_base);132 element->FindParam(&dt,TimesteppingTimeStepEnum);133 IssmDouble gravity = element->FindParam(ConstantsGEnum);134 IssmDouble rho_water = element->FindParam(MaterialsRhoSeawaterEnum);135 IssmDouble rho_ice = element->FindParam(MaterialsRhoIceEnum);136 IssmDouble heatcapacity = element->FindParam(MaterialsHeatcapacityEnum);137 IssmDouble mixed_layer_capacity= element->FindParam(MaterialsMixedLayerCapacityEnum);138 139 /* Start looping on the number of gaussian points: */140 Gauss* gauss=element->NewGaussBase(4);141 while(gauss->next()){142 143 element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);144 element->NodalFunctions(basis,gauss);145 146 D=gauss->weight*Jdet*rho_water*mixed_layer_capacity/(heatcapacity*rho_ice);147 if(reCast<bool,IssmDouble>(dt)) D=dt*D;148 for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j] += D*basis[i]*basis[j];149 }150 151 /*Clean up and return*/152 delete gauss;153 xDelete<IssmDouble>(basis);154 xDelete<IssmDouble>(xyz_list_base);155 return Ke;156 }/*}}}*/157 ElementMatrix* AgeAnalysis::CreateKMatrixVolume(Element* element){/*{{{*/158 94 159 95 /* Check if ice in element */ … … 303 239 if(!element->IsIceInElement()) return NULL; 304 240 305 /*compute all load vectors for this element*/306 ElementVector* pe1=CreatePVectorVolume(element);307 ElementVector* pe2=CreatePVectorSheet(element);308 ElementVector* pe3=CreatePVectorShelf(element);309 ElementVector* pe =new ElementVector(pe1,pe2,pe3);310 311 /*clean-up and return*/312 delete pe1;313 delete pe2;314 delete pe3;315 return pe;316 }/*}}}*/317 ElementVector* AgeAnalysis::CreatePVectorSheet(Element* element){/*{{{*/318 319 /* Check if ice in element */320 if(!element->IsIceInElement()) return NULL;321 322 /* Geothermal flux on ice sheet base and basal friction */323 if(!element->IsOnBase() || element->IsAllFloating()) return NULL;324 325 IssmDouble dt,Jdet,geothermalflux,vx,vy,vz;326 IssmDouble alpha2,scalar,basalfriction,heatflux;327 IssmDouble *xyz_list_base = NULL;328 329 /*Fetch number of nodes for this finite element*/330 int numnodes = element->GetNumberOfNodes();331 332 /*Initialize vectors*/333 ElementVector* pe = element->NewElementVector();334 IssmDouble* basis = xNew<IssmDouble>(numnodes);335 336 /*Retrieve all inputs and parameters*/337 element->GetVerticesCoordinatesBase(&xyz_list_base);338 element->FindParam(&dt,TimesteppingTimeStepEnum);339 Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input);340 Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input);341 Input* vz_input = element->GetInput(VzEnum); _assert_(vz_input);342 Input* geothermalflux_input = element->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);343 IssmDouble rho_ice = element->FindParam(MaterialsRhoIceEnum);344 IssmDouble heatcapacity = element->FindParam(MaterialsHeatcapacityEnum);345 346 /*Build friction element, needed later: */347 Friction* friction=new Friction(element,3);348 349 /* Start looping on the number of gaussian points: */350 Gauss* gauss = element->NewGaussBase(4);351 while(gauss->next()){352 353 element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);354 element->NodalFunctions(basis,gauss);355 356 geothermalflux_input->GetInputValue(&geothermalflux,gauss);357 friction->GetAlpha2(&alpha2,gauss);358 vx_input->GetInputValue(&vx,gauss);359 vy_input->GetInputValue(&vy,gauss);360 vz_input->GetInputValue(&vz,gauss);361 vz = 0.;//FIXME362 basalfriction = alpha2*(vx*vx + vy*vy + vz*vz);363 heatflux = (basalfriction+geothermalflux)/(rho_ice*heatcapacity);364 365 scalar = gauss->weight*Jdet*heatflux;366 if(dt!=0.) scalar=dt*scalar;367 368 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar*basis[i];369 }370 371 /*Clean up and return*/372 delete gauss;373 delete friction;374 xDelete<IssmDouble>(basis);375 xDelete<IssmDouble>(xyz_list_base);376 return pe;377 }/*}}}*/378 ElementVector* AgeAnalysis::CreatePVectorShelf(Element* element){/*{{{*/379 380 /* Check if ice in element */381 if(!element->IsIceInElement()) return NULL;382 383 IssmDouble t_pmp,dt,Jdet,scalar_ocean,pressure;384 IssmDouble *xyz_list_base = NULL;385 386 /*Get basal element*/387 if(!element->IsOnBase() || !element->IsAllFloating()) return NULL;388 389 /*Fetch number of nodes for this finite element*/390 int numnodes = element->GetNumberOfNodes();391 392 /*Initialize vectors*/393 ElementVector* pe = element->NewElementVector();394 IssmDouble* basis = xNew<IssmDouble>(numnodes);395 396 /*Retrieve all inputs and parameters*/397 element->GetVerticesCoordinatesBase(&xyz_list_base);398 element->FindParam(&dt,TimesteppingTimeStepEnum);399 Input* pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);400 IssmDouble gravity = element->FindParam(ConstantsGEnum);401 IssmDouble rho_water = element->FindParam(MaterialsRhoSeawaterEnum);402 IssmDouble rho_ice = element->FindParam(MaterialsRhoIceEnum);403 IssmDouble heatcapacity = element->FindParam(MaterialsHeatcapacityEnum);404 IssmDouble mixed_layer_capacity= element->FindParam(MaterialsMixedLayerCapacityEnum);405 406 /* Start looping on the number of gaussian points: */407 Gauss* gauss=element->NewGaussBase(4);408 while(gauss->next()){409 410 element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);411 element->NodalFunctions(basis,gauss);412 413 pressure_input->GetInputValue(&pressure,gauss);414 t_pmp=element->TMeltingPoint(pressure);415 416 scalar_ocean=gauss->weight*Jdet*rho_water*mixed_layer_capacity*(t_pmp)/(heatcapacity*rho_ice);417 if(reCast<bool,IssmDouble>(dt)) scalar_ocean=dt*scalar_ocean;418 419 for(int i=0;i<numnodes;i++) pe->values[i]+=scalar_ocean*basis[i];420 }421 422 /*Clean up and return*/423 delete gauss;424 xDelete<IssmDouble>(basis);425 xDelete<IssmDouble>(xyz_list_base);426 return pe;427 }/*}}}*/428 ElementVector* AgeAnalysis::CreatePVectorVolume(Element* element){/*{{{*/429 430 /* Check if ice in element */431 if(!element->IsIceInElement()) return NULL;432 433 241 /*Intermediaries*/ 434 242 int stabilization; 435 IssmDouble Jdet, phi,dt;243 IssmDouble Jdet,dt; 436 244 IssmDouble temperature; 437 245 IssmDouble tau_parameter,diameter,hx,hy,hz; … … 451 259 /*Retrieve all inputs and parameters*/ 452 260 element->GetVerticesCoordinates(&xyz_list); 453 IssmDouble rho_ice = element->FindParam(MaterialsRhoIceEnum);454 IssmDouble heatcapacity = element->FindParam(MaterialsHeatcapacityEnum);455 IssmDouble thermalconductivity = 1.;456 IssmDouble kappa = thermalconductivity/(rho_ice*heatcapacity);457 261 element->FindParam(&dt,TimesteppingTimeStepEnum); 458 262 element->FindParam(&stabilization,AgeStabilizationEnum); … … 469 273 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 470 274 element->NodalFunctions(basis,gauss); 471 element->ViscousHeating(&phi,xyz_list,gauss,vx_input,vy_input,vz_input); 472 473 scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss->weight; 275 276 scalar_def=1.*Jdet*gauss->weight; 474 277 if(reCast<bool,IssmDouble>(dt)) scalar_def=scalar_def*dt; 475 278 … … 490 293 vz_input->GetInputValue(&w,gauss); 491 294 492 tau_parameter=element->StabilizationParameter(u,v,w,diameter, kappa);295 tau_parameter=element->StabilizationParameter(u,v,w,diameter,1.e-15); //assume very small conductivity to get tau 493 296 494 297 for(int i=0;i<numnodes;i++) pe->values[i]+=tau_parameter*scalar_def*(u*dbasis[0*numnodes+i]+v*dbasis[1*numnodes+i]+w*dbasis[2*numnodes+i]); … … 504 307 vy_input->GetInputValue(&v,gauss); 505 308 vz_input->GetInputValue(&w,gauss); 506 element->StabilizationParameterAnisotropic(&tau_parameter_anisotropic[0],u,v,w,hx,hy,hz, kappa);309 element->StabilizationParameterAnisotropic(&tau_parameter_anisotropic[0],u,v,w,hx,hy,hz,1.e-15); //assume very small conductivity to get tau 507 310 tau_parameter_hor=tau_parameter_anisotropic[0]; 508 311 tau_parameter_ver=tau_parameter_anisotropic[1]; … … 518 321 delete gauss; 519 322 return pe; 520 521 323 }/*}}}*/ 522 324 void AgeAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/ … … 533 335 void AgeAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/ 534 336 SetActiveNodesLSMx(femmodel); 535 536 337 _error_("Should also automatically constrain surface/basal nodes where we have inflow"); 537 }/*}}}*/ 338 339 /*Constrain all nodes that are grounded and unconstrain the ones that float*/ 340 for(Object* & object : femmodel->elements->objects){ 341 Element *element = xDynamicCast<Element*>(object); 342 343 if(element->IsOnSurface()){ 344 element = element->SpawnTopElement(); 345 int numnodes = element->GetNumberOfNodes(); 346 IssmDouble *mask = xNew<IssmDouble>(numnodes); 347 IssmDouble *bed = xNew<IssmDouble>(numnodes); 348 IssmDouble *ls_active = xNew<IssmDouble>(numnodes); 349 350 element->GetInputListOnNodes(&mask[0],MaskOceanLevelsetEnum); 351 element->GetInputListOnNodes(&bed[0],BaseEnum); 352 element->GetInputListOnNodes(&ls_active[0],IceMaskNodeActivationEnum); 353 354 for(int in=0;in<numnodes;in++){ 355 Node* node=element->GetNode(in); 356 if(mask[in]<0. && ls_active[in]==1.){ 357 node->Activate(); 358 } 359 else{ 360 node->Deactivate(); 361 node->ApplyConstraint(0,bed[in]); 362 } 363 } 364 xDelete<IssmDouble>(mask); 365 xDelete<IssmDouble>(bed); 366 xDelete<IssmDouble>(ls_active); 367 } 368 else if(element->IsOnBase()){ 369 element = element->SpawnBasalElement(); 370 _error_("not supported"); 371 } 372 } 373 }/*}}}*/ -
issm/trunk-jpl/src/c/analyses/AgeAnalysis.h
r27154 r27572 26 26 ElementMatrix* CreateJacobianMatrix(Element* element); 27 27 ElementMatrix* CreateKMatrix(Element* element); 28 ElementMatrix* CreateKMatrixShelf(Element* element);29 ElementMatrix* CreateKMatrixVolume(Element* element);30 28 ElementVector* CreatePVector(Element* element); 31 ElementVector* CreatePVectorSheet(Element* element);32 ElementVector* CreatePVectorShelf(Element* element);33 ElementVector* CreatePVectorVolume(Element* element);34 29 void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element); 35 30 void GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_interp,int control_index);
Note:
See TracChangeset
for help on using the changeset viewer.