Changeset 4285
- Timestamp:
- 06/28/10 23:22:14 (15 years ago)
- Location:
- issm/trunk/src/c
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/modules/ModelProcessorx/CreateDataSets.cpp
r4218 r4285 58 58 59 59 case SlopeAnalysisEnum: 60 CreateNodesSlopeCompute(pnodes, iomodel,iomodel_handle); 61 CreateConstraintsSlopeCompute(pconstraints,iomodel,iomodel_handle); 62 CreateLoadsSlopeCompute(ploads,iomodel,iomodel_handle); 63 UpdateElementsSlopeCompute(elements,iomodel,iomodel_handle,analysis_counter,analysis_type); 64 break; 65 66 case BedSlopeAnalysisEnum: 67 CreateNodesSlopeCompute(pnodes, iomodel,iomodel_handle); 68 CreateConstraintsSlopeCompute(pconstraints,iomodel,iomodel_handle); 69 CreateLoadsSlopeCompute(ploads,iomodel,iomodel_handle); 70 UpdateElementsSlopeCompute(elements,iomodel,iomodel_handle,analysis_counter,analysis_type); 71 break; 72 73 case SurfaceSlopeAnalysisEnum: 60 74 CreateNodesSlopeCompute(pnodes, iomodel,iomodel_handle); 61 75 CreateConstraintsSlopeCompute(pconstraints,iomodel,iomodel_handle); -
issm/trunk/src/c/objects/Elements/Penta.cpp
r4280 r4285 324 324 InputUpdateFromSolutionDiagnosticStokes( solution); 325 325 } 326 else if (analysis_type== SlopeAnalysisEnum){326 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 327 327 InputUpdateFromSolutionSlopeCompute( solution); 328 328 } … … 664 664 CreateKMatrixDiagnosticStokes( Kgg); 665 665 } 666 else if (analysis_type== SlopeAnalysisEnum){666 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 667 667 CreateKMatrixSlopeCompute( Kgg); 668 668 } … … 714 714 CreatePVectorDiagnosticStokes( pg); 715 715 } 716 else if (analysis_type== SlopeAnalysisEnum){716 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 717 717 CreatePVectorSlopeCompute( pg); 718 718 } -
issm/trunk/src/c/objects/Elements/Sing.cpp
r4248 r4285 31 31 } 32 32 /*}}}*/ 33 /*FUNCTION void Sing::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type);{{{1*/34 void Sing::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){35 ISSMERROR(" not supported yet!");36 }37 /*}}}*/38 33 39 34 /*Object virtual functions definitions: */ 35 /*FUNCTION Sing::copy {{{1*/ 36 Object* Sing::copy() { 37 38 int i; 39 Sing* sing=NULL; 40 41 sing=new Sing(); 42 43 /*copy fields: */ 44 sing->id=this->id; 45 if(this->inputs){ 46 sing->inputs=(Inputs*)this->inputs->Copy(); 47 } 48 else{ 49 sing->inputs=new Inputs(); 50 } 51 /*point parameters: */ 52 sing->parameters=this->parameters; 53 54 /*pointers: */ 55 sing->node=this->node; 56 sing->matice=this->matice; 57 sing->matpar=this->matpar; 58 59 return sing; 60 } 61 /*}}}*/ 62 /*FUNCTION Sing::DeepEcho {{{1*/ 63 void Sing::DeepEcho(void){ 64 65 printf("Sing:\n"); 66 printf(" id: %i\n",id); 67 node->DeepEcho(); 68 matice->DeepEcho(); 69 matpar->DeepEcho(); 70 printf(" parameters\n"); 71 parameters->DeepEcho(); 72 printf(" inputs\n"); 73 inputs->DeepEcho(); 74 75 return; 76 } 77 /*}}}*/ 78 /*FUNCTION Sing::Demarshall {{{1*/ 79 void Sing::Demarshall(char** pmarshalled_dataset){ 80 ISSMERROR(" not supported yet!"); 81 } 82 /*}}}*/ 40 83 /*FUNCTION Sing::Echo{{{1*/ 41 84 … … 53 96 } 54 97 /*}}}*/ 55 /*FUNCTION Sing::DeepEcho {{{1*/ 56 void Sing::DeepEcho(void){ 57 58 printf("Sing:\n"); 59 printf(" id: %i\n",id); 60 node->DeepEcho(); 61 matice->DeepEcho(); 62 matpar->DeepEcho(); 63 printf(" parameters\n"); 64 parameters->DeepEcho(); 65 printf(" inputs\n"); 66 inputs->DeepEcho(); 67 68 return; 98 /*FUNCTION Sing::Enum {{{1*/ 99 int Sing::Enum(void){ 100 101 return SingEnum; 102 69 103 } 70 104 /*}}}*/ 71 105 /*FUNCTION Sing::Id {{{1*/ 72 106 int Sing::Id(void){ return id; } 107 /*}}}*/ 108 /*FUNCTION Sing::Marshall {{{1*/ 109 void Sing::Marshall(char** pmarshalled_dataset){ 110 ISSMERROR(" not supported yet!"); 111 } 112 /*}}}*/ 113 /*FUNCTION Sing::MashallSize {{{1*/ 114 int Sing::MarshallSize(){ 115 ISSMERROR(" not supported yet!"); 116 } 73 117 /*}}}*/ 74 118 /*FUNCTION Sing::MyRank {{{1*/ … … 78 122 } 79 123 /*}}}*/ 80 /*FUNCTION Sing::Marshall {{{1*/ 81 void Sing::Marshall(char** pmarshalled_dataset){ 82 ISSMERROR(" not supported yet!"); 83 } 84 /*}}}*/ 85 /*FUNCTION Sing::MashallSize {{{1*/ 86 int Sing::MarshallSize(){ 87 ISSMERROR(" not supported yet!"); 88 } 89 /*}}}*/ 90 /*FUNCTION Sing::Demarshall {{{1*/ 91 void Sing::Demarshall(char** pmarshalled_dataset){ 92 ISSMERROR(" not supported yet!"); 93 } 94 /*}}}*/ 95 /*FUNCTION Sing::Enum {{{1*/ 96 int Sing::Enum(void){ 97 98 return SingEnum; 99 100 } 101 /*}}}*/ 102 /*FUNCTION Sing::copy {{{1*/ 103 Object* Sing::copy() { 104 105 int i; 106 Sing* sing=NULL; 107 108 sing=new Sing(); 109 110 /*copy fields: */ 111 sing->id=this->id; 112 if(this->inputs){ 113 sing->inputs=(Inputs*)this->inputs->Copy(); 114 } 115 else{ 116 sing->inputs=new Inputs(); 117 } 118 /*point parameters: */ 119 sing->parameters=this->parameters; 120 121 /*pointers: */ 122 sing->node=this->node; 123 sing->matice=this->matice; 124 sing->matpar=this->matpar; 125 126 return sing; 127 } 128 /*}}}*/ 129 130 /*Sing management*/ 124 125 /*Update virtual functions definitions: */ 126 /*FUNCTION Sing::InputUpdateFromSolution {{{1*/ 127 void Sing::InputUpdateFromSolution(double* solution){ 128 ISSMERROR(" not supported yet!"); 129 } 130 /*}}}*/ 131 /*FUNCTION Sing::InputUpdateFromVector(double* vector, int name, int type);{{{1*/ 132 void Sing::InputUpdateFromVector(double* vector, int name, int type){ 133 134 /*Check that name is an element input*/ 135 if (!IsInput(name)) return; 136 137 switch(type){ 138 139 case VertexEnum: 140 141 /*New SingVertexInpu*/ 142 double value; 143 144 /*Get values on the 6 vertices*/ 145 value=vector[node->GetVertexDof()]; 146 147 /*update input*/ 148 this->inputs->AddInput(new SingVertexInput(name,value)); 149 return; 150 151 default: 152 ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type)); 153 } 154 } 155 /*}}}*/ 156 /*FUNCTION Sing::InputUpdateFromVector(int* vector, int name, int type);{{{1*/ 157 void Sing::InputUpdateFromVector(int* vector, int name, int type){ 158 ISSMERROR(" not supported yet!"); 159 } 160 /*}}}*/ 161 /*FUNCTION Sing::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/ 162 void Sing::InputUpdateFromVector(bool* vector, int name, int type){ 163 ISSMERROR(" not supported yet!"); 164 } 165 /*}}}*/ 166 167 /*Element virtual functions definitions: */ 168 /*FUNCTION Sing::ComputeBasalStress {{{1*/ 169 void Sing::ComputeBasalStress(Vec p_g){ 170 171 ISSMERROR("Not implemented yet"); 172 173 } 174 /*}}}*/ 175 /*FUNCTION Sing::ComputePressure {{{1*/ 176 void Sing::ComputePressure(Vec p_g){ 177 178 int dof; 179 double pressure; 180 double thickness; 181 double rho_ice,g; 182 183 /*Get dof list on which we will plug the pressure values: */ 184 GetDofList1(&dof); 185 186 /*pressure is lithostatic: */ 187 rho_ice=matpar->GetRhoIce(); 188 g=matpar->GetG(); 189 inputs->GetParameterValue(&thickness,ThicknessEnum); 190 pressure=rho_ice*g*thickness; 191 192 /*plug local pressure values into global pressure vector: */ 193 VecSetValue(p_g,dof,pressure,INSERT_VALUES); 194 195 } 196 /*}}}*/ 197 /*FUNCTION Sing::ComputeStrainRate {{{1*/ 198 void Sing::ComputeStrainRate(Vec p_g){ 199 200 ISSMERROR("Not implemented yet"); 201 202 } 203 /*}}}*/ 131 204 /*FUNCTION Sing::Configure {{{1*/ 132 205 void Sing::Configure(Elements* elementsin,Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){ … … 136 209 } 137 210 /*}}}*/ 211 /*FUNCTION Sing::CostFunction {{{1*/ 212 double Sing::CostFunction(){ 213 ISSMERROR(" not supported yet!"); 214 } 215 /*}}}*/ 216 /*FUNCTION Sing::CreateKMatrix {{{1*/ 217 218 void Sing::CreateKMatrix(Mat Kgg){ 219 220 int analysis_type; 221 222 /*retrive parameters: */ 223 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 224 225 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */ 226 if (analysis_type==DiagnosticHutterAnalysisEnum){ 227 CreateKMatrixDiagnosticHutter( Kgg); 228 } 229 else{ 230 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type)); 231 } 232 233 } 234 /*}}}*/ 235 /*FUNCTION Sing::CreatePVector {{{1*/ 236 void Sing::CreatePVector(Vec pg){ 237 238 int analysis_type; 239 240 /*retrive parameters: */ 241 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 242 243 /*Just branch to the correct load generator, according to the type of analysis we are carrying out: */ 244 if (analysis_type==DiagnosticHutterAnalysisEnum){ 245 CreatePVectorDiagnosticHutter( pg); 246 } 247 else{ 248 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type)); 249 } 250 251 } 252 /*}}}*/ 253 /*FUNCTION Sing::Du {{{1*/ 254 void Sing::Du(Vec){ 255 ISSMERROR(" not supported yet!"); 256 } 257 /*}}}*/ 258 /*FUNCTION Sing::GetBedList {{{1*/ 259 void Sing::GetBedList(double*){ 260 ISSMERROR(" not supported yet!"); 261 } 262 /*}}}*/ 263 /*FUNCTION Sing::GetMatPar {{{1*/ 264 void* Sing::GetMatPar(){ 265 266 return matpar; 267 } 268 /*}}}*/ 269 /*FUNCTION Sing::GetNodes {{{1*/ 270 void Sing::GetNodes(void** vpnodes){ 271 272 Node** pnodes=NULL; 273 274 /*recover nodes: */ 275 pnodes=(Node**)vpnodes; 276 277 pnodes[0]=node; 278 } 279 /*}}}*/ 280 /*FUNCTION Sing::GetOnBed {{{1*/ 281 bool Sing::GetOnBed(){ 282 ISSMERROR(" not supported yet!"); 283 } 284 /*}}}*/ 285 /*FUNCTION Sing::GetShelf {{{1*/ 286 bool Sing::GetShelf(){ 287 ISSMERROR(" not supported yet!"); 288 } 289 /*}}}*/ 290 /*FUNCTION Sing::GetSolutionFromInputs(Vec solution);{{{1*/ 291 void Sing::GetSolutionFromInputs(Vec solution){ 292 ISSMERROR(" not supported yet!"); 293 } 294 /*}}}*/ 295 /*FUNCTION Sing::GetThicknessList {{{1*/ 296 void Sing::GetThicknessList(double* thickness_list){ 297 ISSMERROR(" not supported yet!"); 298 } 299 /*}}}*/ 300 /*FUNCTION Sing::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/ 301 void Sing::GetVectorFromInputs(Vec vector,int NameEnum){ 302 303 int i; 304 const int numvertices=1; 305 int doflist1[numvertices]; 306 307 /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */ 308 for(i=0;i<this->inputs->Size();i++){ 309 Input* input=(Input*)this->inputs->GetObjectByOffset(i); 310 if(input->EnumType()==NameEnum){ 311 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */ 312 this->GetDofList1(&doflist1[0]); 313 input->GetVectorFromInputs(vector,&doflist1[0]); 314 break; 315 } 316 } 317 } 318 /*}}}*/ 319 /*FUNCTION Sing::Gradj {{{1*/ 320 void Sing::Gradj(Vec gradient,int control_type){ 321 ISSMERROR(" not supported yet!"); 322 } 323 /*}}}*/ 324 /*FUNCTION Sing::GradB {{{1*/ 325 void Sing::GradjB(Vec gradient){ 326 ISSMERROR(" not supported yet!"); 327 } 328 /*}}}*/ 329 /*FUNCTION Sing::GradjDrag {{{1*/ 330 void Sing::GradjDrag(Vec gradient){ 331 ISSMERROR(" not supported yet!"); 332 } 333 /*}}}*/ 334 /*FUNCTION Sing::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/ 335 void Sing::InputAXPY(int YEnum, double scalar, int XEnum){ 336 337 Input* xinput=NULL; 338 Input* yinput=NULL; 339 340 /*Find x and y inputs: */ 341 xinput=(Input*)this->inputs->GetInput(XEnum); 342 yinput=(Input*)this->inputs->GetInput(YEnum); 343 344 /*some checks: */ 345 if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!"); 346 if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!"); 347 348 /*Scale: */ 349 yinput->AXPY(xinput,scalar); 350 } 351 /*}}}*/ 352 /*FUNCTION Sing::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/ 353 void Sing::InputControlConstrain(int control_type, double cm_min, double cm_max){ 354 355 Input* input=NULL; 356 357 /*Find input: */ 358 input=(Input*)this->inputs->GetInput(control_type); 359 360 /*Do nothing if we don't find it: */ 361 if(!input)return; 362 363 /*Constrain input using cm_min and cm_max: */ 364 input->Constrain(cm_min,cm_max); 365 366 } 367 /*}}}*/ 368 /*FUNCTION Sing::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/ 369 void Sing::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){ 370 371 int i; 372 Input** new_inputs=NULL; 373 Input** old_inputs=NULL; 374 int converged=1; 375 376 new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs 377 old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs 378 379 for(i=0;i<num_enums/2;i++){ 380 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]); 381 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]); 382 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 383 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 384 } 385 386 /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/ 387 for(i=0;i<num_criterionenums;i++){ 388 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]); 389 if(eps[i]>criterionvalues[i]) converged=0; 390 } 391 392 /*Assign output pointers:*/ 393 *pconverged=converged; 394 395 } 396 /*}}}*/ 397 /*FUNCTION Sing::InputDuplicate(int original_enum,int new_enum){{{1*/ 398 void Sing::InputDuplicate(int original_enum,int new_enum){ 399 400 Input* original=NULL; 401 Input* copy=NULL; 402 403 /*Make a copy of the original input: */ 404 original=(Input*)this->inputs->GetInput(original_enum); 405 copy=(Input*)original->copy(); 406 407 /*Change copy enum to reinitialized_enum: */ 408 copy->ChangeEnum(new_enum); 409 410 /*Add copy into inputs, it will wipe off the one already there: */ 411 inputs->AddObject((Input*)copy); 412 } 413 /*}}}*/ 414 /*FUNCTION Sing::InputScale(int enum_type,double scale_factor){{{1*/ 415 void Sing::InputScale(int enum_type,double scale_factor){ 416 417 Input* input=NULL; 418 419 /*Make a copy of the original input: */ 420 input=(Input*)this->inputs->GetInput(enum_type); 421 422 /*Scale: */ 423 input->Scale(scale_factor); 424 } 425 /*}}}*/ 426 /*FUNCTION Sing::InputToResult(int enum_type,int step,double time){{{1*/ 427 void Sing::InputToResult(int enum_type,int step,double time){ 428 ISSMERROR(" not supported yet!"); 429 } 430 /*}}}*/ 431 /*FUNCTION Sing::MassFlux {{{1*/ 432 double Sing::MassFlux( double* segment){ 433 ISSMERROR(" not supported yet!"); 434 } 435 /*}}}*/ 436 /*FUNCTION Sing::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/ 437 void Sing::MaxAbsVx(double* pmaxabsvx, bool process_units){ 438 439 int dim; 440 double maxabsvx; 441 442 /*retrieve dim parameter: */ 443 parameters->FindParam(&dim,DimEnum); 444 445 /*retrive velocity values at nodes */ 446 inputs->GetParameterValue(&maxabsvx,VxEnum); 447 maxabsvx=fabs(maxabsvx); 448 449 /*Assign output pointers:*/ 450 *pmaxabsvx=maxabsvx; 451 } 452 /*}}}*/ 453 /*FUNCTION Sing::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/ 454 void Sing::MaxAbsVy(double* pmaxabsvy, bool process_units){ 455 456 int dim; 457 double maxabsvy; 458 459 /*retrieve dim parameter: */ 460 parameters->FindParam(&dim,DimEnum); 461 462 /*retrive velocity values at nodes */ 463 inputs->GetParameterValue(&maxabsvy,VyEnum); 464 maxabsvy=fabs(maxabsvy); 465 466 /*Assign output pointers:*/ 467 *pmaxabsvy=maxabsvy; 468 } 469 /*}}}*/ 470 /*FUNCTION Sing::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/ 471 void Sing::MaxAbsVz(double* pmaxabsvz, bool process_units){ 472 473 int dim; 474 double maxabsvz; 475 476 /*retrieve dim parameter: */ 477 parameters->FindParam(&dim,DimEnum); 478 479 /*retrive velocity values at nodes */ 480 inputs->GetParameterValue(&maxabsvz,VzEnum); 481 maxabsvz=fabs(maxabsvz); 482 483 /*Assign output pointers:*/ 484 *pmaxabsvz=maxabsvz; 485 } 486 /*}}}*/ 487 /*FUNCTION Sing::MaxVel(double* pmaxvel, bool process_units);{{{1*/ 488 void Sing::MaxVel(double* pmaxvel, bool process_units){ 489 490 int dim; 491 double vx; 492 double vy; 493 double vz; 494 double maxvel; 495 496 /*retrive velocity values at nodes */ 497 inputs->GetParameterValue(&vx,VxEnum); 498 inputs->GetParameterValue(&vy,VyEnum); 499 if(dim==3)inputs->GetParameterValue(&vz,VzEnum); 500 501 /*now, compute maximum of velocity :*/ 502 if(dim==2){ 503 maxvel=sqrt(pow(vx,2)+pow(vy,2)); 504 } 505 else{ 506 maxvel=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2)); 507 } 508 509 /*Assign output pointers:*/ 510 *pmaxvel=maxvel; 511 512 } 513 /*}}}*/ 514 /*FUNCTION Sing::MaxVx(double* pmaxvx, bool process_units);{{{1*/ 515 void Sing::MaxVx(double* pmaxvx, bool process_units){ 516 517 int dim; 518 double maxvx; 519 520 /*retrieve dim parameter: */ 521 parameters->FindParam(&dim,DimEnum); 522 523 /*retrive velocity values at nodes */ 524 inputs->GetParameterValue(&maxvx,VxEnum); 525 526 /*Assign output pointers:*/ 527 *pmaxvx=maxvx; 528 529 } 530 /*}}}*/ 531 /*FUNCTION Sing::MaxVy(double* pmaxvy, bool process_units);{{{1*/ 532 void Sing::MaxVy(double* pmaxvy, bool process_units){ 533 534 int dim; 535 double maxvy; 536 537 /*retrieve dim parameter: */ 538 parameters->FindParam(&dim,DimEnum); 539 540 /*retrive velocity values at nodes */ 541 inputs->GetParameterValue(&maxvy,VyEnum); 542 543 /*Assign output pointers:*/ 544 *pmaxvy=maxvy; 545 546 } 547 /*}}}*/ 548 /*FUNCTION Sing::MaxVz(double* pmaxvz, bool process_units);{{{1*/ 549 void Sing::MaxVz(double* pmaxvz, bool process_units){ 550 551 int dim; 552 double maxvz; 553 554 /*retrieve dim parameter: */ 555 parameters->FindParam(&dim,DimEnum); 556 557 /*retrive velocity values at nodes */ 558 inputs->GetParameterValue(&maxvz,VzEnum); 559 560 /*Assign output pointers:*/ 561 *pmaxvz=maxvz; 562 563 } 564 /*}}}*/ 565 /*FUNCTION Sing::MinVel(double* pminvel, bool process_units);{{{1*/ 566 void Sing::MinVel(double* pminvel, bool process_units){ 567 568 int dim; 569 double vx; 570 double vy; 571 double vz; 572 double minvel; 573 574 /*retrive velocity values at nodes */ 575 inputs->GetParameterValue(&vx,VxEnum); 576 inputs->GetParameterValue(&vy,VyEnum); 577 if(dim==3)inputs->GetParameterValue(&vz,VzEnum); 578 579 /*now, compute minimum of velocity :*/ 580 if(dim==2){ 581 minvel=sqrt(pow(vx,2)+pow(vy,2)); 582 } 583 else{ 584 minvel=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2)); 585 } 586 587 /*Assign output pointers:*/ 588 *pminvel=minvel; 589 590 } 591 /*}}}*/ 592 /*FUNCTION Sing::MinVx(double* pminvx, bool process_units);{{{1*/ 593 void Sing::MinVx(double* pminvx, bool process_units){ 594 595 int dim; 596 double minvx; 597 598 /*retrieve dim parameter: */ 599 parameters->FindParam(&dim,DimEnum); 600 601 /*retrive velocity values at nodes */ 602 inputs->GetParameterValue(&minvx,VxEnum); 603 604 /*Assign output pointers:*/ 605 *pminvx=minvx; 606 607 } 608 /*}}}*/ 609 /*FUNCTION Sing::MinVy(double* pminvy, bool process_units);{{{1*/ 610 void Sing::MinVy(double* pminvy, bool process_units){ 611 612 int dim; 613 double minvy; 614 615 /*retrieve dim parameter: */ 616 parameters->FindParam(&dim,DimEnum); 617 618 /*retrive velocity values at nodes */ 619 inputs->GetParameterValue(&minvy,VyEnum); 620 621 /*Assign output pointers:*/ 622 *pminvy=minvy; 623 624 } 625 /*}}}*/ 626 /*FUNCTION Sing::MinVz(double* pminvz, bool process_units);{{{1*/ 627 void Sing::MinVz(double* pminvz, bool process_units){ 628 629 int dim; 630 double minvz; 631 632 /*retrieve dim parameter: */ 633 parameters->FindParam(&dim,DimEnum); 634 635 /*retrive velocity values at nodes */ 636 inputs->GetParameterValue(&minvz,VzEnum); 637 638 /*Assign output pointers:*/ 639 *pminvz=minvz; 640 641 } 642 /*}}}*/ 643 /*FUNCTION Sing::Misfit {{{1*/ 644 double Sing::Misfit(void){ 645 ISSMERROR(" not supported yet!"); 646 } 647 /*}}}*/ 648 /*FUNCTION Sing::PatchFill(int* pcount, Patch* patch){{{1*/ 649 void Sing::PatchFill(int* pcount, Patch* patch){ 650 651 ISSMERROR(" not supported yet!"); 652 } 653 /*}}}*/ 654 /*FUNCTION Sing::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/ 655 void Sing::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){ 656 657 ISSMERROR(" not supported yet!"); 658 659 } 660 /*}}}*/ 661 /*FUNCTION Sing::ProcessResultsUnits(void){{{1*/ 662 void Sing::ProcessResultsUnits(void){ 663 ISSMERROR(" not supported yet!"); 664 } 665 /*}}}*/ 666 /*FUNCTION Sing::SurfaceArea {{{1*/ 667 double Sing::SurfaceArea( void){ 668 ISSMERROR(" not supported yet!"); 669 } 670 /*}}}*/ 671 /*FUNCTION Sing::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type);{{{1*/ 672 void Sing::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){ 673 ISSMERROR(" not supported yet!"); 674 } 675 /*}}}*/ 676 677 /*Sing specific routines: */ 138 678 /*FUNCTION Sing::IsInput{{{1*/ 139 679 bool Sing::IsInput(int name){ … … 143 683 } 144 684 else return false; 145 }146 /*}}}*/147 /*FUNCTION Sing::InputUpdateFromSolution {{{1*/148 void Sing::InputUpdateFromSolution(double* solution){149 ISSMERROR(" not supported yet!");150 }151 /*}}}*/152 /*FUNCTION Sing::GetSolutionFromInputs(Vec solution);{{{1*/153 void Sing::GetSolutionFromInputs(Vec solution){154 ISSMERROR(" not supported yet!");155 }156 /*}}}*/157 /*FUNCTION Sing::InputToResult(int enum_type,int step,double time){{{1*/158 void Sing::InputToResult(int enum_type,int step,double time){159 ISSMERROR(" not supported yet!");160 }161 /*}}}*/162 /*FUNCTION Sing::ProcessResultsUnits(void){{{1*/163 void Sing::ProcessResultsUnits(void){164 ISSMERROR(" not supported yet!");165 }166 /*}}}*/167 168 /*Sing functions*/169 /*FUNCTION Sing::ComputeBasalStress {{{1*/170 void Sing::ComputeBasalStress(Vec p_g){171 172 ISSMERROR("Not implemented yet");173 174 }175 /*}}}*/176 /*FUNCTION Sing::ComputePressure {{{1*/177 void Sing::ComputePressure(Vec p_g){178 179 int dof;180 double pressure;181 double thickness;182 double rho_ice,g;183 184 /*Get dof list on which we will plug the pressure values: */185 GetDofList1(&dof);186 187 /*pressure is lithostatic: */188 rho_ice=matpar->GetRhoIce();189 g=matpar->GetG();190 inputs->GetParameterValue(&thickness,ThicknessEnum);191 pressure=rho_ice*g*thickness;192 193 /*plug local pressure values into global pressure vector: */194 VecSetValue(p_g,dof,pressure,INSERT_VALUES);195 196 }197 /*}}}*/198 /*FUNCTION Sing::ComputeStrainRate {{{1*/199 void Sing::ComputeStrainRate(Vec p_g){200 201 ISSMERROR("Not implemented yet");202 203 }204 /*}}}*/205 /*FUNCTION Sing::CostFunction {{{1*/206 double Sing::CostFunction(){207 ISSMERROR(" not supported yet!");208 }209 /*}}}*/210 /*FUNCTION Sing::CreateKMatrix {{{1*/211 212 void Sing::CreateKMatrix(Mat Kgg){213 214 int analysis_type;215 216 /*retrive parameters: */217 parameters->FindParam(&analysis_type,AnalysisTypeEnum);218 219 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */220 if (analysis_type==DiagnosticHutterAnalysisEnum){221 CreateKMatrixDiagnosticHutter( Kgg);222 }223 else{224 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));225 }226 227 685 } 228 686 /*}}}*/ … … 246 704 247 705 MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES); 248 249 }250 /*}}}*/251 /*FUNCTION Sing::CreatePVector {{{1*/252 void Sing::CreatePVector(Vec pg){253 254 int analysis_type;255 256 /*retrive parameters: */257 parameters->FindParam(&analysis_type,AnalysisTypeEnum);258 259 /*Just branch to the correct load generator, according to the type of analysis we are carrying out: */260 if (analysis_type==DiagnosticHutterAnalysisEnum){261 CreatePVectorDiagnosticHutter( pg);262 }263 else{264 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));265 }266 706 267 707 } … … 317 757 } 318 758 /*}}}*/ 319 /*FUNCTION Sing::Du {{{1*/320 void Sing::Du(Vec){321 ISSMERROR(" not supported yet!");322 }323 /*}}}*/324 /*FUNCTION Sing::GetBedList {{{1*/325 void Sing::GetBedList(double*){326 ISSMERROR(" not supported yet!");327 }328 /*}}}*/329 759 /*FUNCTION Sing::GetDofList {{{1*/ 330 760 void Sing::GetDofList(int* doflist,int* pnumberofdofspernode){ … … 352 782 } 353 783 /*}}}*/ 354 /*FUNCTION Sing::GetMatPar {{{1*/355 void* Sing::GetMatPar(){356 357 return matpar;358 }359 /*}}}*/360 /*FUNCTION Sing::GetNodes {{{1*/361 void Sing::GetNodes(void** vpnodes){362 363 Node** pnodes=NULL;364 365 /*recover nodes: */366 pnodes=(Node**)vpnodes;367 368 pnodes[0]=node;369 }370 /*}}}*/371 /*FUNCTION Sing::GetOnBed {{{1*/372 bool Sing::GetOnBed(){373 ISSMERROR(" not supported yet!");374 }375 /*}}}*/376 /*FUNCTION Sing::GetShelf {{{1*/377 bool Sing::GetShelf(){378 ISSMERROR(" not supported yet!");379 }380 /*}}}*/381 /*FUNCTION Sing::GetThicknessList {{{1*/382 void Sing::GetThicknessList(double* thickness_list){383 ISSMERROR(" not supported yet!");384 }385 /*}}}*/386 /*FUNCTION Sing::Gradj {{{1*/387 void Sing::Gradj(Vec gradient,int control_type){388 ISSMERROR(" not supported yet!");389 }390 /*}}}*/391 /*FUNCTION Sing::GradB {{{1*/392 void Sing::GradjB(Vec gradient){393 ISSMERROR(" not supported yet!");394 }395 /*}}}*/396 /*FUNCTION Sing::GradjDrag {{{1*/397 void Sing::GradjDrag(Vec gradient){398 ISSMERROR(" not supported yet!");399 }400 /*}}}*/401 /*FUNCTION Sing::MassFlux {{{1*/402 double Sing::MassFlux( double* segment){403 ISSMERROR(" not supported yet!");404 }405 /*}}}*/406 /*FUNCTION Sing::Misfit {{{1*/407 double Sing::Misfit(void){408 ISSMERROR(" not supported yet!");409 }410 /*}}}*/411 /*FUNCTION Sing::SurfaceArea {{{1*/412 double Sing::SurfaceArea( void){413 ISSMERROR(" not supported yet!");414 }415 /*}}}*/416 784 /*FUNCTION Sing::SetClone {{{1*/ 417 785 void Sing::SetClone(int* minranks){ … … 420 788 } 421 789 /*}}}1*/ 422 /*FUNCTION Sing::InputUpdateFromVector(double* vector, int name, int type);{{{1*/423 void Sing::InputUpdateFromVector(double* vector, int name, int type){424 425 /*Check that name is an element input*/426 if (!IsInput(name)) return;427 428 switch(type){429 430 case VertexEnum:431 432 /*New SingVertexInpu*/433 double value;434 435 /*Get values on the 6 vertices*/436 value=vector[node->GetVertexDof()];437 438 /*update input*/439 this->inputs->AddInput(new SingVertexInput(name,value));440 return;441 442 default:443 ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type));444 }445 }446 /*}}}*/447 /*FUNCTION Sing::InputUpdateFromVector(int* vector, int name, int type);{{{1*/448 void Sing::InputUpdateFromVector(int* vector, int name, int type){449 ISSMERROR(" not supported yet!");450 }451 /*}}}*/452 /*FUNCTION Sing::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/453 void Sing::InputUpdateFromVector(bool* vector, int name, int type){454 ISSMERROR(" not supported yet!");455 }456 /*}}}*/457 /*FUNCTION Sing::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/458 void Sing::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){459 460 ISSMERROR(" not supported yet!");461 462 }463 /*}}}*/464 /*FUNCTION Sing::PatchFill(int* pcount, Patch* patch){{{1*/465 void Sing::PatchFill(int* pcount, Patch* patch){466 467 ISSMERROR(" not supported yet!");468 }469 /*}}}*/470 /*FUNCTION Sing::MinVel(double* pminvel, bool process_units);{{{1*/471 void Sing::MinVel(double* pminvel, bool process_units){472 473 int dim;474 double vx;475 double vy;476 double vz;477 double minvel;478 479 /*retrive velocity values at nodes */480 inputs->GetParameterValue(&vx,VxEnum);481 inputs->GetParameterValue(&vy,VyEnum);482 if(dim==3)inputs->GetParameterValue(&vz,VzEnum);483 484 /*now, compute minimum of velocity :*/485 if(dim==2){486 minvel=sqrt(pow(vx,2)+pow(vy,2));487 }488 else{489 minvel=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));490 }491 492 /*Assign output pointers:*/493 *pminvel=minvel;494 495 }496 /*}}}*/497 /*FUNCTION Sing::MaxVel(double* pmaxvel, bool process_units);{{{1*/498 void Sing::MaxVel(double* pmaxvel, bool process_units){499 500 int dim;501 double vx;502 double vy;503 double vz;504 double maxvel;505 506 /*retrive velocity values at nodes */507 inputs->GetParameterValue(&vx,VxEnum);508 inputs->GetParameterValue(&vy,VyEnum);509 if(dim==3)inputs->GetParameterValue(&vz,VzEnum);510 511 /*now, compute maximum of velocity :*/512 if(dim==2){513 maxvel=sqrt(pow(vx,2)+pow(vy,2));514 }515 else{516 maxvel=sqrt(pow(vx,2)+pow(vy,2)+pow(vz,2));517 }518 519 /*Assign output pointers:*/520 *pmaxvel=maxvel;521 522 }523 /*}}}*/524 /*FUNCTION Sing::MinVx(double* pminvx, bool process_units);{{{1*/525 void Sing::MinVx(double* pminvx, bool process_units){526 527 int dim;528 double minvx;529 530 /*retrieve dim parameter: */531 parameters->FindParam(&dim,DimEnum);532 533 /*retrive velocity values at nodes */534 inputs->GetParameterValue(&minvx,VxEnum);535 536 /*Assign output pointers:*/537 *pminvx=minvx;538 539 }540 /*}}}*/541 /*FUNCTION Sing::MaxVx(double* pmaxvx, bool process_units);{{{1*/542 void Sing::MaxVx(double* pmaxvx, bool process_units){543 544 int dim;545 double maxvx;546 547 /*retrieve dim parameter: */548 parameters->FindParam(&dim,DimEnum);549 550 /*retrive velocity values at nodes */551 inputs->GetParameterValue(&maxvx,VxEnum);552 553 /*Assign output pointers:*/554 *pmaxvx=maxvx;555 556 }557 /*}}}*/558 /*FUNCTION Sing::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/559 void Sing::MaxAbsVx(double* pmaxabsvx, bool process_units){560 561 int dim;562 double maxabsvx;563 564 /*retrieve dim parameter: */565 parameters->FindParam(&dim,DimEnum);566 567 /*retrive velocity values at nodes */568 inputs->GetParameterValue(&maxabsvx,VxEnum);569 maxabsvx=fabs(maxabsvx);570 571 /*Assign output pointers:*/572 *pmaxabsvx=maxabsvx;573 }574 /*}}}*/575 /*FUNCTION Sing::MinVy(double* pminvy, bool process_units);{{{1*/576 void Sing::MinVy(double* pminvy, bool process_units){577 578 int dim;579 double minvy;580 581 /*retrieve dim parameter: */582 parameters->FindParam(&dim,DimEnum);583 584 /*retrive velocity values at nodes */585 inputs->GetParameterValue(&minvy,VyEnum);586 587 /*Assign output pointers:*/588 *pminvy=minvy;589 590 }591 /*}}}*/592 /*FUNCTION Sing::MaxVy(double* pmaxvy, bool process_units);{{{1*/593 void Sing::MaxVy(double* pmaxvy, bool process_units){594 595 int dim;596 double maxvy;597 598 /*retrieve dim parameter: */599 parameters->FindParam(&dim,DimEnum);600 601 /*retrive velocity values at nodes */602 inputs->GetParameterValue(&maxvy,VyEnum);603 604 /*Assign output pointers:*/605 *pmaxvy=maxvy;606 607 }608 /*}}}*/609 /*FUNCTION Sing::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/610 void Sing::MaxAbsVy(double* pmaxabsvy, bool process_units){611 612 int dim;613 double maxabsvy;614 615 /*retrieve dim parameter: */616 parameters->FindParam(&dim,DimEnum);617 618 /*retrive velocity values at nodes */619 inputs->GetParameterValue(&maxabsvy,VyEnum);620 maxabsvy=fabs(maxabsvy);621 622 /*Assign output pointers:*/623 *pmaxabsvy=maxabsvy;624 }625 /*}}}*/626 /*FUNCTION Sing::MinVz(double* pminvz, bool process_units);{{{1*/627 void Sing::MinVz(double* pminvz, bool process_units){628 629 int dim;630 double minvz;631 632 /*retrieve dim parameter: */633 parameters->FindParam(&dim,DimEnum);634 635 /*retrive velocity values at nodes */636 inputs->GetParameterValue(&minvz,VzEnum);637 638 /*Assign output pointers:*/639 *pminvz=minvz;640 641 }642 /*}}}*/643 /*FUNCTION Sing::MaxVz(double* pmaxvz, bool process_units);{{{1*/644 void Sing::MaxVz(double* pmaxvz, bool process_units){645 646 int dim;647 double maxvz;648 649 /*retrieve dim parameter: */650 parameters->FindParam(&dim,DimEnum);651 652 /*retrive velocity values at nodes */653 inputs->GetParameterValue(&maxvz,VzEnum);654 655 /*Assign output pointers:*/656 *pmaxvz=maxvz;657 658 }659 /*}}}*/660 /*FUNCTION Sing::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/661 void Sing::MaxAbsVz(double* pmaxabsvz, bool process_units){662 663 int dim;664 double maxabsvz;665 666 /*retrieve dim parameter: */667 parameters->FindParam(&dim,DimEnum);668 669 /*retrive velocity values at nodes */670 inputs->GetParameterValue(&maxabsvz,VzEnum);671 maxabsvz=fabs(maxabsvz);672 673 /*Assign output pointers:*/674 *pmaxabsvz=maxabsvz;675 }676 /*}}}*/677 /*FUNCTION Sing::InputDuplicate(int original_enum,int new_enum){{{1*/678 void Sing::InputDuplicate(int original_enum,int new_enum){679 680 Input* original=NULL;681 Input* copy=NULL;682 683 /*Make a copy of the original input: */684 original=(Input*)this->inputs->GetInput(original_enum);685 copy=(Input*)original->copy();686 687 /*Change copy enum to reinitialized_enum: */688 copy->ChangeEnum(new_enum);689 690 /*Add copy into inputs, it will wipe off the one already there: */691 inputs->AddObject((Input*)copy);692 }693 /*}}}*/694 /*FUNCTION Sing::InputScale(int enum_type,double scale_factor){{{1*/695 void Sing::InputScale(int enum_type,double scale_factor){696 697 Input* input=NULL;698 699 /*Make a copy of the original input: */700 input=(Input*)this->inputs->GetInput(enum_type);701 702 /*Scale: */703 input->Scale(scale_factor);704 }705 /*}}}*/706 /*FUNCTION Sing::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/707 void Sing::InputAXPY(int YEnum, double scalar, int XEnum){708 709 Input* xinput=NULL;710 Input* yinput=NULL;711 712 /*Find x and y inputs: */713 xinput=(Input*)this->inputs->GetInput(XEnum);714 yinput=(Input*)this->inputs->GetInput(YEnum);715 716 /*some checks: */717 if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!");718 if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!");719 720 /*Scale: */721 yinput->AXPY(xinput,scalar);722 }723 /*}}}*/724 /*FUNCTION Sing::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/725 void Sing::InputControlConstrain(int control_type, double cm_min, double cm_max){726 727 Input* input=NULL;728 729 /*Find input: */730 input=(Input*)this->inputs->GetInput(control_type);731 732 /*Do nothing if we don't find it: */733 if(!input)return;734 735 /*Constrain input using cm_min and cm_max: */736 input->Constrain(cm_min,cm_max);737 738 }739 /*}}}*/740 /*FUNCTION Sing::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/741 void Sing::GetVectorFromInputs(Vec vector,int NameEnum){742 743 int i;744 const int numvertices=1;745 int doflist1[numvertices];746 747 /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */748 for(i=0;i<this->inputs->Size();i++){749 Input* input=(Input*)this->inputs->GetObjectByOffset(i);750 if(input->EnumType()==NameEnum){751 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */752 this->GetDofList1(&doflist1[0]);753 input->GetVectorFromInputs(vector,&doflist1[0]);754 break;755 }756 }757 }758 /*}}}*/759 /*FUNCTION Sing::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/760 void Sing::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){761 762 int i;763 Input** new_inputs=NULL;764 Input** old_inputs=NULL;765 int converged=1;766 767 new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs768 old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs769 770 for(i=0;i<num_enums/2;i++){771 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]);772 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]);773 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));774 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));775 }776 777 /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/778 for(i=0;i<num_criterionenums;i++){779 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]);780 if(eps[i]>criterionvalues[i]) converged=0;781 }782 783 /*Assign output pointers:*/784 *pconverged=converged;785 786 }787 /*}}}*/ -
issm/trunk/src/c/objects/Elements/Sing.h
r4249 r4285 42 42 /*}}}*/ 43 43 /*Object virtual functions definitions:{{{1 */ 44 void Echo();45 void DeepEcho();46 int Id();47 int MyRank();48 void Marshall(char** pmarshalled_dataset);49 int MarshallSize();50 void Demarshall(char** pmarshalled_dataset);51 int Enum();52 44 Object* copy(); 45 void Echo(); 46 int Id(); 47 int MyRank(); 48 void Marshall(char** pmarshalled_dataset); 49 int MarshallSize(); 50 int Enum(); 51 void DeepEcho(); 52 void Demarshall(char** pmarshalled_dataset); 53 53 /*}}}*/ 54 54 /*Update virtual functions resolution: {{{1*/ 55 void InputUpdateFromConstant(bool constant, int name){ISSMERROR("Not implemented yet!");} 56 void InputUpdateFromConstant(double constant, int name){ISSMERROR("Not implemented yet!");} 57 void InputUpdateFromConstant(int constant, int name){ISSMERROR("Not implemented yet!");} 58 void InputUpdateFromSolution(double* solutiong); 59 void InputUpdateFromVector(bool* vector, int name, int type); 55 60 void InputUpdateFromVector(double* vector, int name, int type); 56 61 void InputUpdateFromVector(int* vector, int name, int type); 57 void InputUpdateFromVector(bool* vector, int name, int type);58 void InputUpdateFromConstant(double constant, int name){ISSMERROR("Not implemented yet!");}59 void InputUpdateFromConstant(int constant, int name){ISSMERROR("Not implemented yet!");}60 void InputUpdateFromConstant(bool constant, int name){ISSMERROR("Not implemented yet!");}61 void InputUpdateFromSolution(double* solutiong);62 62 /*}}}*/ 63 63 /*Element virtual functions definitions: {{{1*/ -
issm/trunk/src/c/objects/Elements/Tria.cpp
r4282 r4285 69 69 } 70 70 /*}}}*/ 71 /*FUNCTION Tria::Update(IoModel* iomodel,int analysis_counter,int analysis_type){{{1*/ 72 void Tria::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){ //i is the element index 73 74 /*Intermediaries*/ 75 int i; 76 int tria_node_ids[3]; 77 int tria_vertex_ids[3]; 78 double nodeinputs[3]; 79 80 /*Checks if debuging*/ 81 /*{{{2*/ 82 ISSMASSERT(iomodel->elements); 83 /*}}}*/ 84 85 /*Recover vertices ids needed to initialize inputs*/ 86 for(i=0;i<3;i++){ 87 tria_vertex_ids[i]=(int)iomodel->elements[3*index+i]; //ids for vertices are in the elements array from Matlab 88 } 89 90 /*Recover nodes ids needed to initialize the node hook.*/ 91 if (analysis_type==Prognostic2AnalysisEnum || analysis_type==Balancedthickness2AnalysisEnum){ 92 /*Discontinuous Galerkin*/ 93 tria_node_ids[0]=iomodel->nodecounter+3*index+1; 94 tria_node_ids[1]=iomodel->nodecounter+3*index+2; 95 tria_node_ids[2]=iomodel->nodecounter+3*index+3; 71 72 /*Object virtual functions definitions:*/ 73 /*FUNCTION Tria::copy {{{1*/ 74 Object* Tria::copy() { 75 76 int i; 77 Tria* tria=NULL; 78 79 tria=new Tria(); 80 81 /*copy fields: */ 82 tria->id=this->id; 83 tria->interpolation_type=this->interpolation_type; 84 if(this->inputs){ 85 tria->inputs=(Inputs*)this->inputs->Copy(); 96 86 } 97 87 else{ 98 /*Continuous Galerkin*/ 99 for(i=0;i<3;i++){ 100 tria_node_ids[i]=iomodel->nodecounter+(int)*(iomodel->elements+3*index+i); //ids for vertices are in the elements array from Matlab 101 } 102 } 103 104 /*hooks: */ 105 this->SetHookNodes(tria_node_ids,analysis_counter); this->nodes=NULL; //set hook to nodes, for this analysis type 88 tria->inputs=new Inputs(); 89 } 90 if(this->results){ 91 tria->results=(Results*)this->results->Copy(); 92 } 93 else{ 94 tria->results=new Results(); 95 } 96 /*point parameters: */ 97 tria->parameters=this->parameters; 98 99 /*now deal with hooks and objects: */ 100 tria->InitHookNodes(this->numanalyses); 101 for(i=0;i<this->numanalyses;i++)tria->hnodes[i].copy(&this->hnodes[i]); 102 tria->hmatice.copy(&this->hmatice); 103 tria->hmatpar.copy(&this->hmatpar); 104 105 /*recover objects: */ 106 tria->nodes=(Node**)xmalloc(3*sizeof(Node*)); //we cannot rely on an analysis_counter to tell us which analysis_type we are running, so we just copy the nodes. 107 for(i=0;i<3;i++)tria->nodes[i]=this->nodes[i]; 108 tria->matice=(Matice*)tria->hmatice.delivers(); 109 tria->matpar=(Matpar*)tria->hmatpar.delivers(); 110 111 return tria; 112 } 113 /*}}}*/ 114 /*FUNCTION Tria::DeepEcho{{{1*/ 115 void Tria::DeepEcho(void){ 116 117 printf("Tria:\n"); 118 printf(" id: %i\n",id); 119 if(nodes){ 120 nodes[0]->DeepEcho(); 121 nodes[1]->DeepEcho(); 122 nodes[2]->DeepEcho(); 123 } 124 else printf("nodes = NULL\n"); 125 126 if (matice) matice->DeepEcho(); 127 else printf("matice = NULL\n"); 128 129 if (matpar) matpar->DeepEcho(); 130 else printf("matpar = NULL\n"); 131 132 printf(" parameters\n"); 133 if (parameters) parameters->DeepEcho(); 134 else printf("parameters = NULL\n"); 135 136 printf(" inputs\n"); 137 if (inputs) inputs->DeepEcho(); 138 else printf("inputs=NULL\n"); 139 140 if (results) results->DeepEcho(); 141 else printf("results=NULL\n"); 106 142 107 /*add as many inputs per element as requested:*/ 108 if (iomodel->thickness) { 109 for(i=0;i<3;i++)nodeinputs[i]=iomodel->thickness[tria_vertex_ids[i]-1]; 110 this->inputs->AddInput(new TriaVertexInput(ThicknessEnum,nodeinputs)); 111 } 112 if (iomodel->surface) { 113 for(i=0;i<3;i++)nodeinputs[i]=iomodel->surface[tria_vertex_ids[i]-1]; 114 this->inputs->AddInput(new TriaVertexInput(SurfaceEnum,nodeinputs)); 115 } 116 if (iomodel->bed) { 117 for(i=0;i<3;i++)nodeinputs[i]=iomodel->bed[tria_vertex_ids[i]-1]; 118 this->inputs->AddInput(new TriaVertexInput(BedEnum,nodeinputs)); 119 } 120 if (iomodel->drag_coefficient) { 121 for(i=0;i<3;i++)nodeinputs[i]=iomodel->drag_coefficient[tria_vertex_ids[i]-1]; 122 this->inputs->AddInput(new TriaVertexInput(DragCoefficientEnum,nodeinputs)); 123 124 if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index])); 125 if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index])); 126 this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type)); 127 } 128 if (iomodel->melting_rate) { 129 for(i=0;i<3;i++)nodeinputs[i]=iomodel->melting_rate[tria_vertex_ids[i]-1]/iomodel->yts; 130 this->inputs->AddInput(new TriaVertexInput(MeltingRateEnum,nodeinputs)); 131 } 132 if (iomodel->accumulation_rate) { 133 for(i=0;i<3;i++)nodeinputs[i]=iomodel->accumulation_rate[tria_vertex_ids[i]-1]/iomodel->yts; 134 this->inputs->AddInput(new TriaVertexInput(AccumulationRateEnum,nodeinputs)); 135 } 136 if (iomodel->geothermalflux) { 137 for(i=0;i<3;i++)nodeinputs[i]=iomodel->geothermalflux[tria_vertex_ids[i]-1]; 138 this->inputs->AddInput(new TriaVertexInput(GeothermalFluxEnum,nodeinputs)); 139 } 140 if (iomodel->dhdt) { 141 for(i=0;i<3;i++)nodeinputs[i]=iomodel->dhdt[tria_vertex_ids[i]-1]; 142 this->inputs->AddInput(new TriaVertexInput(DhDtEnum,nodeinputs)); 143 } 144 if (iomodel->pressure) { 145 for(i=0;i<3;i++)nodeinputs[i]=iomodel->pressure[tria_vertex_ids[i]-1]; 146 this->inputs->AddInput(new TriaVertexInput(PressureEnum,nodeinputs)); 147 } 148 if (iomodel->temperature) { 149 for(i=0;i<3;i++)nodeinputs[i]=iomodel->temperature[tria_vertex_ids[i]-1]; 150 this->inputs->AddInput(new TriaVertexInput(TemperatureEnum,nodeinputs)); 151 } 152 /*vx,vy and vz: */ 153 if (iomodel->vx) { 154 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx[tria_vertex_ids[i]-1]/iomodel->yts; 155 this->inputs->AddInput(new TriaVertexInput(VxEnum,nodeinputs)); 156 this->inputs->AddInput(new TriaVertexInput(VxOldEnum,nodeinputs)); 157 } 158 if (iomodel->vy) { 159 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy[tria_vertex_ids[i]-1]/iomodel->yts; 160 this->inputs->AddInput(new TriaVertexInput(VyEnum,nodeinputs)); 161 this->inputs->AddInput(new TriaVertexInput(VyOldEnum,nodeinputs)); 162 } 163 if (iomodel->vz) { 164 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz[tria_vertex_ids[i]-1]/iomodel->yts; 165 this->inputs->AddInput(new TriaVertexInput(VzEnum,nodeinputs)); 166 this->inputs->AddInput(new TriaVertexInput(VzOldEnum,nodeinputs)); 167 } 168 if (iomodel->vx_obs) { 169 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx_obs[tria_vertex_ids[i]-1]/iomodel->yts; 170 this->inputs->AddInput(new TriaVertexInput(VxObsEnum,nodeinputs)); 171 } 172 if (iomodel->vy_obs) { 173 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy_obs[tria_vertex_ids[i]-1]/iomodel->yts; 174 this->inputs->AddInput(new TriaVertexInput(VyObsEnum,nodeinputs)); 175 } 176 if (iomodel->vz_obs) { 177 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz_obs[tria_vertex_ids[i]-1]/iomodel->yts; 178 this->inputs->AddInput(new TriaVertexInput(VzObsEnum,nodeinputs)); 179 } 180 if (iomodel->weights) { 181 for(i=0;i<3;i++)nodeinputs[i]=iomodel->weights[tria_vertex_ids[i]-1]; 182 this->inputs->AddInput(new TriaVertexInput(WeightsEnum,nodeinputs)); 183 } 184 if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index])); 185 if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index])); 186 if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index])); 187 if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index])); 188 189 /*Defaults if not provided in iomodel*/ 190 switch(analysis_type){ 191 192 case DiagnosticHorizAnalysisEnum: case DiagnosticVertAnalysisEnum: case DiagnosticStokesAnalysisEnum: 193 194 /*default vx,vy and vz: either observation or 0 */ 195 if(!iomodel->vx){ 196 if (iomodel->vx_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx_obs[tria_vertex_ids[i]-1]/iomodel->yts; 197 else for(i=0;i<3;i++)nodeinputs[i]=0; 198 this->inputs->AddInput(new TriaVertexInput(VxEnum,nodeinputs)); 199 this->inputs->AddInput(new TriaVertexInput(VxOldEnum,nodeinputs)); 200 } 201 if(!iomodel->vy){ 202 if (iomodel->vy_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy_obs[tria_vertex_ids[i]-1]/iomodel->yts; 203 else for(i=0;i<3;i++)nodeinputs[i]=0; 204 this->inputs->AddInput(new TriaVertexInput(VyEnum,nodeinputs)); 205 this->inputs->AddInput(new TriaVertexInput(VyOldEnum,nodeinputs)); 206 } 207 if(!iomodel->vz){ 208 if (iomodel->vz_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz_obs[tria_vertex_ids[i]-1]/iomodel->yts; 209 else for(i=0;i<3;i++)nodeinputs[i]=0; 210 this->inputs->AddInput(new TriaVertexInput(VzEnum,nodeinputs)); 211 this->inputs->AddInput(new TriaVertexInput(VzOldEnum,nodeinputs)); 212 } 213 break; 214 215 default: 216 /*No update for other solution types*/ 217 break; 218 219 } 220 221 //this->parameters: we still can't point to it, it may not even exist. Configure will handle this. 143 return; 144 } 145 /*}}}*/ 146 /*FUNCTION Tria::Demarshall {{{1*/ 147 void Tria::Demarshall(char** pmarshalled_dataset){ 148 149 char* marshalled_dataset=NULL; 150 int i; 151 152 /*recover marshalled_dataset: */ 153 marshalled_dataset=*pmarshalled_dataset; 154 155 /*this time, no need to get enum type, the pointer directly points to the beginning of the 156 *object data (thanks to DataSet::Demarshall):*/ 157 memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id); 158 memcpy(&interpolation_type,marshalled_dataset,sizeof(interpolation_type));marshalled_dataset+=sizeof(interpolation_type); 159 memcpy(&numanalyses,marshalled_dataset,sizeof(numanalyses));marshalled_dataset+=sizeof(numanalyses); 160 161 /*allocate dynamic memory: */ 162 InitHookNodes(numanalyses); 163 164 /*demarshall hooks: */ 165 for(i=0;i<numanalyses;i++)hnodes[i].Demarshall(&marshalled_dataset); 166 hmatice.Demarshall(&marshalled_dataset); 167 hmatpar.Demarshall(&marshalled_dataset); 168 169 /*pointers are garbabe, until configuration is carried out: */ 170 nodes=NULL; 171 matice=NULL; 172 matpar=NULL; 173 174 /*demarshall inputs: */ 175 inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 176 results=(Results*)DataSetDemarshallRaw(&marshalled_dataset); 177 178 /*parameters: may not exist even yet, so let Configure handle it: */ 222 179 this->parameters=NULL; 223 180 224 } 225 /*}}}*/ 226 227 /*Object virtual functions definitions:*/ 181 /*return: */ 182 *pmarshalled_dataset=marshalled_dataset; 183 return; 184 } 185 /*}}}*/ 228 186 /*FUNCTION Tria::Echo{{{1*/ 229 187 void Tria::Echo(void){ … … 255 213 } 256 214 /*}}}*/ 257 /*FUNCTION Tria::DeepEcho{{{1*/ 258 void Tria::DeepEcho(void){ 259 260 printf("Tria:\n"); 261 printf(" id: %i\n",id); 262 if(nodes){ 263 nodes[0]->DeepEcho(); 264 nodes[1]->DeepEcho(); 265 nodes[2]->DeepEcho(); 266 } 267 else printf("nodes = NULL\n"); 268 269 if (matice) matice->DeepEcho(); 270 else printf("matice = NULL\n"); 271 272 if (matpar) matpar->DeepEcho(); 273 else printf("matpar = NULL\n"); 274 275 printf(" parameters\n"); 276 if (parameters) parameters->DeepEcho(); 277 else printf("parameters = NULL\n"); 278 279 printf(" inputs\n"); 280 if (inputs) inputs->DeepEcho(); 281 else printf("inputs=NULL\n"); 282 283 if (results) results->DeepEcho(); 284 else printf("results=NULL\n"); 285 286 return; 215 /*FUNCTION Tria::Enum {{{1*/ 216 int Tria::Enum(void){ 217 218 return TriaEnum; 219 287 220 } 288 221 /*}}}*/ 289 222 /*FUNCTION Tria::Id {{{1*/ 290 223 int Tria::Id(){ return id; } 291 /*}}}*/292 /*FUNCTION Tria::MyRank {{{1*/293 int Tria::MyRank(void){294 extern int my_rank;295 return my_rank;296 }297 224 /*}}}*/ 298 225 /*FUNCTION Tria::Marshall {{{1*/ … … 366 293 } 367 294 /*}}}*/ 368 /*FUNCTION Tria::Demarshall {{{1*/ 369 void Tria::Demarshall(char** pmarshalled_dataset){ 370 371 char* marshalled_dataset=NULL; 372 int i; 373 374 /*recover marshalled_dataset: */ 375 marshalled_dataset=*pmarshalled_dataset; 376 377 /*this time, no need to get enum type, the pointer directly points to the beginning of the 378 *object data (thanks to DataSet::Demarshall):*/ 379 memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id); 380 memcpy(&interpolation_type,marshalled_dataset,sizeof(interpolation_type));marshalled_dataset+=sizeof(interpolation_type); 381 memcpy(&numanalyses,marshalled_dataset,sizeof(numanalyses));marshalled_dataset+=sizeof(numanalyses); 382 383 /*allocate dynamic memory: */ 384 InitHookNodes(numanalyses); 385 386 /*demarshall hooks: */ 387 for(i=0;i<numanalyses;i++)hnodes[i].Demarshall(&marshalled_dataset); 388 hmatice.Demarshall(&marshalled_dataset); 389 hmatpar.Demarshall(&marshalled_dataset); 390 391 /*pointers are garbabe, until configuration is carried out: */ 392 nodes=NULL; 393 matice=NULL; 394 matpar=NULL; 395 396 /*demarshall inputs: */ 397 inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset); 398 results=(Results*)DataSetDemarshallRaw(&marshalled_dataset); 399 400 /*parameters: may not exist even yet, so let Configure handle it: */ 401 this->parameters=NULL; 402 403 /*return: */ 404 *pmarshalled_dataset=marshalled_dataset; 405 return; 406 } 407 /*}}}*/ 408 /*FUNCTION Tria::Enum {{{1*/ 409 int Tria::Enum(void){ 410 411 return TriaEnum; 412 413 } 414 /*}}}*/ 415 /*FUNCTION Tria::copy {{{1*/ 416 Object* Tria::copy() { 417 418 int i; 419 Tria* tria=NULL; 420 421 tria=new Tria(); 422 423 /*copy fields: */ 424 tria->id=this->id; 425 tria->interpolation_type=this->interpolation_type; 426 if(this->inputs){ 427 tria->inputs=(Inputs*)this->inputs->Copy(); 428 } 429 else{ 430 tria->inputs=new Inputs(); 431 } 432 if(this->results){ 433 tria->results=(Results*)this->results->Copy(); 434 } 435 else{ 436 tria->results=new Results(); 437 } 438 /*point parameters: */ 439 tria->parameters=this->parameters; 440 441 /*now deal with hooks and objects: */ 442 tria->InitHookNodes(this->numanalyses); 443 for(i=0;i<this->numanalyses;i++)tria->hnodes[i].copy(&this->hnodes[i]); 444 tria->hmatice.copy(&this->hmatice); 445 tria->hmatpar.copy(&this->hmatpar); 446 447 /*recover objects: */ 448 tria->nodes=(Node**)xmalloc(3*sizeof(Node*)); //we cannot rely on an analysis_counter to tell us which analysis_type we are running, so we just copy the nodes. 449 for(i=0;i<3;i++)tria->nodes[i]=this->nodes[i]; 450 tria->matice=(Matice*)tria->hmatice.delivers(); 451 tria->matpar=(Matpar*)tria->hmatpar.delivers(); 452 453 return tria; 454 } 455 /*}}}*/ 456 457 /*Tria management: */ 458 /*FUNCTION Tria::Configure {{{1*/ 459 void Tria::Configure(Elements* elementsin, Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){ 460 461 int analysis_counter; 462 463 /*go into parameters and get the analysis_counter: */ 464 parametersin->FindParam(&analysis_counter,AnalysisCounterEnum); 465 466 /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 467 * datasets, using internal ids and offsets hidden in hooks: */ 468 this->hnodes[analysis_counter].configure(nodesin); 469 this->hmatice.configure(materialsin); 470 this->hmatpar.configure(materialsin); 471 472 /*Now, go pick up the objects inside the hooks: */ 473 this->nodes=(Node**)this->hnodes[analysis_counter].deliverp(); 474 this->matice=(Matice*)this->hmatice.delivers(); 475 this->matpar=(Matpar*)this->hmatpar.delivers(); 476 477 /*point parameters to real dataset: */ 478 this->parameters=parametersin; 479 480 } 481 /*}}}*/ 482 /*FUNCTION Tria::SpawnBeam {{{1*/ 483 void* Tria::SpawnBeam(int g0, int g1){ 484 485 int i; 486 487 /*out of grids g0,g1 and g2 from Tria, build a beam element: */ 488 Beam* beam=NULL; 489 int indices[2]; 490 int zero=0; 491 Parameters *beam_parameters = NULL; 492 Inputs *beam_inputs = NULL; 493 494 indices[0]=g0; 495 indices[1]=g1; 496 497 beam_parameters=this->parameters; 498 beam_inputs=(Inputs*)this->inputs->SpawnBeamInputs(indices); 499 500 beam=new Beam(); 501 beam->id=this->id; 502 beam->inputs=beam_inputs; 503 beam->parameters=beam_parameters; 504 505 /*now deal with nodes, matice and matpar: */ 506 beam->nodes=(Node**)xmalloc(2*sizeof(Node*)); 507 for(i=0;i<2;i++)beam->nodes[i]=this->nodes[indices[i]]; 508 beam->matice=this->matice; 509 beam->matpar=this->matpar; 510 511 512 return beam; 513 } 514 /*}}}*/ 515 /*FUNCTION Tria::SpawnSing {{{1*/ 516 void* Tria::SpawnSing(int index){ 517 518 Sing* sing=NULL; 519 int zero=0; 520 Parameters *sing_parameters = NULL; 521 Inputs *sing_inputs = NULL; 522 523 sing_parameters=this->parameters; 524 sing_inputs=(Inputs*)this->inputs->SpawnSingInputs(index); 525 526 sing=new Sing(); 527 sing->id=this->id; 528 sing->inputs=sing_inputs; 529 sing->parameters=sing_parameters; 530 531 /*now deal with node,matice and matpar: */ 532 sing->node=this->nodes[index]; 533 sing->matice=this->matice; 534 sing->matpar=this->matpar; 535 536 return sing; 537 } 538 /*}}}*/ 539 /*FUNCTION Tria::InputToResult(int enum_type,int step,double time){{{1*/ 540 void Tria::InputToResult(int enum_type,int step,double time){ 541 542 int i; 543 bool found = false; 544 Input *input = NULL; 545 546 /*Go through all the input objects, and find the one corresponding to enum_type, if it exists: */ 547 for (i=0;i<this->inputs->Size();i++){ 548 input=(Input*)this->inputs->GetObjectByOffset(i); 549 if (input->EnumType()==enum_type){ 550 found=true; 551 break; 552 } 553 } 554 555 /*If we don't find it, no big deal, just don't do the transfer. Otherwise, build a new Result 556 * object out of the input, with the additional step and time information: */ 557 this->results->AddObject((Object*)input->SpawnResult(step,time)); 558 559 } 560 /*}}}*/ 561 /*FUNCTION Tria::ProcessResultsUnits(void){{{1*/ 562 void Tria::ProcessResultsUnits(void){ 563 564 int i; 565 566 for(i=0;i<this->results->Size();i++){ 567 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i); 568 elementresult->ProcessUnits(this->parameters); 569 } 570 571 } 572 /*}}}*/ 573 574 /*Updates: */ 575 /*FUNCTION Tria::UpdateGeometry{{{1*/ 576 void Tria::UpdateGeometry(void){ 577 578 /*Intermediaries*/ 579 double rho_ice,rho_water; 580 581 /*If shelf: hydrostatic equilibrium*/ 582 if (this->GetShelf()){ 583 584 /*recover material parameters: */ 585 rho_ice=matpar->GetRhoIce(); 586 rho_water=matpar->GetRhoWater(); 587 588 /*Create New Surface: s = (1-rho_ice/rho_water) h*/ 589 InputDuplicate(ThicknessEnum,SurfaceEnum); //1: copy thickness into surface 590 InputScale(SurfaceEnum,(1-rho_ice/rho_water)); //2: surface = surface * (1-di) 591 592 /*Create New Bed b = -rho_ice/rho_water h*/ 593 InputDuplicate(ThicknessEnum,BedEnum); //1: copy thickness into bed 594 InputScale(BedEnum, -rho_ice/rho_water); //2: bed = bed * (-di) 595 } 596 597 /*If sheet: surface = bed + thickness*/ 598 else{ 599 600 /*The bed does not change, update surface only s = b + h*/ 601 InputDuplicate(BedEnum,SurfaceEnum); //1: copy bed into surface 602 InputAXPY(SurfaceEnum,1.0,ThicknessEnum); //2: surface = surface + 1 * thickness 603 } 604 605 } 606 /*}}}*/ 607 /*FUNCTION Tria::UpdateFromDakota {{{1*/ 608 void Tria::UpdateFromDakota(void* vinputs){ 609 610 int i; 611 int dofs[1]={0}; 612 double temperature_list[3]; 613 double temperature_average; 614 double B_list[3]; 615 double B_average; 616 double new_h[3]; 617 618 /*Update internal data if inputs holds new values: */ 619 /*inputs->Recover("thickness",&this->properties.h[0],1,dofs,3,(void**)nodes); 620 if(inputs->Recover("thickness",&new_h[0],1,dofs,3,(void**)nodes)){ 621 //density, needed later: 622 double di=(this->matpar->GetRhoIce()/this->matpar->GetRhoWater()); 623 //Go through grids: 624 for (i=0;i<3;i++){ 625 if(nodes[i]->IsOnShelf()){ 626 this->b[i]=this->b[i]-di*(new_h[i]-h[i]); //hydrostatic equilibrium; 627 } 628 this->s[i]=this->b[i]+new_h[i]; 629 this->h[i]=new_h[i]; 630 } 631 }*/ 632 633 ISSMERROR("not supported yet!"); 634 295 /*FUNCTION Tria::MyRank {{{1*/ 296 int Tria::MyRank(void){ 297 extern int my_rank; 298 return my_rank; 299 } 300 /*}}}*/ 301 302 /*Update virtual functions definitions: */ 303 /*FUNCTION Tria::InputUpdateFromConstant(int value, int name);{{{1*/ 304 void Tria::InputUpdateFromConstant(int constant, int name){ 305 /*Nothing updated for now*/ 306 } 307 /*}}}*/ 308 /*FUNCTION Tria::InputUpdateFromConstant(double value, int name);{{{1*/ 309 void Tria::InputUpdateFromConstant(double constant, int name){ 310 /*Nothing updated for now*/ 311 } 312 /*}}}*/ 313 /*FUNCTION Tria::InputUpdateFromConstant(bool value, int name);{{{1*/ 314 void Tria::InputUpdateFromConstant(bool constant, int name){ 315 /*Nothing updated for now*/ 635 316 } 636 317 /*}}}*/ … … 650 331 InputUpdateFromSolutionDiagnosticHoriz( solution); 651 332 } 652 else if (analysis_type== SlopeAnalysisEnum){333 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 653 334 InputUpdateFromSolutionSlopeCompute( solution); 654 335 } … … 673 354 } 674 355 /*}}}*/ 675 /*FUNCTION Tria::InputUpdateFromSolutionDiagnosticHoriz {{{1*/ 676 void Tria::InputUpdateFromSolutionDiagnosticHoriz(double* solution){ 677 678 int i; 679 680 const int numvertices=3; 681 const int numdofpervertex=2; 682 const int numdof=numdofpervertex*numvertices; 683 684 int doflist[numdof]; 685 double values[numdof]; 686 double vx[numvertices]; 687 double vy[numvertices]; 688 double vz[numvertices]; 689 double vel[numvertices]; 690 double pressure[numvertices]; 691 double thickness[numvertices]; 692 double rho_ice,g; 693 double gauss[numvertices][numvertices]={{1,0,0},{0,1,0},{0,0,1}}; 694 695 int dummy; 696 Input* VzInput=NULL; 697 double* VzPtr=NULL; 698 699 /*Get dof list: */ 700 GetDofList(&doflist[0],&dummy); 701 702 /*Use the dof list to index into the solution vector: */ 703 for(i=0;i<numdof;i++){ 704 values[i]=solution[doflist[i]]; 705 } 706 707 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 708 for(i=0;i<numvertices;i++){ 709 vx[i]=values[i*numdofpervertex+0]; 710 vy[i]=values[i*numdofpervertex+1]; 711 } 712 713 /*Get Vz*/ 714 VzInput=inputs->GetInput(VzEnum); 715 if (VzInput){ 716 if (VzInput->Enum()!=TriaVertexInputEnum){ 717 ISSMERROR("Cannot compute Vel as Vz is of type %s",EnumAsString(VzInput->Enum())); 718 } 719 VzInput->GetValuesPtr(&VzPtr,&dummy); 720 for(i=0;i<numvertices;i++) vz[i]=VzPtr[i]; 721 } 722 else{ 723 for(i=0;i<numvertices;i++) vz[i]=0.0; 724 } 725 726 /*Now Compute vel*/ 727 for(i=0;i<numvertices;i++) vel[i]=pow( pow(vx[i],2.0) + pow(vy[i],2.0) + pow(vz[i],2.0) , 0.5); 728 729 /*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 730 *so the pressure is just the pressure at the bedrock: */ 731 rho_ice=matpar->GetRhoIce(); 732 g=matpar->GetG(); 733 inputs->GetParameterValues(&thickness[0],&gauss[0][0],3,ThicknessEnum); 734 735 for(i=0;i<numvertices;i++){ 736 pressure[i]=rho_ice*g*thickness[i]; 737 } 738 739 /*Now, we have to move the previous Vx and Vy inputs to old 740 * status, otherwise, we'll wipe them off: */ 741 this->inputs->ChangeEnum(VxEnum,VxOldEnum); 742 this->inputs->ChangeEnum(VyEnum,VyOldEnum); 743 this->inputs->ChangeEnum(PressureEnum,PressureOldEnum); 744 745 /*Add vx and vy as inputs to the tria element: */ 746 this->inputs->AddInput(new TriaVertexInput(VxEnum,vx)); 747 this->inputs->AddInput(new TriaVertexInput(VyEnum,vy)); 748 this->inputs->AddInput(new TriaVertexInput(VelEnum,vel)); 749 this->inputs->AddInput(new TriaVertexInput(PressureEnum,pressure)); 750 751 } 752 753 /*}}}*/ 754 /*FUNCTION Tria::InputUpdateFromSolutionSlopeCompute {{{1*/ 755 void Tria::InputUpdateFromSolutionSlopeCompute(double* solution){ 356 /*FUNCTION Tria::InputUpdateFromVector(double* vector, int name, int type);{{{1*/ 357 void Tria::InputUpdateFromVector(double* vector, int name, int type){ 358 359 /*Check that name is an element input*/ 360 if (!IsInput(name)) return; 361 362 switch(type){ 363 364 case VertexEnum: 365 366 /*New PentaVertexInpu*/ 367 double values[3]; 368 369 /*Get values on the 6 vertices*/ 370 for (int i=0;i<3;i++){ 371 values[i]=vector[this->nodes[i]->GetVertexDof()]; 372 } 373 374 /*update input*/ 375 this->inputs->AddInput(new TriaVertexInput(name,values)); 376 return; 377 378 default: 379 380 ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type)); 381 } 382 } 383 /*}}}*/ 384 /*FUNCTION Tria::InputUpdateFromVector(int* vector, int name, int type);{{{1*/ 385 void Tria::InputUpdateFromVector(int* vector, int name, int type){ 756 386 ISSMERROR(" not supported yet!"); 757 387 } 758 388 /*}}}*/ 759 /*FUNCTION Tria::InputUpdateFromSolutionPrognostic {{{1*/ 760 void Tria::InputUpdateFromSolutionPrognostic(double* solution){ 761 762 int i; 763 764 const int numvertices=3; 765 const int numdofpervertex=1; 766 const int numdof=numdofpervertex*numvertices; 767 768 int doflist[numdof]; 769 double values[numdof]; 770 double thickness[numvertices]; 771 772 int dummy; 773 774 /*Get dof list: */ 775 GetDofList(&doflist[0],&dummy); 776 777 /*Use the dof list to index into the solution vector: */ 778 for(i=0;i<numdof;i++){ 779 values[i]=solution[doflist[i]]; 780 } 781 782 /*Add thickness as inputs to the tria element: */ 783 this->inputs->AddInput(new TriaVertexInput(ThicknessEnum,values)); 784 } 785 /*}}}*/ 786 /*FUNCTION Tria::InputUpdateFromSolutionPrognostic2 {{{1*/ 787 void Tria::InputUpdateFromSolutionPrognostic2(double* solution){ 389 /*FUNCTION Tria::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/ 390 void Tria::InputUpdateFromVector(bool* vector, int name, int type){ 788 391 ISSMERROR(" not supported yet!"); 789 392 } 790 393 /*}}}*/ 791 /*FUNCTION Tria::InputUpdateFromSolutionBalancedthickness {{{1*/ 792 void Tria::InputUpdateFromSolutionBalancedthickness(double* solution){ 793 794 int i; 795 796 const int numvertices=3; 797 const int numdofpervertex=1; 798 const int numdof=numdofpervertex*numvertices; 799 800 int doflist[numdof]; 801 double values[numdof]; 802 double thickness[numvertices]; 803 804 int dummy; 805 806 /*Get dof list: */ 807 GetDofList(&doflist[0],&dummy); 808 809 /*Use the dof list to index into the solution vector: */ 810 for(i=0;i<numdof;i++){ 811 values[i]=solution[doflist[i]]; 812 } 813 814 /*Add thickness as inputs to the tria element: */ 815 this->inputs->AddInput(new TriaVertexInput(ThicknessEnum,values)); 816 } 817 /*}}}*/ 818 /*FUNCTION Tria::InputUpdateFromSolutionBalancedthickness2 {{{1*/ 819 void Tria::InputUpdateFromSolutionBalancedthickness2(double* solution){ 820 ISSMERROR(" not supported yet!"); 821 } 822 /*}}}*/ 823 /*FUNCTION Tria::InputUpdateFromSolutionBalancedvelocities {{{1*/ 824 void Tria::InputUpdateFromSolutionBalancedvelocities(double* solution){ 825 ISSMERROR(" not supported yet!"); 826 } 827 /*}}}*/ 828 /*FUNCTION Tria::GetSolutionFromInputs(Vec solution){{{1*/ 829 void Tria::GetSolutionFromInputs(Vec solution){ 830 831 int analysis_type; 832 833 /*retrive parameters: */ 834 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 835 836 /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */ 837 if (analysis_type==DiagnosticHorizAnalysisEnum) 838 GetSolutionFromInputsDiagnosticHoriz(solution); 839 else 840 ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet"); 841 842 } 843 /*}}}*/ 844 /*FUNCTION Tria::GetSolutionFromInputsDiagnosticHoriz(Vec solution){{{1*/ 845 void Tria::GetSolutionFromInputsDiagnosticHoriz(Vec solution){ 846 847 int i; 848 849 const int numvertices=3; 850 const int numdofpervertex=2; 851 const int numdof=numdofpervertex*numvertices; 852 double gauss[numvertices][numvertices]={{1,0,0},{0,1,0},{0,0,1}}; 853 854 int doflist[numdof]; 855 double values[numdof]; 856 double vx; 857 double vy; 858 859 int dummy; 860 861 /*Get dof list: */ 862 GetDofList(&doflist[0],&dummy); 863 864 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 865 /*P1 element only for now*/ 866 for(i=0;i<numvertices;i++){ 867 868 /*Recover vx and vy*/ 869 inputs->GetParameterValue(&vx,&gauss[i][0],VxEnum); 870 inputs->GetParameterValue(&vy,&gauss[i][0],VyEnum); 871 values[i*numdofpervertex+0]=vx; 872 values[i*numdofpervertex+1]=vy; 873 } 874 875 /*Add value to global vector*/ 876 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 877 878 } 879 /*}}}*/ 880 881 /*Object functions*/ 882 /*FUNCTION Tria::IsInput{{{1*/ 883 bool Tria::IsInput(int name){ 884 if (name==SurfaceSlopeXEnum || 885 name==SurfaceSlopeYEnum){ 886 return true; 887 } 888 else return false; 889 } 890 /*}}}*/ 394 395 /*Element virtual functions definitions: */ 891 396 /*FUNCTION Tria::ComputeBasalStress {{{1*/ 892 397 void Tria::ComputeBasalStress(Vec eps){ … … 947 452 } 948 453 /*}}}*/ 454 /*FUNCTION Tria::Configure {{{1*/ 455 void Tria::Configure(Elements* elementsin, Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){ 456 457 int analysis_counter; 458 459 /*go into parameters and get the analysis_counter: */ 460 parametersin->FindParam(&analysis_counter,AnalysisCounterEnum); 461 462 /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective 463 * datasets, using internal ids and offsets hidden in hooks: */ 464 this->hnodes[analysis_counter].configure(nodesin); 465 this->hmatice.configure(materialsin); 466 this->hmatpar.configure(materialsin); 467 468 /*Now, go pick up the objects inside the hooks: */ 469 this->nodes=(Node**)this->hnodes[analysis_counter].deliverp(); 470 this->matice=(Matice*)this->hmatice.delivers(); 471 this->matpar=(Matpar*)this->hmatpar.delivers(); 472 473 /*point parameters to real dataset: */ 474 this->parameters=parametersin; 475 476 } 477 /*}}}*/ 949 478 /*FUNCTION Tria::CostFunction {{{1*/ 950 479 double Tria::CostFunction(void){ … … 1070 599 CreateKMatrixDiagnosticHutter( Kgg); 1071 600 } 1072 else if (analysis_type== SlopeAnalysisEnum){601 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 1073 602 CreateKMatrixSlopeCompute( Kgg); 1074 603 } … … 1091 620 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type)); 1092 621 } 1093 1094 }1095 /*}}}*/1096 /*FUNCTION Tria::CreateKMatrixBalancedthickness {{{1*/1097 void Tria::CreateKMatrixBalancedthickness(Mat Kgg){1098 1099 /* local declarations */1100 int i,j;1101 1102 /* node data: */1103 const int numgrids=3;1104 const int NDOF1=1;1105 const int numdof=NDOF1*numgrids;1106 double xyz_list[numgrids][3];1107 int doflist[numdof];1108 int numberofdofspernode;1109 1110 /* gaussian points: */1111 int num_gauss,ig;1112 double* first_gauss_area_coord = NULL;1113 double* second_gauss_area_coord = NULL;1114 double* third_gauss_area_coord = NULL;1115 double* gauss_weights = NULL;1116 double gauss_weight;1117 double gauss_l1l2l3[3];1118 1119 /* matrices: */1120 double L[numgrids];1121 double B[2][numgrids];1122 double Bprime[2][numgrids];1123 double DL[2][2]={0.0};1124 double DLprime[2][2]={0.0};1125 double DL_scalar;1126 double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix1127 double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1128 double Ke_gg_thickness1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1129 double Ke_gg_thickness2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1130 1131 double Jdettria;1132 1133 /*input parameters for structural analysis (diagnostic): */1134 double dvx[2];1135 double dvy[2];1136 double vx,vy;1137 double dvxdx,dvydy;1138 double v_gauss[2]={0.0};1139 1140 1141 double K[2][2]={0.0};1142 double KDL[2][2]={0.0};1143 int dofs[2]={0,1};1144 int found=0;1145 1146 /*parameters: */1147 bool artdiff;1148 1149 /* Get node coordinates and dof list: */1150 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1151 GetDofList(&doflist[0],&numberofdofspernode);1152 1153 /*retrieve some parameters: */1154 this->parameters->FindParam(&artdiff,ArtDiffEnum);1155 1156 //Create Artificial diffusivity once for all if requested1157 if(artdiff){1158 //Get the Jacobian determinant1159 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;1160 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);1161 1162 //Build K matrix (artificial diffusivity matrix)1163 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum);1164 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum);1165 1166 K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]);1167 K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);1168 }1169 1170 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1171 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1172 1173 /* Start looping on the number of gaussian points: */1174 for (ig=0; ig<num_gauss; ig++){1175 /*Pick up the gaussian point: */1176 gauss_weight=*(gauss_weights+ig);1177 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1178 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1179 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1180 1181 /* Get Jacobian determinant: */1182 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);1183 1184 /*Get B and B prime matrix: */1185 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);1186 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);1187 1188 //Get vx, vy and their derivatives at gauss point1189 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxAverageEnum);1190 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyAverageEnum);1191 1192 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum);1193 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum);1194 1195 dvxdx=dvx[0];1196 dvydy=dvy[1];1197 1198 DL_scalar=gauss_weight*Jdettria;1199 1200 //Create DL and DLprime matrix1201 DL[0][0]=DL_scalar*dvxdx;1202 DL[1][1]=DL_scalar*dvydy;1203 1204 DLprime[0][0]=DL_scalar*vx;1205 DLprime[1][1]=DL_scalar*vy;1206 1207 //Do the triple product tL*D*L.1208 //Ke_gg_thickness=B'*DLprime*Bprime;1209 1210 TripleMultiply( &B[0][0],2,numdof,1,1211 &DL[0][0],2,2,0,1212 &B[0][0],2,numdof,0,1213 &Ke_gg_thickness1[0][0],0);1214 1215 TripleMultiply( &B[0][0],2,numdof,1,1216 &DLprime[0][0],2,2,0,1217 &Bprime[0][0],2,numdof,0,1218 &Ke_gg_thickness2[0][0],0);1219 1220 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */1221 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j];1222 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j];1223 1224 if(artdiff){1225 1226 /* Compute artificial diffusivity */1227 KDL[0][0]=DL_scalar*K[0][0];1228 KDL[1][1]=DL_scalar*K[1][1];1229 1230 TripleMultiply( &Bprime[0][0],2,numdof,1,1231 &KDL[0][0],2,2,0,1232 &Bprime[0][0],2,numdof,0,1233 &Ke_gg_gaussian[0][0],0);1234 1235 /* Add artificial diffusivity matrix */1236 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];1237 1238 }1239 } // for (ig=0; ig<num_gauss; ig++)1240 1241 /*Add Ke_gg to global matrix Kgg: */1242 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1243 1244 cleanup_and_return:1245 xfree((void**)&first_gauss_area_coord);1246 xfree((void**)&second_gauss_area_coord);1247 xfree((void**)&third_gauss_area_coord);1248 xfree((void**)&gauss_weights);1249 1250 }1251 /*}}}*/1252 /*FUNCTION Tria::CreateKMatrixBalancedthickness2 {{{1*/1253 void Tria::CreateKMatrixBalancedthickness2(Mat Kgg){1254 1255 /* local declarations */1256 int i,j;1257 1258 /* node data: */1259 const int numgrids=3;1260 const int NDOF1=1;1261 const int numdof=NDOF1*numgrids;1262 double xyz_list[numgrids][3];1263 int doflist[numdof];1264 int numberofdofspernode;1265 1266 /* gaussian points: */1267 int num_gauss,ig;1268 double* first_gauss_area_coord = NULL;1269 double* second_gauss_area_coord = NULL;1270 double* third_gauss_area_coord = NULL;1271 double* gauss_weights = NULL;1272 double gauss_weight;1273 double gauss_l1l2l3[3];1274 1275 /* matrices: */1276 double B[2][numgrids];1277 double Bprime[2][numgrids];1278 double DL[2][2]={0.0};1279 double DLprime[2][2]={0.0};1280 double DL_scalar;1281 double Ke_gg[numdof][numdof]={0.0};1282 double Ke_gg2[numdof][numdof]={0.0};1283 double Jdettria;1284 1285 /*input parameters for structural analysis (diagnostic): */1286 double vx,vy;1287 int dofs[1]={0};1288 int found;1289 1290 /* Get node coordinates and dof list: */1291 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1292 GetDofList(&doflist[0],&numberofdofspernode);1293 1294 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1295 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1296 1297 /* Start looping on the number of gaussian points: */1298 for (ig=0; ig<num_gauss; ig++){1299 /*Pick up the gaussian point: */1300 gauss_weight=*(gauss_weights+ig);1301 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1302 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1303 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1304 1305 /* Get Jacobian determinant: */1306 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);1307 1308 /*Get B and B prime matrix: */1309 /*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/1310 GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);1311 GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);1312 1313 //Get vx, vy and their derivatives at gauss point1314 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);1315 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);1316 1317 DL_scalar=-gauss_weight*Jdettria;1318 1319 DLprime[0][0]=DL_scalar*vx;1320 DLprime[1][1]=DL_scalar*vy;1321 1322 //Do the triple product tL*D*L.1323 TripleMultiply( &B[0][0],2,numdof,1,1324 &DLprime[0][0],2,2,0,1325 &Bprime[0][0],2,numdof,0,1326 &Ke_gg2[0][0],0);1327 1328 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */1329 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j];1330 1331 } // for (ig=0; ig<num_gauss; ig++)1332 1333 /*Add Ke_gg to global matrix Kgg: */1334 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1335 1336 cleanup_and_return:1337 xfree((void**)&first_gauss_area_coord);1338 xfree((void**)&second_gauss_area_coord);1339 xfree((void**)&third_gauss_area_coord);1340 xfree((void**)&gauss_weights);1341 1342 }1343 /*}}}*/1344 /*FUNCTION Tria::CreateKMatrixBalancedvelocities {{{1*/1345 void Tria::CreateKMatrixBalancedvelocities(Mat Kgg){1346 1347 /* local declarations */1348 int i,j;1349 1350 /* node data: */1351 const int numgrids=3;1352 const int NDOF1=1;1353 const int numdof=NDOF1*numgrids;1354 double xyz_list[numgrids][3];1355 int doflist[numdof];1356 int numberofdofspernode;1357 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};1358 1359 /* gaussian points: */1360 int num_gauss,ig;1361 double* first_gauss_area_coord = NULL;1362 double* second_gauss_area_coord = NULL;1363 double* third_gauss_area_coord = NULL;1364 double* gauss_weights = NULL;1365 double gauss_weight;1366 double gauss_l1l2l3[3];1367 1368 /* matrices: */1369 double L[numgrids];1370 double B[2][numgrids];1371 double Bprime[2][numgrids];1372 double DL[2][2]={0.0};1373 double DLprime[2][2]={0.0};1374 double DL_scalar;1375 double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix1376 double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1377 double Ke_gg_velocities1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1378 double Ke_gg_velocities2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point.1379 double Jdettria;1380 1381 /*input parameters for structural analysis (diagnostic): */1382 double surface_normal[3];1383 double surface_list[3];1384 double nx,ny,norm;1385 double dvx[2];1386 double dvy[2];1387 double vx,vy;1388 double dvxdx,dvydy;1389 double v_gauss[2]={0.0};1390 double K[2][2]={0.0};1391 double KDL[2][2]={0.0};1392 int dofs[2]={0,1};1393 int found=0;1394 1395 /*parameters: */1396 bool artdiff;1397 1398 /*retrieve some parameters: */1399 this->parameters->FindParam(&artdiff,ArtDiffEnum);1400 1401 /* Get node coordinates and dof list: */1402 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1403 GetDofList(&doflist[0],&numberofdofspernode);1404 1405 /*Modify z so that it reflects the surface*/1406 inputs->GetParameterValues(&surface_list[0],&gaussgrids[0][0],3,SurfaceEnum);1407 for(i=0;i<numgrids;i++) xyz_list[i][2]=surface_list[i];1408 1409 /*Get normal vector to the surface*/1410 inputs->GetParameterAverage(&nx,VxAverageEnum);1411 inputs->GetParameterAverage(&ny,VyAverageEnum);1412 if(nx==0 && ny==0){1413 SurfaceNormal(&surface_normal[0],xyz_list);1414 nx=surface_normal[0];1415 ny=surface_normal[1];1416 }1417 if(nx==0 && ny==0){1418 nx=0;1419 ny=1;1420 }1421 norm=pow( pow(nx,2)+pow(ny,2) , (double).5);1422 nx=nx/norm;1423 ny=ny/norm;1424 1425 //Create Artificial diffusivity once for all if requested1426 if(artdiff){1427 //Get the Jacobian determinant1428 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;1429 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);1430 1431 //Build K matrix (artificial diffusivity matrix)1432 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum);1433 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum);1434 1435 K[0][0]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]); //pow should be zero!!1436 K[1][1]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);1437 }1438 1439 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1440 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1441 1442 /* Start looping on the number of gaussian points: */1443 for (ig=0; ig<num_gauss; ig++){1444 /*Pick up the gaussian point: */1445 gauss_weight=*(gauss_weights+ig);1446 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1447 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1448 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1449 1450 /* Get Jacobian determinant: */1451 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);1452 1453 /*Get B and B prime matrix: */1454 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);1455 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);1456 1457 //Get vx, vy and their derivatives at gauss point1458 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum);1459 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum);1460 1461 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum);1462 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum);1463 1464 dvxdx=dvx[0];1465 dvydy=dvy[1];1466 1467 DL_scalar=gauss_weight*Jdettria;1468 1469 DLprime[0][0]=DL_scalar*nx;1470 DLprime[1][1]=DL_scalar*ny;1471 1472 //Do the triple product tL*D*L.1473 //Ke_gg_velocities=B'*DLprime*Bprime;1474 TripleMultiply( &B[0][0],2,numdof,1,1475 &DLprime[0][0],2,2,0,1476 &Bprime[0][0],2,numdof,0,1477 &Ke_gg_velocities2[0][0],0);1478 1479 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */1480 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_velocities2[i][j];1481 1482 if(artdiff){1483 1484 /* Compute artificial diffusivity */1485 KDL[0][0]=DL_scalar*K[0][0];1486 KDL[1][1]=DL_scalar*K[1][1];1487 1488 TripleMultiply( &Bprime[0][0],2,numdof,1,1489 &KDL[0][0],2,2,0,1490 &Bprime[0][0],2,numdof,0,1491 &Ke_gg_gaussian[0][0],0);1492 1493 /* Add artificial diffusivity matrix */1494 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];1495 1496 }1497 1498 } // for (ig=0; ig<num_gauss; ig++)1499 1500 /*Add Ke_gg to global matrix Kgg: */1501 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1502 1503 1504 cleanup_and_return:1505 xfree((void**)&first_gauss_area_coord);1506 xfree((void**)&second_gauss_area_coord);1507 xfree((void**)&third_gauss_area_coord);1508 xfree((void**)&gauss_weights);1509 1510 }1511 /*}}}*/1512 /*FUNCTION Tria::CreateKMatrixDiagnosticHoriz {{{1*/1513 void Tria::CreateKMatrixDiagnosticHoriz(Mat Kgg){1514 1515 /* local declarations */1516 int i,j;1517 1518 /* node data: */1519 const int numgrids=3;1520 const int numdof=2*numgrids;1521 double xyz_list[numgrids][3];1522 int doflist[numdof];1523 int numberofdofspernode;1524 1525 /* gaussian points: */1526 int num_gauss,ig;1527 double* first_gauss_area_coord = NULL;1528 double* second_gauss_area_coord = NULL;1529 double* third_gauss_area_coord = NULL;1530 double* gauss_weights = NULL;1531 double gauss_weight;1532 double gauss_l1l2l3[3];1533 1534 /* material data: */1535 double viscosity; //viscosity1536 double newviscosity; //viscosity1537 double oldviscosity; //viscosity1538 1539 /* strain rate: */1540 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/1541 double oldepsilon[3]; /* oldepsilon=[exx,eyy,exy];*/1542 1543 /* matrices: */1544 double B[3][numdof];1545 double Bprime[3][numdof];1546 double D[3][3]={0.0}; // material matrix, simple scalar matrix.1547 double D_scalar;1548 1549 /*parameters: */1550 double viscosity_overshoot;1551 1552 /* local element matrices: */1553 double Ke_gg[numdof][numdof]={0.0};1554 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.1555 1556 double Jdet;1557 1558 /*input parameters for structural analysis (diagnostic): */1559 double thickness;1560 int dofs[2]={0,1};1561 1562 /*inputs: */1563 bool onwater,shelf;1564 1565 /*retrieve inputs :*/1566 inputs->GetParameterValue(&onwater,ElementOnWaterEnum);1567 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);1568 1569 /*retrieve some parameters: */1570 this->parameters->FindParam(&viscosity_overshoot,ViscosityOvershootEnum);1571 1572 /*First, if we are on water, return empty matrix: */1573 if(onwater) return;1574 1575 /* Get node coordinates and dof list: */1576 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1577 GetDofList(&doflist[0],&numberofdofspernode);1578 1579 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1580 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1581 1582 /* Start looping on the number of gaussian points: */1583 for (ig=0; ig<num_gauss; ig++){1584 /*Pick up the gaussian point: */1585 gauss_weight=*(gauss_weights+ig);1586 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1587 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1588 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1589 1590 1591 /*Compute thickness at gaussian point: */1592 inputs->GetParameterValue(&thickness, gauss_l1l2l3,ThicknessEnum);1593 1594 /*Get strain rate from velocity: */1595 inputs->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxEnum,VyEnum);1596 inputs->GetStrainRate2d(&oldepsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxOldEnum,VyOldEnum);1597 1598 /*Get viscosity: */1599 matice->GetViscosity2d(&viscosity, &epsilon[0]);1600 matice->GetViscosity2d(&oldviscosity, &oldepsilon[0]);1601 1602 /* Get Jacobian determinant: */1603 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);1604 1605 /* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant1606 onto this scalar matrix, so that we win some computational time: */1607 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);1608 D_scalar=newviscosity*thickness*gauss_weight*Jdet;1609 1610 for (i=0;i<3;i++){1611 D[i][i]=D_scalar;1612 }1613 1614 /*Get B and Bprime matrices: */1615 GetB(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);1616 GetBPrime(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);1617 1618 /* Do the triple product tB*D*Bprime: */1619 TripleMultiply( &B[0][0],3,numdof,1,1620 &D[0][0],3,3,0,1621 &Bprime[0][0],3,numdof,0,1622 &Ke_gg_gaussian[0][0],0);1623 1624 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */1625 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];1626 1627 } // for (ig=0; ig<num_gauss; ig++)1628 1629 /*Add Ke_gg to global matrix Kgg: */1630 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1631 1632 /*Do not forget to include friction: */1633 if(!shelf){1634 CreateKMatrixDiagnosticHorizFriction(Kgg);1635 }1636 1637 cleanup_and_return:1638 xfree((void**)&first_gauss_area_coord);1639 xfree((void**)&second_gauss_area_coord);1640 xfree((void**)&third_gauss_area_coord);1641 xfree((void**)&gauss_weights);1642 1643 }1644 /*}}}*/1645 /*FUNCTION Tria::CreateKMatrixDiagnosticHorizFriction {{{1*/1646 void Tria::CreateKMatrixDiagnosticHorizFriction(Mat Kgg){1647 1648 1649 /* local declarations */1650 int i,j;1651 int analysis_type;1652 1653 /* node data: */1654 const int numgrids=3;1655 const int numdof=2*numgrids;1656 double xyz_list[numgrids][3];1657 int doflist[numdof];1658 int numberofdofspernode;1659 1660 /* gaussian points: */1661 int num_gauss,ig;1662 double* first_gauss_area_coord = NULL;1663 double* second_gauss_area_coord = NULL;1664 double* third_gauss_area_coord = NULL;1665 double* gauss_weights = NULL;1666 double gauss_weight;1667 double gauss_l1l2l3[3];1668 1669 /* matrices: */1670 double L[2][numdof];1671 double DL[2][2]={{ 0,0 },{0,0}}; //for basal drag1672 double DL_scalar;1673 1674 /* local element matrices: */1675 double Ke_gg[numdof][numdof]={0.0};1676 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag1677 1678 double Jdet;1679 1680 /*slope: */1681 double slope[2]={0.0,0.0};1682 double slope_magnitude;1683 1684 /*friction: */1685 Friction* friction=NULL;1686 double alpha2;1687 1688 double MAXSLOPE=.06; // 6 %1689 double MOUNTAINKEXPONENT=10;1690 1691 /*inputs: */1692 bool shelf;1693 int drag_type;1694 1695 /*retrive parameters: */1696 parameters->FindParam(&analysis_type,AnalysisTypeEnum);1697 1698 /*retrieve inputs :*/1699 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);1700 inputs->GetParameterValue(&drag_type,DragTypeEnum);1701 1702 /* Get node coordinates and dof list: */1703 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1704 GetDofList(&doflist[0],&numberofdofspernode);1705 1706 if (shelf){1707 /*no friction, do nothing*/1708 return;1709 }1710 1711 /*build friction object, used later on: */1712 if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!");1713 friction=new Friction("2d",inputs,matpar,analysis_type);1714 1715 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1716 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1717 1718 /* Start looping on the number of gaussian points: */1719 for (ig=0; ig<num_gauss; ig++){1720 /*Pick up the gaussian point: */1721 gauss_weight=*(gauss_weights+ig);1722 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1723 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1724 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1725 1726 /*Friction: */1727 friction->GetAlpha2(&alpha2, gauss_l1l2l3,VxEnum,VyEnum,VzEnum);1728 1729 // If we have a slope > 6% for this element, it means we are on a mountain. In this particular case,1730 //velocity should be = 0. To achieve this result, we set alpha2_list to a very high value: */1731 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);1732 slope_magnitude=sqrt(pow(slope[0],2)+pow(slope[1],2));1733 1734 if (slope_magnitude>MAXSLOPE){1735 alpha2=pow((double)10,MOUNTAINKEXPONENT);1736 }1737 1738 /* Get Jacobian determinant: */1739 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);1740 1741 /*Get L matrix: */1742 GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);1743 1744 1745 DL_scalar=alpha2*gauss_weight*Jdet;1746 for (i=0;i<2;i++){1747 DL[i][i]=DL_scalar;1748 }1749 1750 /* Do the triple producte tL*D*L: */1751 TripleMultiply( &L[0][0],2,numdof,1,1752 &DL[0][0],2,2,0,1753 &L[0][0],2,numdof,0,1754 &Ke_gg_gaussian[0][0],0);1755 1756 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];1757 1758 } // for (ig=0; ig<num_gauss; ig++)1759 1760 /*Add Ke_gg to global matrix Kgg: */1761 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1762 1763 cleanup_and_return:1764 xfree((void**)&first_gauss_area_coord);1765 xfree((void**)&second_gauss_area_coord);1766 xfree((void**)&third_gauss_area_coord);1767 xfree((void**)&gauss_weights);1768 delete friction;1769 1770 }1771 /*}}}*/1772 /*FUNCTION Tria::CreateKMatrixDiagnosticHutter{{{1*/1773 void Tria::CreateKMatrixDiagnosticHutter(Mat Kgg){1774 1775 /*Collapsed formulation: */1776 Sing* sing=NULL;1777 int i;1778 1779 /*flags: */1780 bool onwater;1781 1782 /*recover some inputs: */1783 inputs->GetParameterValue(&onwater,ElementOnWaterEnum);1784 1785 /*If on water, skip: */1786 if(onwater)return;1787 1788 /*Spawn 3 sing elements: */1789 for(i=0;i<3;i++){1790 sing=(Sing*)SpawnSing(i);1791 sing->CreateKMatrix(Kgg);1792 }1793 1794 /*clean up*/1795 delete sing;1796 1797 }1798 /*}}}*/1799 /*FUNCTION Tria::CreateKMatrixDiagnosticSurfaceVert {{{1*/1800 void Tria::CreateKMatrixDiagnosticSurfaceVert(Mat Kgg){1801 1802 int i,j;1803 1804 /* node data: */1805 const int numgrids=3;1806 const int NDOF1=1;1807 const int numdof=NDOF1*numgrids;1808 double xyz_list[numgrids][3];1809 int doflist[numdof];1810 int numberofdofspernode;1811 1812 /* gaussian points: */1813 int num_gauss,ig;1814 double* first_gauss_area_coord = NULL;1815 double* second_gauss_area_coord = NULL;1816 double* third_gauss_area_coord = NULL;1817 double* gauss_weights = NULL;1818 double gauss_weight;1819 double gauss_l1l2l3[3];1820 1821 1822 /* surface normal: */1823 double x4,y4,z4;1824 double x5,y5,z5;1825 double x6,y6,z6;1826 double v46[3];1827 double v56[3];1828 double normal[3];1829 double norm_normal;1830 double nz;1831 1832 /*Matrices: */1833 double DL_scalar;1834 double L[3];1835 double Jdet;1836 1837 /* local element matrices: */1838 double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix1839 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.1840 1841 /* Get node coordinates and dof list: */1842 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1843 GetDofList(&doflist[0],&numberofdofspernode);1844 1845 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */1846 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1847 1848 /*Build normal vector to the surface:*/1849 1850 x4=xyz_list[0][0];1851 y4=xyz_list[0][1];1852 z4=xyz_list[0][2];1853 1854 x5=xyz_list[1][0];1855 y5=xyz_list[1][1];1856 z5=xyz_list[1][2];1857 1858 x6=xyz_list[2][0];1859 y6=xyz_list[2][1];1860 z6=xyz_list[2][2];1861 1862 v46[0]=x4-x6;1863 v46[1]=y4-y6;1864 v46[2]=z4-z6;1865 1866 v56[0]=x5-x6;1867 v56[1]=y5-y6;1868 v56[2]=z5-z6;1869 1870 normal[0]=(y4-y6)*(z5-z6)-(z4-z6)*(y5-y6);1871 normal[1]=(z4-z6)*(x5-x6)-(x4-x6)*(z5-z6);1872 normal[2]=(x4-x6)*(y5-y6)-(y4-y6)*(x5-x6);1873 1874 norm_normal=sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2));1875 nz=1.0/norm_normal*normal[2];1876 1877 /* Start looping on the number of gaussian points: */1878 for (ig=0; ig<num_gauss; ig++){1879 /*Pick up the gaussian point: */1880 gauss_weight=*(gauss_weights+ig);1881 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);1882 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);1883 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);1884 1885 /* Get Jacobian determinant: */1886 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);1887 1888 //Get L matrix if viscous basal drag present:1889 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);1890 1891 /**********************Do not forget the sign**********************************/1892 DL_scalar=- gauss_weight*Jdet*nz;1893 /******************************************************************************/1894 1895 /* Do the triple producte tL*D*L: */1896 TripleMultiply( L,1,3,1,1897 &DL_scalar,1,1,0,1898 L,1,3,0,1899 &Ke_gg_gaussian[0][0],0);1900 1901 /* Add the Ke_gg_gaussian, onto Ke_gg: */1902 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];1903 1904 1905 } //for (ig=0; ig<num_gauss; ig++)1906 1907 /*Add Ke_gg to global matrix Kgg: */1908 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);1909 1910 cleanup_and_return:1911 xfree((void**)&first_gauss_area_coord);1912 xfree((void**)&second_gauss_area_coord);1913 xfree((void**)&third_gauss_area_coord);1914 xfree((void**)&gauss_weights);1915 }1916 /*}}}*/1917 /*FUNCTION Tria::CreateKMatrixMelting {{{1*/1918 void Tria::CreateKMatrixMelting(Mat Kgg){1919 1920 /*indexing: */1921 int i,j;1922 1923 const int numgrids=3;1924 const int NDOF1=1;1925 const int numdof=numgrids*NDOF1;1926 int doflist[numdof];1927 int numberofdofspernode;1928 1929 /*Grid data: */1930 double xyz_list[numgrids][3];1931 1932 /*Material constants */1933 double heatcapacity,latentheat;1934 1935 /* gaussian points: */1936 int num_area_gauss,ig;1937 double* gauss_weights = NULL;1938 double* first_gauss_area_coord = NULL;1939 double* second_gauss_area_coord = NULL;1940 double* third_gauss_area_coord = NULL;1941 double gauss_weight;1942 double gauss_coord[3];1943 1944 /*matrices: */1945 double Jdet;1946 double D_scalar;1947 double K_terms[numdof][numdof]={0.0};1948 double L[3];1949 double tLD[3];1950 double Ke_gaussian[numdof][numdof]={0.0};1951 1952 /*Recover constants of ice */1953 latentheat=matpar->GetLatentHeat();1954 heatcapacity=matpar->GetHeatCapacity();1955 1956 /* Get node coordinates and dof list: */1957 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);1958 GetDofList(&doflist[0],&numberofdofspernode);1959 1960 /* Get gaussian points and weights: */1961 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);1962 1963 /* Start looping on the number of gauss (nodes on the bedrock) */1964 for (ig=0; ig<num_area_gauss; ig++){1965 gauss_weight=*(gauss_weights+ig);1966 gauss_coord[0]=*(first_gauss_area_coord+ig);1967 gauss_coord[1]=*(second_gauss_area_coord+ig);1968 gauss_coord[2]=*(third_gauss_area_coord+ig);1969 1970 //Get the Jacobian determinant1971 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);1972 1973 /*Get L matrix : */1974 GetL(&L[0], &xyz_list[0][0], gauss_coord,NDOF1);1975 1976 /*Calculate DL on gauss point */1977 D_scalar=latentheat/heatcapacity*gauss_weight*Jdet;1978 1979 /* Do the triple product tL*D*L: */1980 MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0);1981 MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian[0][0],0);1982 1983 for(i=0;i<numgrids;i++){1984 for(j=0;j<numgrids;j++){1985 K_terms[i][j]+=Ke_gaussian[i][j];1986 }1987 }1988 }1989 1990 /*Add Ke_gg to global matrix Kgg: */1991 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);1992 1993 cleanup_and_return:1994 xfree((void**)&first_gauss_area_coord);1995 xfree((void**)&second_gauss_area_coord);1996 xfree((void**)&third_gauss_area_coord);1997 xfree((void**)&gauss_weights);1998 1999 }2000 /*}}}*/2001 /*FUNCTION Tria::CreateKMatrixPrognostic {{{1*/2002 void Tria::CreateKMatrixPrognostic(Mat Kgg){2003 2004 /* local declarations */2005 int i,j;2006 2007 /* node data: */2008 const int numgrids=3;2009 const int NDOF1=1;2010 const int numdof=NDOF1*numgrids;2011 double xyz_list[numgrids][3];2012 int doflist[numdof];2013 int numberofdofspernode;2014 2015 /* gaussian points: */2016 int num_gauss,ig;2017 double* first_gauss_area_coord = NULL;2018 double* second_gauss_area_coord = NULL;2019 double* third_gauss_area_coord = NULL;2020 double* gauss_weights = NULL;2021 double gauss_weight;2022 double gauss_l1l2l3[3];2023 2024 /* matrices: */2025 double L[numgrids];2026 double B[2][numgrids];2027 double Bprime[2][numgrids];2028 double DL[2][2]={0.0};2029 double DLprime[2][2]={0.0};2030 double DL_scalar;2031 double Ke_gg[numdof][numdof]={0.0};2032 double Ke_gg_gaussian[numdof][numdof]={0.0};2033 double Ke_gg_thickness1[numdof][numdof]={0.0};2034 double Ke_gg_thickness2[numdof][numdof]={0.0};2035 double Jdettria;2036 2037 /*input parameters for structural analysis (diagnostic): */2038 double dvx[2];2039 double dvy[2];2040 double vx,vy;2041 double dvxdx,dvydy;2042 double v_gauss[2]={0.0};2043 double K[2][2]={0.0};2044 double KDL[2][2]={0.0};2045 int dofs[2]={0,1};2046 int found;2047 2048 /*parameters: */2049 double dt;2050 bool artdiff;2051 2052 /*retrieve some parameters: */2053 this->parameters->FindParam(&dt,DtEnum);2054 this->parameters->FindParam(&artdiff,ArtDiffEnum);2055 2056 /* Get node coordinates and dof list: */2057 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2058 GetDofList(&doflist[0],&numberofdofspernode);2059 2060 //Create Artificial diffusivity once for all if requested2061 if(artdiff){2062 //Get the Jacobian determinant2063 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD;2064 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2065 2066 //Build K matrix (artificial diffusivity matrix)2067 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum);2068 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum);2069 2070 K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]);2071 K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]);2072 }2073 2074 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2075 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2076 2077 /* Start looping on the number of gaussian points: */2078 for (ig=0; ig<num_gauss; ig++){2079 2080 /*Pick up the gaussian point: */2081 gauss_weight=*(gauss_weights+ig);2082 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2083 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2084 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2085 2086 /* Get Jacobian determinant: */2087 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2088 2089 /*Get L matrix: */2090 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);2091 2092 DL_scalar=gauss_weight*Jdettria;2093 2094 /* Do the triple product tL*D*L: */2095 TripleMultiply( &L[0],1,numdof,1,2096 &DL_scalar,1,1,0,2097 &L[0],1,numdof,0,2098 &Ke_gg_gaussian[0][0],0);2099 2100 /*Get B and B prime matrix: */2101 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);2102 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);2103 2104 //Get vx, vy and their derivatives at gauss point2105 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum);2106 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum);2107 2108 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum);2109 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum);2110 2111 dvxdx=dvx[0];2112 dvydy=dvy[1];2113 2114 DL_scalar=dt*gauss_weight*Jdettria;2115 2116 //Create DL and DLprime matrix2117 DL[0][0]=DL_scalar*dvxdx;2118 DL[1][1]=DL_scalar*dvydy;2119 2120 DLprime[0][0]=DL_scalar*vx;2121 DLprime[1][1]=DL_scalar*vy;2122 2123 //Do the triple product tL*D*L.2124 //Ke_gg_thickness=B'*DL*B+B'*DLprime*Bprime;2125 2126 TripleMultiply( &B[0][0],2,numdof,1,2127 &DL[0][0],2,2,0,2128 &B[0][0],2,numdof,0,2129 &Ke_gg_thickness1[0][0],0);2130 2131 TripleMultiply( &B[0][0],2,numdof,1,2132 &DLprime[0][0],2,2,0,2133 &Bprime[0][0],2,numdof,0,2134 &Ke_gg_thickness2[0][0],0);2135 2136 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */2137 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];2138 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j];2139 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j];2140 2141 if(artdiff){2142 2143 /* Compute artificial diffusivity */2144 KDL[0][0]=DL_scalar*K[0][0];2145 KDL[1][1]=DL_scalar*K[1][1];2146 2147 TripleMultiply( &Bprime[0][0],2,numdof,1,2148 &KDL[0][0],2,2,0,2149 &Bprime[0][0],2,numdof,0,2150 &Ke_gg_gaussian[0][0],0);2151 2152 /* Add artificial diffusivity matrix */2153 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];2154 2155 }2156 2157 } // for (ig=0; ig<num_gauss; ig++)2158 2159 /*Add Ke_gg to global matrix Kgg: */2160 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);2161 2162 2163 cleanup_and_return:2164 xfree((void**)&first_gauss_area_coord);2165 xfree((void**)&second_gauss_area_coord);2166 xfree((void**)&third_gauss_area_coord);2167 xfree((void**)&gauss_weights);2168 2169 }2170 /*}}}*/2171 /*FUNCTION Tria::CreateKMatrixPrognostic2 {{{1*/2172 void Tria::CreateKMatrixPrognostic2(Mat Kgg){2173 2174 /* local declarations */2175 int i,j;2176 2177 /* node data: */2178 const int numgrids=3;2179 const int NDOF1=1;2180 const int numdof=NDOF1*numgrids;2181 double xyz_list[numgrids][3];2182 int doflist[numdof];2183 int numberofdofspernode;2184 2185 /* gaussian points: */2186 int num_gauss,ig;2187 double* first_gauss_area_coord = NULL;2188 double* second_gauss_area_coord = NULL;2189 double* third_gauss_area_coord = NULL;2190 double* gauss_weights = NULL;2191 double gauss_weight;2192 double gauss_l1l2l3[3];2193 2194 /* matrices: */2195 double L[numgrids];2196 double B[2][numgrids];2197 double Bprime[2][numgrids];2198 double DL[2][2]={0.0};2199 double DLprime[2][2]={0.0};2200 double DL_scalar;2201 double Ke_gg[numdof][numdof]={0.0};2202 double Ke_gg1[numdof][numdof]={0.0};2203 double Ke_gg2[numdof][numdof]={0.0};2204 double Jdettria;2205 2206 /*input parameters for structural analysis (diagnostic): */2207 double vx,vy;2208 int dofs[1]={0};2209 int found;2210 2211 /*parameters: */2212 double dt;2213 2214 /*retrieve some parameters: */2215 this->parameters->FindParam(&dt,DtEnum);2216 2217 /* Get node coordinates and dof list: */2218 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2219 GetDofList(&doflist[0],&numberofdofspernode);2220 2221 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2222 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2223 2224 /* Start looping on the number of gaussian points: */2225 for (ig=0; ig<num_gauss; ig++){2226 2227 /*Pick up the gaussian point: */2228 gauss_weight=*(gauss_weights+ig);2229 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2230 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2231 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2232 2233 /* Get Jacobian determinant: */2234 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2235 2236 /*Get L matrix: */2237 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);2238 2239 DL_scalar=gauss_weight*Jdettria;2240 2241 /* Do the triple product tL*D*L: */2242 TripleMultiply( &L[0],1,numdof,1,2243 &DL_scalar,1,1,0,2244 &L[0],1,numdof,0,2245 &Ke_gg1[0][0],0);2246 2247 /*Get B and B prime matrix: */2248 /*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/2249 GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3);2250 GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3);2251 2252 //Get vx, vy and their derivatives at gauss point2253 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum);2254 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum);2255 2256 DL_scalar=-dt*gauss_weight*Jdettria;2257 2258 DLprime[0][0]=DL_scalar*vx;2259 DLprime[1][1]=DL_scalar*vy;2260 2261 //Do the triple product tL*D*L.2262 TripleMultiply( &B[0][0],2,numdof,1,2263 &DLprime[0][0],2,2,0,2264 &Bprime[0][0],2,numdof,0,2265 &Ke_gg2[0][0],0);2266 2267 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */2268 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg1[i][j];2269 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j];2270 2271 } // for (ig=0; ig<num_gauss; ig++)2272 2273 /*Add Ke_gg to global matrix Kgg: */2274 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);2275 2276 2277 cleanup_and_return:2278 xfree((void**)&first_gauss_area_coord);2279 xfree((void**)&second_gauss_area_coord);2280 xfree((void**)&third_gauss_area_coord);2281 xfree((void**)&gauss_weights);2282 2283 }2284 /*}}}*/2285 /*FUNCTION Tria::CreateKMatrixSlopeCompute {{{1*/2286 2287 void Tria::CreateKMatrixSlopeCompute(Mat Kgg){2288 2289 /* local declarations */2290 int i,j;2291 2292 /* node data: */2293 const int numgrids=3;2294 const int NDOF1=1;2295 const int numdof=NDOF1*numgrids;2296 double xyz_list[numgrids][3];2297 int doflist[numdof];2298 int numberofdofspernode;2299 2300 /* gaussian points: */2301 int num_gauss,ig;2302 double* first_gauss_area_coord = NULL;2303 double* second_gauss_area_coord = NULL;2304 double* third_gauss_area_coord = NULL;2305 double* gauss_weights = NULL;2306 double gauss_weight;2307 double gauss_l1l2l3[3];2308 2309 /* matrices: */2310 double L[1][3];2311 double DL_scalar;2312 2313 /* local element matrices: */2314 double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix2315 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.2316 2317 double Jdet;2318 2319 /* Get node coordinates and dof list: */2320 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2321 GetDofList(&doflist[0],&numberofdofspernode);2322 2323 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2324 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2325 2326 /* Start looping on the number of gaussian points: */2327 for (ig=0; ig<num_gauss; ig++){2328 /*Pick up the gaussian point: */2329 gauss_weight=*(gauss_weights+ig);2330 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2331 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2332 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2333 2334 2335 /*Get L matrix: */2336 GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);2337 2338 /* Get Jacobian determinant: */2339 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);2340 2341 DL_scalar=gauss_weight*Jdet;2342 2343 /* Do the triple producte tL*D*L: */2344 TripleMultiply( &L[0][0],1,3,1,2345 &DL_scalar,1,1,0,2346 &L[0][0],1,3,0,2347 &Ke_gg_gaussian[0][0],0);2348 2349 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */2350 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];2351 } //for (ig=0; ig<num_gauss; ig++2352 2353 /*Add Ke_gg to global matrix Kgg: */2354 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);2355 2356 cleanup_and_return:2357 xfree((void**)&first_gauss_area_coord);2358 xfree((void**)&second_gauss_area_coord);2359 xfree((void**)&third_gauss_area_coord);2360 xfree((void**)&gauss_weights);2361 }2362 /*}}}*/2363 /*FUNCTION Tria::CreateKMatrixThermal {{{1*/2364 void Tria::CreateKMatrixThermal(Mat Kgg){2365 2366 int i,j;2367 int found=0;2368 2369 /* node data: */2370 const int numgrids=3;2371 const int NDOF1=1;2372 const int numdof=NDOF1*numgrids;2373 double xyz_list[numgrids][3];2374 int doflist[numdof];2375 int numberofdofspernode;2376 2377 double mixed_layer_capacity;2378 double thermal_exchange_velocity;2379 double rho_water;2380 double rho_ice;2381 double heatcapacity;2382 2383 int num_gauss,ig;2384 double* first_gauss_area_coord = NULL;2385 double* second_gauss_area_coord = NULL;2386 double* third_gauss_area_coord = NULL;2387 double* gauss_weights = NULL;2388 double gauss_weight;2389 double gauss_coord[3];2390 2391 /*matrices: */2392 double Jdet;2393 double K_terms[numdof][numdof]={0.0};2394 double Ke_gaussian[numdof][numdof]={0.0};2395 double l1l2l3[numgrids];2396 double tl1l2l3D[3];2397 double D_scalar;2398 2399 /*parameters: */2400 double dt;2401 2402 /*retrieve some parameters: */2403 this->parameters->FindParam(&dt,DtEnum);2404 2405 /* Get node coordinates and dof list: */2406 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2407 GetDofList(&doflist[0],&numberofdofspernode);2408 2409 //recover material parameters2410 mixed_layer_capacity=matpar->GetMixedLayerCapacity();2411 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();2412 rho_water=matpar->GetRhoWater();2413 rho_ice=matpar->GetRhoIce();2414 heatcapacity=matpar->GetHeatCapacity();2415 2416 2417 GaussTria (&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2418 2419 /* Start looping on the number of gauss (nodes on the bedrock) */2420 for (ig=0; ig<num_gauss; ig++){2421 gauss_weight=*(gauss_weights+ig);2422 gauss_coord[0]=*(first_gauss_area_coord+ig);2423 gauss_coord[1]=*(second_gauss_area_coord+ig);2424 gauss_coord[2]=*(third_gauss_area_coord+ig);2425 2426 //Get the Jacobian determinant2427 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord);2428 2429 /*Get nodal functions values: */2430 GetNodalFunctions(&l1l2l3[0], gauss_coord);2431 2432 /*Calculate DL on gauss point */2433 D_scalar=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice);2434 if(dt){2435 D_scalar=dt*D_scalar;2436 }2437 2438 /* Do the triple product tL*D*L: */2439 MatrixMultiply(&l1l2l3[0],numdof,1,0,&D_scalar,1,1,0,&tl1l2l3D[0],0);2440 MatrixMultiply(&tl1l2l3D[0],numdof,1,0,&l1l2l3[0],1,numdof,0,&Ke_gaussian[0][0],0);2441 2442 for(i=0;i<3;i++){2443 for(j=0;j<3;j++){2444 K_terms[i][j]+=Ke_gaussian[i][j];2445 }2446 }2447 }2448 2449 /*Add Ke_gg to global matrix Kgg: */2450 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);2451 2452 cleanup_and_return:2453 xfree((void**)&first_gauss_area_coord);2454 xfree((void**)&second_gauss_area_coord);2455 xfree((void**)&third_gauss_area_coord);2456 xfree((void**)&gauss_weights);2457 622 2458 623 } … … 2481 646 CreatePVectorDiagnosticHutter( pg); 2482 647 } 2483 else if (analysis_type== SlopeAnalysisEnum){648 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 2484 649 CreatePVectorSlopeCompute( pg); 2485 650 } … … 2502 667 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type)); 2503 668 } 2504 2505 }2506 /*}}}*/2507 /*FUNCTION Tria::CreatePVectorBalancedthickness {{{1*/2508 void Tria::CreatePVectorBalancedthickness(Vec pg ){2509 2510 2511 /* local declarations */2512 int i,j;2513 2514 /* node data: */2515 const int numgrids=3;2516 const int NDOF1=1;2517 const int numdof=NDOF1*numgrids;2518 double xyz_list[numgrids][3];2519 int doflist[numdof];2520 int numberofdofspernode;2521 2522 /* gaussian points: */2523 int num_gauss,ig;2524 double* first_gauss_area_coord = NULL;2525 double* second_gauss_area_coord = NULL;2526 double* third_gauss_area_coord = NULL;2527 double* gauss_weights = NULL;2528 double gauss_weight;2529 double gauss_l1l2l3[3];2530 2531 /* matrix */2532 double pe_g[numgrids]={0.0};2533 double L[numgrids];2534 double Jdettria;2535 2536 /*input parameters for structural analysis (diagnostic): */2537 double accumulation_g;2538 double melting_g;2539 2540 /* Get node coordinates and dof list: */2541 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2542 GetDofList(&doflist[0],&numberofdofspernode);2543 2544 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2545 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2546 2547 /* Start looping on the number of gaussian points: */2548 for (ig=0; ig<num_gauss; ig++){2549 /*Pick up the gaussian point: */2550 gauss_weight=*(gauss_weights+ig);2551 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2552 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2553 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2554 2555 /* Get Jacobian determinant: */2556 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2557 2558 /*Get L matrix: */2559 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);2560 2561 /* Get accumulation, melting at gauss point */2562 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);2563 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);2564 2565 /* Add value into pe_g: */2566 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i];2567 2568 } // for (ig=0; ig<num_gauss; ig++)2569 2570 /*Add pe_g to global matrix Kgg: */2571 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);2572 2573 cleanup_and_return:2574 xfree((void**)&first_gauss_area_coord);2575 xfree((void**)&second_gauss_area_coord);2576 xfree((void**)&third_gauss_area_coord);2577 xfree((void**)&gauss_weights);2578 2579 }2580 /*}}}*/2581 /*FUNCTION Tria::CreatePVectorBalancedthickness2 {{{1*/2582 void Tria::CreatePVectorBalancedthickness2(Vec pg){2583 2584 2585 /* local declarations */2586 int i,j;2587 2588 /* node data: */2589 const int numgrids=3;2590 const int NDOF1=1;2591 const int numdof=NDOF1*numgrids;2592 double xyz_list[numgrids][3];2593 int doflist[numdof];2594 int numberofdofspernode;2595 2596 /* gaussian points: */2597 int num_gauss,ig;2598 double* first_gauss_area_coord = NULL;2599 double* second_gauss_area_coord = NULL;2600 double* third_gauss_area_coord = NULL;2601 double* gauss_weights = NULL;2602 double gauss_weight;2603 double gauss_l1l2l3[3];2604 2605 /* matrix */2606 double pe_g[numgrids]={0.0};2607 double L[numgrids];2608 double Jdettria;2609 2610 /*input parameters for structural analysis (diagnostic): */2611 double accumulation_g;2612 double melting_g;2613 double dhdt_g;2614 2615 /* Get node coordinates and dof list: */2616 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2617 GetDofList(&doflist[0],&numberofdofspernode);2618 2619 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2620 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2621 2622 /* Start looping on the number of gaussian points: */2623 for (ig=0; ig<num_gauss; ig++){2624 /*Pick up the gaussian point: */2625 gauss_weight=*(gauss_weights+ig);2626 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2627 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2628 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2629 2630 /* Get Jacobian determinant: */2631 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2632 2633 /*Get L matrix: */2634 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);2635 2636 /* Get accumulation, melting and thickness at gauss point */2637 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);2638 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);2639 inputs->GetParameterValue(&dhdt_g, &gauss_l1l2l3[0],DhDtEnum);2640 2641 /* Add value into pe_g: */2642 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g+dhdt_g)*L[i];2643 2644 } // for (ig=0; ig<num_gauss; ig++)2645 2646 /*Add pe_g to global matrix Kgg: */2647 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);2648 2649 cleanup_and_return:2650 xfree((void**)&first_gauss_area_coord);2651 xfree((void**)&second_gauss_area_coord);2652 xfree((void**)&third_gauss_area_coord);2653 xfree((void**)&gauss_weights);2654 2655 }2656 /*}}}*/2657 /*FUNCTION Tria::CreatePVectorBalancedvelocities {{{1*/2658 void Tria::CreatePVectorBalancedvelocities(Vec pg){2659 2660 2661 /* local declarations */2662 int i,j;2663 2664 /* node data: */2665 const int numgrids=3;2666 const int NDOF1=1;2667 const int numdof=NDOF1*numgrids;2668 double xyz_list[numgrids][3];2669 int doflist[numdof];2670 int numberofdofspernode;2671 2672 /* gaussian points: */2673 int num_gauss,ig;2674 double* first_gauss_area_coord = NULL;2675 double* second_gauss_area_coord = NULL;2676 double* third_gauss_area_coord = NULL;2677 double* gauss_weights = NULL;2678 double gauss_weight;2679 double gauss_l1l2l3[3];2680 2681 /* matrix */2682 double pe_g[numgrids]={0.0};2683 double L[numgrids];2684 double Jdettria;2685 2686 /*input parameters for structural analysis (diagnostic): */2687 double accumulation_g;2688 double melting_g;2689 2690 /* Get node coordinates and dof list: */2691 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2692 GetDofList(&doflist[0],&numberofdofspernode);2693 2694 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2695 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2696 2697 /* Start looping on the number of gaussian points: */2698 for (ig=0; ig<num_gauss; ig++){2699 /*Pick up the gaussian point: */2700 gauss_weight=*(gauss_weights+ig);2701 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2702 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2703 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2704 2705 /* Get Jacobian determinant: */2706 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);2707 2708 /*Get L matrix: */2709 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);2710 2711 /* Get accumulation, melting at gauss point */2712 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);2713 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);2714 2715 /* Add value into pe_g: */2716 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i];2717 2718 } // for (ig=0; ig<num_gauss; ig++)2719 2720 /*Add pe_g to global matrix Kgg: */2721 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);2722 2723 cleanup_and_return:2724 xfree((void**)&first_gauss_area_coord);2725 xfree((void**)&second_gauss_area_coord);2726 xfree((void**)&third_gauss_area_coord);2727 xfree((void**)&gauss_weights);2728 2729 }2730 /*}}}*/2731 /*FUNCTION Tria::CreatePVectorDiagnosticBaseVert {{{1*/2732 void Tria::CreatePVectorDiagnosticBaseVert(Vec pg){2733 2734 int i,j;2735 2736 /* node data: */2737 const int numgrids=3;2738 const int NDOF1=1;2739 const int numdof=NDOF1*numgrids;2740 double xyz_list[numgrids][3];2741 int doflist[numdof];2742 int numberofdofspernode;2743 2744 /* gaussian points: */2745 int num_gauss,ig;2746 double* first_gauss_area_coord = NULL;2747 double* second_gauss_area_coord = NULL;2748 double* third_gauss_area_coord = NULL;2749 double* gauss_weights = NULL;2750 double gauss_weight;2751 double gauss_l1l2l3[3];2752 2753 /* Jacobian: */2754 double Jdet;2755 2756 /*nodal functions: */2757 double l1l2l3[3];2758 2759 /*element vector at the gaussian points: */2760 double pe_g[numdof]={0.0};2761 double pe_g_gaussian[numdof];2762 2763 /* matrices: */2764 double L[numgrids];2765 2766 /*input parameters for structural analysis (diagnostic): */2767 double vx,vy;2768 double meltingvalue;2769 double slope[2];2770 double dbdx,dbdy;2771 2772 /* Get node coordinates and dof list: */2773 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2774 GetDofList(&doflist[0],&numberofdofspernode);2775 2776 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */2777 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);2778 2779 /*For icesheets: */2780 /* Start looping on the number of gaussian points: */2781 for (ig=0; ig<num_gauss; ig++){2782 2783 /*Pick up the gaussian point: */2784 gauss_weight=*(gauss_weights+ig);2785 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2786 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2787 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2788 2789 /*Get melting at gaussian point: */2790 inputs->GetParameterValue(&meltingvalue, &gauss_l1l2l3[0],MeltingRateEnum);2791 2792 /*Get velocity at gaussian point: */2793 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);2794 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);2795 2796 /*Get bed slope: */2797 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum);2798 dbdx=slope[0];2799 dbdy=slope[1];2800 2801 /* Get Jacobian determinant: */2802 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);2803 2804 //Get L matrix if viscous basal drag present:2805 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1);2806 2807 2808 /*Build gaussian vector: */2809 for(i=0;i<numgrids;i++){2810 pe_g_gaussian[i]=-Jdet*gauss_weight*(vx*dbdx+vy*dbdy-meltingvalue)*L[i];2811 }2812 2813 /*Add pe_g_gaussian vector to pe_g: */2814 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];2815 2816 }2817 2818 /*Add pe_g to global vector pg: */2819 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);2820 2821 cleanup_and_return:2822 xfree((void**)&first_gauss_area_coord);2823 xfree((void**)&second_gauss_area_coord);2824 xfree((void**)&third_gauss_area_coord);2825 xfree((void**)&gauss_weights);2826 2827 }2828 /*}}}*/2829 /*FUNCTION Tria::CreatePVectorDiagnosticHoriz {{{1*/2830 void Tria::CreatePVectorDiagnosticHoriz( Vec pg){2831 2832 int i,j;2833 2834 /* node data: */2835 const int numgrids=3;2836 const int numdof=2*numgrids;2837 const int NDOF2=2;2838 double xyz_list[numgrids][3];2839 int doflist[numdof];2840 int numberofdofspernode;2841 2842 /* parameters: */2843 double plastic_stress;2844 double slope[NDOF2];2845 double driving_stress_baseline;2846 2847 /* gaussian points: */2848 int num_gauss,ig;2849 double* first_gauss_area_coord = NULL;2850 double* second_gauss_area_coord = NULL;2851 double* third_gauss_area_coord = NULL;2852 double* gauss_weights = NULL;2853 double gauss_weight;2854 double gauss_l1l2l3[3];2855 2856 /* Jacobian: */2857 double Jdet;2858 2859 /*nodal functions: */2860 double l1l2l3[3];2861 2862 /*element vector at the gaussian points: */2863 double pe_g[numdof]={0.0};2864 double pe_g_gaussian[numdof];2865 2866 /*input parameters for structural analysis (diagnostic): */2867 double thickness;2868 2869 /*inputs: */2870 bool onwater;2871 int drag_type;2872 2873 /*retrieve inputs :*/2874 inputs->GetParameterValue(&onwater,ElementOnWaterEnum);2875 inputs->GetParameterValue(&drag_type,DragTypeEnum);2876 2877 /*First, if we are on water, return empty vector: */2878 if(onwater)return;2879 2880 /* Get node coordinates and dof list: */2881 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);2882 GetDofList(&doflist[0],&numberofdofspernode);2883 2884 2885 /* Get gaussian points and weights: */2886 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/2887 2888 /* Start looping on the number of gaussian points: */2889 for (ig=0; ig<num_gauss; ig++){2890 /*Pick up the gaussian point: */2891 gauss_weight=*(gauss_weights+ig);2892 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);2893 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);2894 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);2895 2896 /*Compute thickness at gaussian point: */2897 inputs->GetParameterValue(&thickness, &gauss_l1l2l3[0],ThicknessEnum);2898 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);2899 2900 /*In case we have plastic basal drag, compute plastic stress at gaussian point from k1, k2 and k3 fields in the2901 * element itself: */2902 if(drag_type==1){2903 inputs->GetParameterValue(&plastic_stress, &gauss_l1l2l3[0],DragCoefficientEnum);2904 }2905 2906 /* Get Jacobian determinant: */2907 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);2908 2909 /*Get nodal functions: */2910 GetNodalFunctions(l1l2l3, gauss_l1l2l3);2911 2912 /*Compute driving stress: */2913 driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG()*thickness;2914 2915 /*Build pe_g_gaussian vector: */2916 if(drag_type==1){2917 for (i=0;i<numgrids;i++){2918 for (j=0;j<NDOF2;j++){2919 pe_g_gaussian[i*NDOF2+j]=(-driving_stress_baseline*slope[j]-plastic_stress)*Jdet*gauss_weight*l1l2l3[i];2920 }2921 }2922 }2923 else {2924 for (i=0;i<numgrids;i++){2925 for (j=0;j<NDOF2;j++){2926 pe_g_gaussian[i*NDOF2+j]=-driving_stress_baseline*slope[j]*Jdet*gauss_weight*l1l2l3[i];2927 }2928 }2929 }2930 2931 /*Add pe_g_gaussian vector to pe_g: */2932 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];2933 2934 } //for (ig=0; ig<num_gauss; ig++)2935 2936 /*Add pe_g to global vector pg: */2937 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);2938 2939 cleanup_and_return:2940 xfree((void**)&first_gauss_area_coord);2941 xfree((void**)&second_gauss_area_coord);2942 xfree((void**)&third_gauss_area_coord);2943 xfree((void**)&gauss_weights);2944 2945 }2946 /*}}}*/2947 /*FUNCTION Tria::CreatePVectorDiagnosticHutter{{{1*/2948 void Tria::CreatePVectorDiagnosticHutter(Vec pg){2949 2950 /*Collapsed formulation: */2951 Sing* sing=NULL;2952 int i;2953 2954 /*flags: */2955 bool onwater;2956 2957 /*recover some inputs: */2958 inputs->GetParameterValue(&onwater,ElementOnWaterEnum);2959 2960 /*If on water, skip: */2961 if(onwater)return;2962 2963 /*Spawn 3 sing elements: */2964 for(i=0;i<3;i++){2965 sing=(Sing*)SpawnSing(i);2966 sing->CreatePVector(pg);2967 }2968 2969 /*clean up*/2970 delete sing;2971 2972 }2973 /*}}}*/2974 /*FUNCTION Tria::CreatePVectorPrognostic {{{1*/2975 void Tria::CreatePVectorPrognostic(Vec pg){2976 2977 2978 /* local declarations */2979 int i,j;2980 2981 /* node data: */2982 const int numgrids=3;2983 const int NDOF1=1;2984 const int numdof=NDOF1*numgrids;2985 double xyz_list[numgrids][3];2986 int doflist[numdof];2987 int numberofdofspernode;2988 2989 /* gaussian points: */2990 int num_gauss,ig;2991 double* first_gauss_area_coord = NULL;2992 double* second_gauss_area_coord = NULL;2993 double* third_gauss_area_coord = NULL;2994 double* gauss_weights = NULL;2995 double gauss_weight;2996 double gauss_l1l2l3[3];2997 2998 /* matrix */2999 double pe_g[numgrids]={0.0};3000 double L[numgrids];3001 double Jdettria;3002 3003 /*input parameters for structural analysis (diagnostic): */3004 double accumulation_g;3005 double melting_g;3006 double thickness_g;3007 3008 /*parameters: */3009 double dt;3010 3011 /*retrieve some parameters: */3012 this->parameters->FindParam(&dt,DtEnum);3013 3014 /* Get node coordinates and dof list: */3015 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3016 GetDofList(&doflist[0],&numberofdofspernode);3017 3018 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */3019 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);3020 3021 /* Start looping on the number of gaussian points: */3022 for (ig=0; ig<num_gauss; ig++){3023 /*Pick up the gaussian point: */3024 gauss_weight=*(gauss_weights+ig);3025 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);3026 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);3027 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);3028 3029 /* Get Jacobian determinant: */3030 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);3031 3032 /*Get L matrix: */3033 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);3034 3035 /* Get accumulation, melting and thickness at gauss point */3036 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);3037 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);3038 inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum);3039 3040 /* Add value into pe_g: */3041 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i];3042 3043 } // for (ig=0; ig<num_gauss; ig++)3044 3045 /*Add pe_g to global matrix Kgg: */3046 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);3047 3048 cleanup_and_return:3049 xfree((void**)&first_gauss_area_coord);3050 xfree((void**)&second_gauss_area_coord);3051 xfree((void**)&third_gauss_area_coord);3052 xfree((void**)&gauss_weights);3053 3054 }3055 /*}}}*/3056 /*FUNCTION Tria::CreatePVectorPrognostic2 {{{1*/3057 void Tria::CreatePVectorPrognostic2(Vec pg){3058 3059 /* local declarations */3060 int i,j;3061 3062 /* node data: */3063 const int numgrids=3;3064 const int NDOF1=1;3065 const int numdof=NDOF1*numgrids;3066 double xyz_list[numgrids][3];3067 int doflist[numdof];3068 int numberofdofspernode;3069 3070 /* gaussian points: */3071 int num_gauss,ig;3072 double* first_gauss_area_coord = NULL;3073 double* second_gauss_area_coord = NULL;3074 double* third_gauss_area_coord = NULL;3075 double* gauss_weights = NULL;3076 double gauss_weight;3077 double gauss_l1l2l3[3];3078 3079 /* matrix */3080 double pe_g[numgrids]={0.0};3081 double L[numgrids];3082 double Jdettria;3083 3084 /*input parameters for structural analysis (diagnostic): */3085 double accumulation_g;3086 double melting_g;3087 double thickness_g;3088 double dt;3089 3090 /*retrieve some parameters: */3091 this->parameters->FindParam(&dt,DtEnum);3092 3093 /* Get node coordinates and dof list: */3094 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3095 GetDofList(&doflist[0],&numberofdofspernode);3096 3097 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */3098 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);3099 3100 /* Start looping on the number of gaussian points: */3101 for (ig=0; ig<num_gauss; ig++){3102 /*Pick up the gaussian point: */3103 gauss_weight=*(gauss_weights+ig);3104 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);3105 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);3106 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);3107 3108 /* Get Jacobian determinant: */3109 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3);3110 3111 /*Get L matrix: */3112 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode);3113 3114 /* Get accumulation, melting and thickness at gauss point */3115 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum);3116 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum);3117 inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum);3118 3119 /* Add value into pe_g: */3120 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i];3121 3122 } // for (ig=0; ig<num_gauss; ig++)3123 3124 /*Add pe_g to global matrix Kgg: */3125 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);3126 3127 cleanup_and_return:3128 xfree((void**)&first_gauss_area_coord);3129 xfree((void**)&second_gauss_area_coord);3130 xfree((void**)&third_gauss_area_coord);3131 xfree((void**)&gauss_weights);3132 3133 }3134 /*}}}*/3135 /*FUNCTION Tria::CreatePVectorSlopeCompute {{{1*/3136 3137 void Tria::CreatePVectorSlopeCompute( Vec pg){3138 3139 int i,j;3140 3141 /* node data: */3142 const int numgrids=3;3143 const int NDOF1=1;3144 const int numdof=NDOF1*numgrids;3145 double xyz_list[numgrids][3];3146 int doflist[numdof];3147 int numberofdofspernode;3148 3149 /* gaussian points: */3150 int num_gauss,ig;3151 double* first_gauss_area_coord = NULL;3152 double* second_gauss_area_coord = NULL;3153 double* third_gauss_area_coord = NULL;3154 double* gauss_weights = NULL;3155 double gauss_weight;3156 double gauss_l1l2l3[3];3157 3158 /* Jacobian: */3159 double Jdet;3160 3161 /*nodal functions: */3162 double l1l2l3[3];3163 3164 /*element vector at the gaussian points: */3165 double pe_g[numdof]={0.0};3166 double pe_g_gaussian[numdof];3167 double slope[2];3168 int sub_analysis_type;3169 3170 /*retrive parameters: */3171 parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);3172 3173 /* Get node coordinates and dof list: */3174 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3175 GetDofList(&doflist[0],&numberofdofspernode);3176 3177 3178 /* Get gaussian points and weights: */3179 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/3180 3181 3182 /* Start looping on the number of gaussian points: */3183 for (ig=0; ig<num_gauss; ig++){3184 /*Pick up the gaussian point: */3185 gauss_weight=*(gauss_weights+ig);3186 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);3187 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);3188 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);3189 3190 if ( (sub_analysis_type==SurfaceSlopeXAnalysisEnum) || (sub_analysis_type==SurfaceSlopeYAnalysisEnum)){3191 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum);3192 }3193 if ( (sub_analysis_type==BedSlopeXAnalysisEnum) || (sub_analysis_type==BedSlopeYAnalysisEnum)){3194 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum);3195 }3196 3197 /* Get Jacobian determinant: */3198 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);3199 3200 /*Get nodal functions: */3201 GetNodalFunctions(l1l2l3, gauss_l1l2l3);3202 3203 /*Build pe_g_gaussian vector: */3204 if ( (sub_analysis_type==SurfaceSlopeXAnalysisEnum) || (sub_analysis_type==BedSlopeXAnalysisEnum)){3205 for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[0]*l1l2l3[i];3206 }3207 if ( (sub_analysis_type==SurfaceSlopeYAnalysisEnum) || (sub_analysis_type==BedSlopeYAnalysisEnum)){3208 for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[1]*l1l2l3[i];3209 }3210 3211 /*Add pe_g_gaussian vector to pe_g: */3212 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];3213 3214 } //for (ig=0; ig<num_gauss; ig++)3215 3216 /*Add pe_g to global vector pg: */3217 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);3218 3219 cleanup_and_return:3220 xfree((void**)&first_gauss_area_coord);3221 xfree((void**)&second_gauss_area_coord);3222 xfree((void**)&third_gauss_area_coord);3223 xfree((void**)&gauss_weights);3224 3225 }3226 /*}}}*/3227 /*FUNCTION Tria::CreatePVectorThermalShelf {{{1*/3228 void Tria::CreatePVectorThermalShelf( Vec pg){3229 3230 int i,found;3231 3232 const int numgrids=3;3233 const int NDOF1=1;3234 const int numdof=numgrids*NDOF1;3235 int doflist[numdof];3236 int numberofdofspernode;3237 double xyz_list[numgrids][3];3238 3239 double mixed_layer_capacity;3240 double thermal_exchange_velocity;3241 double rho_water;3242 double rho_ice;3243 double heatcapacity;3244 double beta;3245 double meltingpoint;3246 3247 /*inputs: */3248 double dt;3249 double pressure;3250 3251 /* gaussian points: */3252 int num_area_gauss,ig;3253 double* gauss_weights = NULL;3254 double* first_gauss_area_coord = NULL;3255 double* second_gauss_area_coord = NULL;3256 double* third_gauss_area_coord = NULL;3257 double gauss_weight;3258 double gauss_coord[3];3259 int dofs1[1]={0};3260 3261 /*matrices: */3262 double Jdet;3263 double P_terms[numdof]={0.0};3264 double l1l2l3[numgrids];3265 3266 double t_pmp;3267 double scalar_ocean;3268 3269 /* Get node coordinates and dof list: */3270 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3271 GetDofList(&doflist[0],&numberofdofspernode);3272 3273 //recover material parameters3274 mixed_layer_capacity=matpar->GetMixedLayerCapacity();3275 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();3276 rho_water=matpar->GetRhoWater();3277 rho_ice=matpar->GetRhoIce();3278 heatcapacity=matpar->GetHeatCapacity();3279 beta=matpar->GetBeta();3280 meltingpoint=matpar->GetMeltingPoint();3281 3282 /*retrieve some solution parameters: */3283 this->parameters->FindParam(&dt,DtEnum);3284 3285 /* Ice/ocean heat exchange flux on ice shelf base */3286 3287 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);3288 3289 /* Start looping on the number of gauss 2d (nodes on the bedrock) */3290 for (ig=0; ig<num_area_gauss; ig++){3291 gauss_weight=*(gauss_weights+ig);3292 gauss_coord[0]=*(first_gauss_area_coord+ig);3293 gauss_coord[1]=*(second_gauss_area_coord+ig);3294 gauss_coord[2]=*(third_gauss_area_coord+ig);3295 3296 //Get the Jacobian determinant3297 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord);3298 3299 /*Get nodal functions values: */3300 GetNodalFunctions(&l1l2l3[0], gauss_coord);3301 3302 /*Get geothermal flux and basal friction */3303 inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum);3304 t_pmp=meltingpoint-beta*pressure;3305 3306 /*Calculate scalar parameter*/3307 scalar_ocean=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(t_pmp)/(heatcapacity*rho_ice);3308 if(dt){3309 scalar_ocean=dt*scalar_ocean;3310 }3311 3312 for(i=0;i<3;i++){3313 P_terms[i]+=scalar_ocean*l1l2l3[i];3314 }3315 }3316 3317 /*Add pe_g to global vector pg: */3318 VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);3319 3320 cleanup_and_return:3321 xfree((void**)&first_gauss_area_coord);3322 xfree((void**)&second_gauss_area_coord);3323 xfree((void**)&third_gauss_area_coord);3324 xfree((void**)&gauss_weights);3325 3326 }3327 /*}}}*/3328 /*FUNCTION Tria::CreatePVectorThermalSheet {{{1*/3329 void Tria::CreatePVectorThermalSheet( Vec pg){3330 3331 int i,found;3332 3333 const int numgrids=3;3334 const int NDOF1=1;3335 const int numdof=numgrids*NDOF1;3336 int doflist[numdof];3337 int numberofdofspernode;3338 double xyz_list[numgrids][3];3339 3340 double rho_ice;3341 double heatcapacity;3342 3343 /*inputs: */3344 double dt;3345 double pressure_list[3];3346 double pressure;3347 int drag_type;3348 double basalfriction;3349 Friction* friction=NULL;3350 double alpha2,vx,vy;3351 double geothermalflux_value;3352 3353 /* gaussian points: */3354 int num_area_gauss,ig;3355 double* gauss_weights = NULL;3356 double* first_gauss_area_coord = NULL;3357 double* second_gauss_area_coord = NULL;3358 double* third_gauss_area_coord = NULL;3359 double gauss_weight;3360 double gauss_coord[3];3361 3362 /*matrices: */3363 double Jdet;3364 double P_terms[numdof]={0.0};3365 double l1l2l3[numgrids];3366 double scalar;3367 3368 int analysis_type;3369 3370 /*retrive parameters: */3371 parameters->FindParam(&analysis_type,AnalysisTypeEnum);3372 3373 3374 /* Get node coordinates and dof list: */3375 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3376 GetDofList(&doflist[0],&numberofdofspernode);3377 3378 //recover material parameters3379 rho_ice=matpar->GetRhoIce();3380 heatcapacity=matpar->GetHeatCapacity();3381 3382 /*retrieve some parameters: */3383 this->parameters->FindParam(&dt,DtEnum);3384 3385 /*Build frictoin element, needed later: */3386 inputs->GetParameterValue(&drag_type,DragTypeEnum);3387 if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!");3388 friction=new Friction("3d",inputs,matpar,analysis_type);3389 3390 /* Ice/ocean heat exchange flux on ice shelf base */3391 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);3392 3393 /* Start looping on the number of gauss 2d (nodes on the bedrock) */3394 for (ig=0; ig<num_area_gauss; ig++){3395 gauss_weight=*(gauss_weights+ig);3396 gauss_coord[0]=*(first_gauss_area_coord+ig);3397 gauss_coord[1]=*(second_gauss_area_coord+ig);3398 gauss_coord[2]=*(third_gauss_area_coord+ig);3399 3400 //Get the Jacobian determinant3401 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);3402 3403 /*Get nodal functions values: */3404 GetNodalFunctions(&l1l2l3[0], gauss_coord);3405 3406 /*Get geothermal flux and basal friction */3407 inputs->GetParameterValue(&geothermalflux_value, &gauss_coord[0],GeothermalFluxEnum);3408 3409 friction->GetAlpha2(&alpha2,&gauss_coord[0],VxEnum,VyEnum,VzEnum);3410 inputs->GetParameterValue(&vx, &gauss_coord[0],VxEnum);3411 inputs->GetParameterValue(&vy, &gauss_coord[0],VyEnum);3412 basalfriction= alpha2*(pow(vx,(double)2.0)+pow(vy,(double)2.0));3413 3414 /*Calculate scalar parameter*/3415 scalar=gauss_weight*Jdet*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice);3416 if(dt){3417 scalar=dt*scalar;3418 }3419 3420 for(i=0;i<3;i++){3421 P_terms[i]+=scalar*l1l2l3[i];3422 }3423 }3424 3425 /*Add pe_g to global vector pg: */3426 VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);3427 3428 cleanup_and_return:3429 xfree((void**)&first_gauss_area_coord);3430 xfree((void**)&second_gauss_area_coord);3431 xfree((void**)&third_gauss_area_coord);3432 xfree((void**)&gauss_weights);3433 delete friction;3434 669 3435 670 } … … 3674 909 } 3675 910 /*}}}*/ 3676 /*FUNCTION Tria::GetArea {{{1*/3677 double Tria::GetArea(void){3678 3679 double area=0;3680 const int numgrids=3;3681 double xyz_list[numgrids][3];3682 double x1,y1,x2,y2,x3,y3;3683 3684 /*Get xyz list: */3685 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3686 x1=xyz_list[0][0]; y1=xyz_list[0][1];3687 x2=xyz_list[1][0]; y2=xyz_list[1][1];3688 x3=xyz_list[2][0]; y3=xyz_list[2][1];3689 3690 return x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1;3691 }3692 /*}}}*/3693 /*FUNCTION Tria::GetAreaCoordinate {{{1*/3694 double Tria::GetAreaCoordinate(double x, double y, int which_one){3695 3696 double area=0;3697 const int numgrids=3;3698 double xyz_list[numgrids][3];3699 double x1,y1,x2,y2,x3,y3;3700 3701 /*Get area: */3702 area=this->GetArea();3703 3704 /*Get xyz list: */3705 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);3706 x1=xyz_list[0][0]; y1=xyz_list[0][1];3707 x2=xyz_list[1][0]; y2=xyz_list[1][1];3708 x3=xyz_list[2][0]; y3=xyz_list[2][1];3709 3710 if(which_one==1){3711 /*Get first area coordinate = det(x-x3 x2-x3 ; y-y3 y2-y3)/area*/3712 return ((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area;3713 }3714 else if(which_one==2){3715 /*Get second area coordinate = det(x1-x3 x-x3 ; y1-y3 y-y3)/area*/3716 return ((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area;3717 }3718 else if(which_one==3){3719 /*Get third area coordinate 1-area1-area2: */3720 return 1-((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area -((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area;3721 }3722 else ISSMERROR("%s%i%s\n"," error message: area coordinate ",which_one," done not exist!");3723 }3724 /*}}}*/3725 /*FUNCTION Tria::GetB {{{1*/3726 3727 void Tria::GetB(double* B, double* xyz_list, double* gauss_l1l2l3){3728 3729 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.3730 * For grid i, Bi can be expressed in the actual coordinate system3731 * by:3732 * Bi=[ dh/dx 0 ]3733 * [ 0 dh/dy ]3734 * [ 1/2*dh/dy 1/2*dh/dx ]3735 * where h is the interpolation function for grid i.3736 *3737 * We assume B has been allocated already, of size: 3x(NDOF2*numgrids)3738 */3739 3740 int i;3741 const int NDOF2=2;3742 const int numgrids=3;3743 3744 double dh1dh3[NDOF2][numgrids];3745 3746 3747 /*Get dh1dh2dh3 in actual coordinate system: */3748 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3);3749 3750 /*Build B: */3751 for (i=0;i<numgrids;i++){3752 *(B+NDOF2*numgrids*0+NDOF2*i)=dh1dh3[0][i]; //B[0][NDOF2*i]=dh1dh3[0][i];3753 *(B+NDOF2*numgrids*0+NDOF2*i+1)=0;3754 *(B+NDOF2*numgrids*1+NDOF2*i)=0;3755 *(B+NDOF2*numgrids*1+NDOF2*i+1)=dh1dh3[1][i];3756 *(B+NDOF2*numgrids*2+NDOF2*i)=(float).5*dh1dh3[1][i];3757 *(B+NDOF2*numgrids*2+NDOF2*i+1)=(float).5*dh1dh3[0][i];3758 }3759 }3760 /*}}}*/3761 /*FUNCTION Tria::GetB_prog {{{1*/3762 3763 void Tria::GetB_prog(double* B_prog, double* xyz_list, double* gauss_l1l2l3){3764 3765 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.3766 * For grid i, Bi can be expressed in the actual coordinate system3767 * by:3768 * Bi=[ h ]3769 * [ h ]3770 * where h is the interpolation function for grid i.3771 *3772 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numgrids)3773 */3774 3775 int i;3776 const int NDOF1=1;3777 const int numgrids=3;3778 3779 double l1l2l3[numgrids];3780 3781 3782 /*Get dh1dh2dh3 in actual coordinate system: */3783 GetNodalFunctions(&l1l2l3[0],gauss_l1l2l3);3784 3785 /*Build B_prog: */3786 for (i=0;i<numgrids;i++){3787 *(B_prog+NDOF1*numgrids*0+NDOF1*i)=l1l2l3[i];3788 *(B_prog+NDOF1*numgrids*1+NDOF1*i)=l1l2l3[i];3789 }3790 }3791 /*}}}*/3792 911 /*FUNCTION Tria::GetBedList {{{1*/ 3793 912 void Tria::GetBedList(double* bedlist){ … … 3800 919 } 3801 920 /*}}}*/ 3802 /*FUNCTION Tria::GetBPrime {{{1*/3803 3804 void Tria::GetBPrime(double* Bprime, double* xyz_list, double* gauss_l1l2l3){3805 3806 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.3807 * For grid i, Bi' can be expressed in the actual coordinate system3808 * by:3809 * Bi_prime=[ 2*dh/dx dh/dy ]3810 * [ dh/dx 2*dh/dy]3811 * [dh/dy dh/dx]3812 * where h is the interpolation function for grid i.3813 *3814 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids)3815 */3816 3817 int i;3818 const int NDOF2=2;3819 const int numgrids=3;3820 3821 /*Same thing in the actual coordinate system: */3822 double dh1dh3[NDOF2][numgrids];3823 3824 3825 /*Get dh1dh2dh3 in actual coordinates system : */3826 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3);3827 3828 /*Build B': */3829 for (i=0;i<numgrids;i++){3830 *(Bprime+NDOF2*numgrids*0+NDOF2*i)=2*dh1dh3[0][i];3831 *(Bprime+NDOF2*numgrids*0+NDOF2*i+1)=dh1dh3[1][i];3832 *(Bprime+NDOF2*numgrids*1+NDOF2*i)=dh1dh3[0][i];3833 *(Bprime+NDOF2*numgrids*1+NDOF2*i+1)=2*dh1dh3[1][i];3834 *(Bprime+NDOF2*numgrids*2+NDOF2*i)=dh1dh3[1][i];3835 *(Bprime+NDOF2*numgrids*2+NDOF2*i+1)=dh1dh3[0][i];3836 }3837 }3838 /*}}}*/3839 /*FUNCTION Tria::GetBPrime_prog {{{1*/3840 3841 void Tria::GetBPrime_prog(double* Bprime_prog, double* xyz_list, double* gauss_l1l2l3){3842 3843 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.3844 * For grid i, Bi' can be expressed in the actual coordinate system3845 * by:3846 * Bi_prime=[ dh/dx ]3847 * [ dh/dy ]3848 * where h is the interpolation function for grid i.3849 *3850 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids)3851 */3852 3853 int i;3854 const int NDOF1=1;3855 const int NDOF2=2;3856 const int numgrids=3;3857 3858 /*Same thing in the actual coordinate system: */3859 double dh1dh3[NDOF2][numgrids];3860 3861 /*Get dh1dh2dh3 in actual coordinates system : */3862 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3);3863 3864 /*Build B': */3865 for (i=0;i<numgrids;i++){3866 *(Bprime_prog+NDOF1*numgrids*0+NDOF1*i)=dh1dh3[0][i];3867 *(Bprime_prog+NDOF1*numgrids*1+NDOF1*i)=dh1dh3[1][i];3868 }3869 }3870 /*}}}*/3871 /*FUNCTION Tria::GetDofList {{{1*/3872 void Tria::GetDofList(int* doflist,int* pnumberofdofspernode){3873 3874 int i,j;3875 int doflist_per_node[MAXDOFSPERNODE];3876 int numberofdofspernode;3877 3878 /*Some checks for debugging*/3879 ISSMASSERT(doflist);3880 ISSMASSERT(pnumberofdofspernode);3881 ISSMASSERT(nodes);3882 3883 /*Build doflist from nodes*/3884 for(i=0;i<3;i++){3885 nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode);3886 for(j=0;j<numberofdofspernode;j++){3887 doflist[i*numberofdofspernode+j]=doflist_per_node[j];3888 }3889 }3890 3891 /*Assign output pointers:*/3892 *pnumberofdofspernode=numberofdofspernode;3893 3894 }3895 /*}}}*/3896 /*FUNCTION Tria::GetDofList1 {{{1*/3897 void Tria::GetDofList1(int* doflist){3898 3899 int i;3900 for(i=0;i<3;i++){3901 doflist[i]=nodes[i]->GetDofList1();3902 }3903 3904 }3905 /*}}}*/3906 /*FUNCTION Tria::GetJacobian {{{1*/3907 void Tria::GetJacobian(double* J, double* xyz_list,double* gauss_l1l2l3){3908 3909 /*The Jacobian is constant over the element, discard the gaussian points.3910 * J is assumed to have been allocated of size NDOF2xNDOF2.*/3911 3912 const int NDOF2=2;3913 const int numgrids=3;3914 double x1,y1,x2,y2,x3,y3;3915 3916 x1=*(xyz_list+numgrids*0+0);3917 y1=*(xyz_list+numgrids*0+1);3918 x2=*(xyz_list+numgrids*1+0);3919 y2=*(xyz_list+numgrids*1+1);3920 x3=*(xyz_list+numgrids*2+0);3921 y3=*(xyz_list+numgrids*2+1);3922 3923 3924 *(J+NDOF2*0+0)=0.5*(x2-x1);3925 *(J+NDOF2*1+0)=SQRT3/6.0*(2*x3-x1-x2);3926 *(J+NDOF2*0+1)=0.5*(y2-y1);3927 *(J+NDOF2*1+1)=SQRT3/6.0*(2*y3-y1-y2);3928 }3929 /*}}}*/3930 /*FUNCTION Tria::GetJacobianDeterminant2d {{{1*/3931 void Tria::GetJacobianDeterminant2d(double* Jdet, double* xyz_list,double* gauss_l1l2l3){3932 3933 /*The Jacobian determinant is constant over the element, discard the gaussian points.3934 * J is assumed to have been allocated of size NDOF2xNDOF2.*/3935 3936 double x1,x2,x3,y1,y2,y3;3937 3938 x1=*(xyz_list+3*0+0);3939 y1=*(xyz_list+3*0+1);3940 x2=*(xyz_list+3*1+0);3941 y2=*(xyz_list+3*1+1);3942 x3=*(xyz_list+3*2+0);3943 y3=*(xyz_list+3*2+1);3944 3945 3946 *Jdet=SQRT3/6.0*((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1));3947 3948 3949 if(Jdet<0){3950 ISSMERROR("negative jacobian determinant!");3951 }3952 3953 }3954 /*}}}*/3955 /*FUNCTION Tria::GetJacobianDeterminant3d {{{1*/3956 void Tria::GetJacobianDeterminant3d(double* Jdet, double* xyz_list,double* gauss_l1l2l3){3957 3958 /*The Jacobian determinant is constant over the element, discard the gaussian points.3959 * J is assumed to have been allocated of size NDOF2xNDOF2.*/3960 3961 double x1,x2,x3,y1,y2,y3,z1,z2,z3;3962 3963 x1=*(xyz_list+3*0+0);3964 y1=*(xyz_list+3*0+1);3965 z1=*(xyz_list+3*0+2);3966 x2=*(xyz_list+3*1+0);3967 y2=*(xyz_list+3*1+1);3968 z2=*(xyz_list+3*1+2);3969 x3=*(xyz_list+3*2+0);3970 y3=*(xyz_list+3*2+1);3971 z3=*(xyz_list+3*2+2);3972 3973 3974 *Jdet=SQRT3/6.0*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2.0)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2.0)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2.0),0.5);3975 3976 if(Jdet<0){3977 ISSMERROR("negative jacobian determinant!");3978 }3979 3980 }3981 /*}}}*/3982 /*FUNCTION Tria::GetJacobianInvert {{{1*/3983 void Tria::GetJacobianInvert(double* Jinv, double* xyz_list,double* gauss_l1l2l3){3984 3985 double Jdet;3986 const int NDOF2=2;3987 const int numgrids=3;3988 3989 /*Call Jacobian routine to get the jacobian:*/3990 GetJacobian(Jinv, xyz_list, gauss_l1l2l3);3991 3992 /*Invert Jacobian matrix: */3993 MatrixInverse(Jinv,NDOF2,NDOF2,NULL,0,&Jdet);3994 3995 }3996 /*}}}*/3997 /*FUNCTION Tria::GetL {{{1*/3998 3999 void Tria::GetL(double* L, double* xyz_list, double* gauss_l1l2l3,int numdof){4000 4001 /*Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof.4002 * For grid i, Li can be expressed in the actual coordinate system4003 * by:4004 * numdof=1:4005 * Li=h;4006 * numdof=2:4007 * Li=[ h 0 ]4008 * [ 0 h ]4009 * where h is the interpolation function for grid i.4010 *4011 * We assume L has been allocated already, of size: numgrids (numdof=1), or numdofx(numdof*numgrids) (numdof=2)4012 */4013 4014 int i;4015 const int NDOF2=2;4016 const int numgrids=3;4017 4018 double l1l2l3[3];4019 4020 4021 /*Get l1l2l3 in actual coordinate system: */4022 GetNodalFunctions(l1l2l3, gauss_l1l2l3);4023 4024 #ifdef _DELUG_4025 for (i=0;i<3;i++){4026 printf("Node %i h=%lf \n",i,l1l2l3[i]);4027 }4028 #endif4029 4030 /*Build L: */4031 if(numdof==1){4032 for (i=0;i<numgrids;i++){4033 L[i]=l1l2l3[i];4034 }4035 }4036 else{4037 for (i=0;i<numgrids;i++){4038 *(L+numdof*numgrids*0+numdof*i)=l1l2l3[i]; //L[0][NDOF2*i]=dh1dh3[0][i];4039 *(L+numdof*numgrids*0+numdof*i+1)=0;4040 *(L+numdof*numgrids*1+numdof*i)=0;4041 *(L+numdof*numgrids*1+numdof*i+1)=l1l2l3[i];4042 }4043 }4044 }4045 /*}}}*/4046 921 /*FUNCTION Tria::GetMatPar {{{1*/ 4047 922 void* Tria::GetMatPar(){ 4048 923 4049 924 return matpar; 4050 }4051 /*}}}*/4052 /*FUNCTION Tria::GetNodalFunctions {{{1*/4053 void Tria::GetNodalFunctions(double* l1l2l3, double* gauss_l1l2l3){4054 4055 /*This routine returns the values of the nodal functions at the gaussian point.*/4056 4057 /*First nodal function: */4058 l1l2l3[0]=gauss_l1l2l3[0];4059 4060 /*Second nodal function: */4061 l1l2l3[1]=gauss_l1l2l3[1];4062 4063 /*Third nodal function: */4064 l1l2l3[2]=gauss_l1l2l3[2];4065 4066 }4067 /*}}}*/4068 /*FUNCTION Tria::GetNodalFunctionsDerivatives {{{1*/4069 void Tria::GetNodalFunctionsDerivatives(double* dh1dh3,double* xyz_list, double* gauss_l1l2l3){4070 4071 /*This routine returns the values of the nodal functions derivatives (with respect to the4072 * actual coordinate system: */4073 4074 int i;4075 const int NDOF2=2;4076 const int numgrids=3;4077 4078 double dh1dh3_ref[NDOF2][numgrids];4079 double Jinv[NDOF2][NDOF2];4080 4081 4082 /*Get derivative values with respect to parametric coordinate system: */4083 GetNodalFunctionsDerivativesReference(&dh1dh3_ref[0][0], gauss_l1l2l3);4084 4085 /*Get Jacobian invert: */4086 GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_l1l2l3);4087 4088 /*Build dh1dh3:4089 *4090 * [dhi/dx]= Jinv*[dhi/dr]4091 * [dhi/dy] [dhi/ds]4092 */4093 4094 for (i=0;i<numgrids;i++){4095 *(dh1dh3+numgrids*0+i)=Jinv[0][0]*dh1dh3_ref[0][i]+Jinv[0][1]*dh1dh3_ref[1][i];4096 *(dh1dh3+numgrids*1+i)=Jinv[1][0]*dh1dh3_ref[0][i]+Jinv[1][1]*dh1dh3_ref[1][i];4097 }4098 4099 }4100 /*}}}*/4101 /*FUNCTION Tria::GetNodalFunctionsDerivativesReference {{{1*/4102 void Tria::GetNodalFunctionsDerivativesReference(double* dl1dl3,double* gauss_l1l2l3){4103 4104 /*This routine returns the values of the nodal functions derivatives (with respect to the4105 * natural coordinate system) at the gaussian point. */4106 4107 const int NDOF2=2;4108 const int numgrids=3;4109 4110 /*First nodal function: */4111 *(dl1dl3+numgrids*0+0)=-0.5;4112 *(dl1dl3+numgrids*1+0)=-1.0/(2.0*SQRT3);4113 4114 /*Second nodal function: */4115 *(dl1dl3+numgrids*0+1)=0.5;4116 *(dl1dl3+numgrids*1+1)=-1.0/(2.0*SQRT3);4117 4118 /*Third nodal function: */4119 *(dl1dl3+numgrids*0+2)=0;4120 *(dl1dl3+numgrids*1+2)=1.0/SQRT3;4121 4122 925 } 4123 926 /*}}}*/ … … 4144 947 } 4145 948 /*}}}*/ 4146 /*FUNCTION Tria::GetParameterDerivativeValue {{{1*/4147 void Tria::GetParameterDerivativeValue(double* p, double* plist,double* xyz_list, double* gauss_l1l2l3){4148 4149 const int NDOF2=2;4150 const int numgrids=3;4151 /*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter derivative value at gaussian4152 * point specified by gauss_l1l2l3:4153 * dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx4154 * dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx4155 *4156 * p is a vector of size 2x1 already allocated.4157 */4158 4159 double dh1dh3[NDOF2][numgrids]; //nodal derivative functions in actual coordinate system.4160 4161 /*Get dh1dh2dh3 in actual coordinate system: */4162 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3);4163 4164 *(p+0)=plist[0]*dh1dh3[0][0]+plist[1]*dh1dh3[0][1]+plist[2]*dh1dh3[0][2];4165 *(p+1)=plist[0]*dh1dh3[1][0]+plist[1]*dh1dh3[1][1]+plist[2]*dh1dh3[1][2];4166 4167 }4168 /*}}}*/4169 /*FUNCTION Tria::GetParameterValue {{{1*/4170 void Tria::GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3){4171 4172 /*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter value at gaussian4173 * point specifie by gauss_l1l2l3: */4174 4175 /*nodal functions: */4176 double l1l2l3[3];4177 4178 /*output: */4179 double p;4180 4181 GetNodalFunctions(l1l2l3, gauss_l1l2l3);4182 4183 p=l1l2l3[0]*plist[0]+l1l2l3[1]*plist[1]+l1l2l3[2]*plist[2];4184 4185 /*Assign output pointers:*/4186 *pp=p;4187 }4188 /*}}}*/4189 949 /*FUNCTION Tria::GetShelf {{{1*/ 4190 950 bool Tria::GetShelf(){ … … 4198 958 } 4199 959 /*}}}*/ 960 /*FUNCTION Tria::GetSolutionFromInputs(Vec solution){{{1*/ 961 void Tria::GetSolutionFromInputs(Vec solution){ 962 963 int analysis_type; 964 965 /*retrive parameters: */ 966 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 967 968 /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */ 969 if (analysis_type==DiagnosticHorizAnalysisEnum) 970 GetSolutionFromInputsDiagnosticHoriz(solution); 971 else 972 ISSMERROR("%s%i%s\n","analysis: ",analysis_type," not supported yet"); 973 974 } 975 /*}}}*/ 4200 976 /*FUNCTION Tria::GetThicknessList {{{1*/ 4201 977 void Tria::GetThicknessList(double* thickness_list){ … … 4207 983 } 4208 984 /*}}}*/ 985 /*FUNCTION Tria::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/ 986 void Tria::GetVectorFromInputs(Vec vector,int NameEnum){ 987 988 int i; 989 const int numvertices=3; 990 int doflist1[numvertices]; 991 992 /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */ 993 for(i=0;i<this->inputs->Size();i++){ 994 Input* input=(Input*)this->inputs->GetObjectByOffset(i); 995 if(input->EnumType()==NameEnum){ 996 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */ 997 this->GetDofList1(&doflist1[0]); 998 input->GetVectorFromInputs(vector,&doflist1[0]); 999 break; 1000 } 1001 } 1002 } 1003 /*}}}*/ 4209 1004 /*FUNCTION Tria::Gradj {{{1*/ 4210 1005 void Tria::Gradj(Vec gradient,int control_type){ … … 4226 1021 } 4227 1022 else ISSMERROR("%s%i","control type not supported yet: ",control_type); 4228 }4229 /*}}}*/4230 /*FUNCTION Tria::GradjDrag {{{1*/4231 void Tria::GradjDrag(Vec gradient){4232 4233 4234 int i;4235 4236 /* node data: */4237 const int numgrids=3;4238 const int NDOF2=2;4239 const int numdof=NDOF2*numgrids;4240 double xyz_list[numgrids][3];4241 int doflist1[numgrids];4242 double dh1dh3[NDOF2][numgrids];4243 4244 /* grid data: */4245 double adjx_list[numgrids];4246 double adjy_list[numgrids];4247 4248 /* gaussian points: */4249 int num_gauss,ig;4250 double* first_gauss_area_coord = NULL;4251 double* second_gauss_area_coord = NULL;4252 double* third_gauss_area_coord = NULL;4253 double* gauss_weights = NULL;4254 double gauss_weight;4255 double gauss_l1l2l3[3];4256 4257 /* parameters: */4258 double dk[NDOF2];4259 double vx,vy;4260 double lambda,mu;4261 double bed,thickness,Neff;4262 double alpha_complement;4263 int drag_type;4264 double drag;4265 Friction* friction=NULL;4266 4267 /*element vector at the gaussian points: */4268 double grade_g[numgrids]={0.0};4269 double grade_g_gaussian[numgrids];4270 4271 /* Jacobian: */4272 double Jdet;4273 4274 /*nodal functions: */4275 double l1l2l3[3];4276 4277 /* strain rate: */4278 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/4279 4280 /*inputs: */4281 bool shelf;4282 4283 /*parameters: */4284 double cm_noisedmp;4285 double cm_mindmp_slope;4286 double cm_mindmp_value;4287 double cm_maxdmp_value;4288 double cm_maxdmp_slope;4289 4290 int analysis_type;4291 4292 /*retrive parameters: */4293 parameters->FindParam(&analysis_type,AnalysisTypeEnum);4294 4295 /*retrieve inputs :*/4296 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);4297 4298 /*retrieve some parameters: */4299 this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);4300 this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum);4301 this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum);4302 this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum);4303 this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum);4304 4305 4306 /*Get out if shelf*/4307 if(shelf)return;4308 4309 /* Get node coordinates and dof list: */4310 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);4311 GetDofList1(&doflist1[0]);4312 4313 /*Build frictoin element, needed later: */4314 inputs->GetParameterValue(&drag_type,DragTypeEnum);4315 friction=new Friction("2d",inputs,matpar,analysis_type);4316 4317 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */4318 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4);4319 4320 /* Start looping on the number of gaussian points: */4321 for (ig=0; ig<num_gauss; ig++){4322 /*Pick up the gaussian point: */4323 gauss_weight=*(gauss_weights+ig);4324 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);4325 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);4326 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);4327 4328 /*Build alpha_complement_list: */4329 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss_l1l2l3,VxAverageEnum,VyAverageEnum);4330 else alpha_complement=0;4331 4332 /*Recover alpha_complement and k: */4333 inputs->GetParameterValue(&drag, gauss_l1l2l3,DragCoefficientEnum);4334 4335 /*recover lambda and mu: */4336 inputs->GetParameterValue(&lambda, gauss_l1l2l3,AdjointxEnum);4337 inputs->GetParameterValue(&mu, gauss_l1l2l3,AdjointyEnum);4338 4339 /*recover vx and vy: */4340 inputs->GetParameterValue(&vx, gauss_l1l2l3,VxEnum);4341 inputs->GetParameterValue(&vy, gauss_l1l2l3,VyEnum);4342 4343 /* Get Jacobian determinant: */4344 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);4345 4346 /* Get nodal functions value at gaussian point:*/4347 GetNodalFunctions(l1l2l3, gauss_l1l2l3);4348 4349 /*Get nodal functions derivatives*/4350 GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3);4351 4352 /*Get k derivative: dk/dx */4353 inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum);4354 4355 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */4356 for (i=0;i<numgrids;i++){4357 4358 //standard term dJ/dki4359 grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss_weight*l1l2l3[i];4360 4361 //noise dampening d/dki(1/2*(dk/dx)^2)4362 grade_g_gaussian[i]+=-cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]);4363 4364 //min dampening4365 if(drag<cm_mindmp_value){4366 grade_g_gaussian[i]+=cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i];4367 }4368 4369 //max dampening4370 if(drag>cm_maxdmp_value){4371 grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i];4372 }4373 }4374 4375 /*Add gradje_g_gaussian vector to gradje_g: */4376 for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i];4377 }4378 4379 4380 /*Add grade_g to global vector gradient: */4381 VecSetValues(gradient,numgrids,doflist1,(const double*)grade_g,ADD_VALUES);4382 4383 cleanup_and_return:4384 xfree((void**)&first_gauss_area_coord);4385 xfree((void**)&second_gauss_area_coord);4386 xfree((void**)&third_gauss_area_coord);4387 xfree((void**)&gauss_weights);4388 delete friction;4389 4390 }4391 /*}}}*/4392 /*FUNCTION Tria::GradjDragStokes {{{1*/4393 void Tria::GradjDragStokes(Vec gradient){4394 4395 int i;4396 4397 /* node data: */4398 const int numgrids=3;4399 const int NDOF2=2;4400 double xyz_list[numgrids][3];4401 int doflist1[numgrids];4402 double dh1dh3[NDOF2][numgrids];4403 4404 /* grid data: */4405 double drag;4406 double alpha_complement;4407 Friction* friction=NULL;4408 4409 /* gaussian points: */4410 int num_gauss,ig;4411 double* first_gauss_area_coord = NULL;4412 double* second_gauss_area_coord = NULL;4413 double* third_gauss_area_coord = NULL;4414 double* gauss_weights = NULL;4415 double gauss_weight;4416 double gauss_l1l2l3[3];4417 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}};4418 4419 /* parameters: */4420 double vx,vy,vz;4421 double lambda,mu,xi;4422 double bed,thickness,Neff;4423 double surface_normal[3];4424 double bed_normal[3];4425 double dk[NDOF2];4426 4427 /*element vector at the gaussian points: */4428 double grade_g[numgrids]={0.0};4429 double grade_g_gaussian[numgrids];4430 4431 /* Jacobian: */4432 double Jdet;4433 4434 /*nodal functions: */4435 double l1l2l3[3];4436 4437 /* strain rate: */4438 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/4439 4440 /*inputs: */4441 bool shelf;4442 int drag_type;4443 4444 /*parameters: */4445 double cm_noisedmp;4446 double cm_mindmp_slope;4447 double cm_mindmp_value;4448 double cm_maxdmp_value;4449 double cm_maxdmp_slope;4450 4451 int analysis_type;4452 4453 /*retrive parameters: */4454 parameters->FindParam(&analysis_type,AnalysisTypeEnum);4455 4456 /*retrieve inputs :*/4457 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);4458 inputs->GetParameterValue(&drag_type,DragTypeEnum);4459 4460 /*retrieve some parameters: */4461 this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum);4462 this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum);4463 this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum);4464 this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum);4465 this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum);4466 4467 /*Get out if shelf*/4468 if(shelf)return;4469 4470 /* Get node coordinates and dof list: */4471 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);4472 GetDofList1(&doflist1[0]);4473 4474 /*Build frictoin element, needed later: */4475 inputs->GetParameterValue(&drag_type,DragTypeEnum);4476 friction=new Friction("2d",inputs,matpar,analysis_type);4477 4478 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */4479 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4);4480 4481 /* Start looping on the number of gaussian points: */4482 for (ig=0; ig<num_gauss; ig++){4483 /*Pick up the gaussian point: */4484 gauss_weight=*(gauss_weights+ig);4485 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig);4486 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig);4487 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig);4488 4489 /*Recover alpha_complement and drag: */4490 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss_l1l2l3,VxAverageEnum,VyAverageEnum);4491 else alpha_complement=0;4492 inputs->GetParameterValue(&drag, &gauss_l1l2l3[0],DragCoefficientEnum);4493 4494 /*recover lambda mu and xi: */4495 inputs->GetParameterValue(&lambda, &gauss_l1l2l3[0],AdjointxEnum);4496 inputs->GetParameterValue(&mu, &gauss_l1l2l3[0],AdjointyEnum);4497 inputs->GetParameterValue(&xi, &gauss_l1l2l3[0],AdjointzEnum);4498 4499 /*recover vx vy and vz: */4500 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum);4501 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum);4502 inputs->GetParameterValue(&vz, &gauss_l1l2l3[0],VzEnum);4503 4504 /*Get normal vector to the bed */4505 SurfaceNormal(&surface_normal[0],xyz_list);4506 4507 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result4508 bed_normal[1]=-surface_normal[1];4509 bed_normal[2]=-surface_normal[2];4510 4511 /* Get Jacobian determinant: */4512 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3);4513 4514 /* Get nodal functions value at gaussian point:*/4515 GetNodalFunctions(l1l2l3, gauss_l1l2l3);4516 4517 /*Get nodal functions derivatives*/4518 GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3);4519 4520 /*Get k derivative: dk/dx */4521 inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum);4522 4523 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */4524 for (i=0;i<numgrids;i++){4525 //standard gradient dJ/dki4526 grade_g_gaussian[i]=(4527 -lambda*(2*drag*alpha_complement*(vx - vz*bed_normal[0]*bed_normal[2]))4528 -mu *(2*drag*alpha_complement*(vy - vz*bed_normal[1]*bed_normal[2]))4529 -xi *(2*drag*alpha_complement*(-vx*bed_normal[0]*bed_normal[2]-vy*bed_normal[1]*bed_normal[2]))4530 )*Jdet*gauss_weight*l1l2l3[i];4531 4532 //Add regularization term4533 grade_g_gaussian[i]+= - cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]);4534 4535 //min dampening4536 if(drag<cm_mindmp_value){4537 grade_g_gaussian[i]+= cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i];4538 }4539 4540 //max dampening4541 if(drag>cm_maxdmp_value){4542 grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i];4543 }4544 }4545 4546 /*Add gradje_g_gaussian vector to gradje_g: */4547 for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i];4548 }4549 4550 /*Add grade_g to global vector gradient: */4551 VecSetValues(gradient,numgrids,doflist1,(const double*)grade_g,ADD_VALUES);4552 4553 /*Add grade_g to the inputs of this element: */4554 this->inputs->AddInput(new TriaVertexInput(GradientEnum,&grade_g[0]));4555 4556 cleanup_and_return:4557 xfree((void**)&first_gauss_area_coord);4558 xfree((void**)&second_gauss_area_coord);4559 xfree((void**)&third_gauss_area_coord);4560 xfree((void**)&gauss_weights);4561 delete friction;4562 4563 1023 } 4564 1024 /*}}}*/ … … 4709 1169 } 4710 1170 /*}}}*/ 1171 /*FUNCTION Tria::GradjDrag {{{1*/ 1172 void Tria::GradjDrag(Vec gradient){ 1173 1174 1175 int i; 1176 1177 /* node data: */ 1178 const int numgrids=3; 1179 const int NDOF2=2; 1180 const int numdof=NDOF2*numgrids; 1181 double xyz_list[numgrids][3]; 1182 int doflist1[numgrids]; 1183 double dh1dh3[NDOF2][numgrids]; 1184 1185 /* grid data: */ 1186 double adjx_list[numgrids]; 1187 double adjy_list[numgrids]; 1188 1189 /* gaussian points: */ 1190 int num_gauss,ig; 1191 double* first_gauss_area_coord = NULL; 1192 double* second_gauss_area_coord = NULL; 1193 double* third_gauss_area_coord = NULL; 1194 double* gauss_weights = NULL; 1195 double gauss_weight; 1196 double gauss_l1l2l3[3]; 1197 1198 /* parameters: */ 1199 double dk[NDOF2]; 1200 double vx,vy; 1201 double lambda,mu; 1202 double bed,thickness,Neff; 1203 double alpha_complement; 1204 int drag_type; 1205 double drag; 1206 Friction* friction=NULL; 1207 1208 /*element vector at the gaussian points: */ 1209 double grade_g[numgrids]={0.0}; 1210 double grade_g_gaussian[numgrids]; 1211 1212 /* Jacobian: */ 1213 double Jdet; 1214 1215 /*nodal functions: */ 1216 double l1l2l3[3]; 1217 1218 /* strain rate: */ 1219 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/ 1220 1221 /*inputs: */ 1222 bool shelf; 1223 1224 /*parameters: */ 1225 double cm_noisedmp; 1226 double cm_mindmp_slope; 1227 double cm_mindmp_value; 1228 double cm_maxdmp_value; 1229 double cm_maxdmp_slope; 1230 1231 int analysis_type; 1232 1233 /*retrive parameters: */ 1234 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 1235 1236 /*retrieve inputs :*/ 1237 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum); 1238 1239 /*retrieve some parameters: */ 1240 this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum); 1241 this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum); 1242 this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum); 1243 this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum); 1244 this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum); 1245 1246 1247 /*Get out if shelf*/ 1248 if(shelf)return; 1249 1250 /* Get node coordinates and dof list: */ 1251 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 1252 GetDofList1(&doflist1[0]); 1253 1254 /*Build frictoin element, needed later: */ 1255 inputs->GetParameterValue(&drag_type,DragTypeEnum); 1256 friction=new Friction("2d",inputs,matpar,analysis_type); 1257 1258 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 1259 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4); 1260 1261 /* Start looping on the number of gaussian points: */ 1262 for (ig=0; ig<num_gauss; ig++){ 1263 /*Pick up the gaussian point: */ 1264 gauss_weight=*(gauss_weights+ig); 1265 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 1266 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 1267 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 1268 1269 /*Build alpha_complement_list: */ 1270 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss_l1l2l3,VxAverageEnum,VyAverageEnum); 1271 else alpha_complement=0; 1272 1273 /*Recover alpha_complement and k: */ 1274 inputs->GetParameterValue(&drag, gauss_l1l2l3,DragCoefficientEnum); 1275 1276 /*recover lambda and mu: */ 1277 inputs->GetParameterValue(&lambda, gauss_l1l2l3,AdjointxEnum); 1278 inputs->GetParameterValue(&mu, gauss_l1l2l3,AdjointyEnum); 1279 1280 /*recover vx and vy: */ 1281 inputs->GetParameterValue(&vx, gauss_l1l2l3,VxEnum); 1282 inputs->GetParameterValue(&vy, gauss_l1l2l3,VyEnum); 1283 1284 /* Get Jacobian determinant: */ 1285 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 1286 1287 /* Get nodal functions value at gaussian point:*/ 1288 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 1289 1290 /*Get nodal functions derivatives*/ 1291 GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3); 1292 1293 /*Get k derivative: dk/dx */ 1294 inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum); 1295 1296 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */ 1297 for (i=0;i<numgrids;i++){ 1298 1299 //standard term dJ/dki 1300 grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss_weight*l1l2l3[i]; 1301 1302 //noise dampening d/dki(1/2*(dk/dx)^2) 1303 grade_g_gaussian[i]+=-cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]); 1304 1305 //min dampening 1306 if(drag<cm_mindmp_value){ 1307 grade_g_gaussian[i]+=cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i]; 1308 } 1309 1310 //max dampening 1311 if(drag>cm_maxdmp_value){ 1312 grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i]; 1313 } 1314 } 1315 1316 /*Add gradje_g_gaussian vector to gradje_g: */ 1317 for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i]; 1318 } 1319 1320 1321 /*Add grade_g to global vector gradient: */ 1322 VecSetValues(gradient,numgrids,doflist1,(const double*)grade_g,ADD_VALUES); 1323 1324 cleanup_and_return: 1325 xfree((void**)&first_gauss_area_coord); 1326 xfree((void**)&second_gauss_area_coord); 1327 xfree((void**)&third_gauss_area_coord); 1328 xfree((void**)&gauss_weights); 1329 delete friction; 1330 1331 } 1332 /*}}}*/ 1333 /*FUNCTION Tria::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/ 1334 void Tria::InputAXPY(int YEnum, double scalar, int XEnum){ 1335 1336 Input* xinput=NULL; 1337 Input* yinput=NULL; 1338 1339 /*Find x and y inputs: */ 1340 xinput=(Input*)this->inputs->GetInput(XEnum); 1341 yinput=(Input*)this->inputs->GetInput(YEnum); 1342 1343 /*some checks: */ 1344 if(!xinput || !yinput) ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!"); 1345 1346 /*Scale: */ 1347 yinput->AXPY(xinput,scalar); 1348 } 1349 /*}}}*/ 1350 /*FUNCTION Tria::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/ 1351 void Tria::InputControlConstrain(int control_type, double cm_min, double cm_max){ 1352 1353 Input* input=NULL; 1354 1355 /*Find input: */ 1356 input=(Input*)this->inputs->GetInput(control_type); 1357 1358 /*Do nothing if we don't find it: */ 1359 if(!input)return; 1360 1361 /*Constrain input using cm_min and cm_max: */ 1362 input->Constrain(cm_min,cm_max); 1363 1364 } 1365 /*}}}*/ 1366 /*FUNCTION Tria::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/ 1367 void Tria::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){ 1368 1369 int i; 1370 Input** new_inputs=NULL; 1371 Input** old_inputs=NULL; 1372 int converged=1; 1373 1374 new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs 1375 old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs 1376 1377 for(i=0;i<num_enums/2;i++){ 1378 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]); 1379 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]); 1380 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 1381 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 1382 } 1383 1384 /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/ 1385 for(i=0;i<num_criterionenums;i++){ 1386 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]); 1387 if(eps[i]>criterionvalues[i]) converged=0; 1388 } 1389 1390 /*Assign output pointers:*/ 1391 *pconverged=converged; 1392 1393 } 1394 /*}}}*/ 1395 /*FUNCTION Tria::InputDepthAverageAtBase {{{1*/ 1396 void Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type){ 1397 1398 /*New input*/ 1399 Input* oldinput=NULL; 1400 Input* newinput=NULL; 1401 1402 /*copy input of enum_type*/ 1403 oldinput=this->inputs->GetInput(enum_type); 1404 if(!oldinput)ISSMERROR("%s%s"," could not find old input with enum: ",EnumAsString(enum_type)); 1405 newinput=(Input*)oldinput->copy(); 1406 1407 /*Assign new name (average)*/ 1408 newinput->ChangeEnum(average_enum_type); 1409 1410 /*Add new input to current element*/ 1411 this->inputs->AddInput(newinput); 1412 1413 } 1414 /*}}}*/ 1415 /*FUNCTION Tria::InputDuplicate(int original_enum,int new_enum){{{1*/ 1416 void Tria::InputDuplicate(int original_enum,int new_enum){ 1417 1418 Input* original=NULL; 1419 Input* copy=NULL; 1420 1421 /*Make a copy of the original input: */ 1422 original=(Input*)this->inputs->GetInput(original_enum); 1423 copy=(Input*)original->copy(); 1424 1425 /*Change copy enum to reinitialized_enum: */ 1426 copy->ChangeEnum(new_enum); 1427 1428 /*Add copy into inputs, it will wipe off the one already there: */ 1429 inputs->AddObject((Input*)copy); 1430 } 1431 /*}}}*/ 1432 /*FUNCTION Tria::InputScale(int enum_type,double scale_factor){{{1*/ 1433 void Tria::InputScale(int enum_type,double scale_factor){ 1434 1435 Input* input=NULL; 1436 1437 /*Make a copy of the original input: */ 1438 input=(Input*)this->inputs->GetInput(enum_type); 1439 1440 /*Scale: */ 1441 input->Scale(scale_factor); 1442 } 1443 /*}}}*/ 1444 /*FUNCTION Tria::InputToResult(int enum_type,int step,double time){{{1*/ 1445 void Tria::InputToResult(int enum_type,int step,double time){ 1446 1447 int i; 1448 bool found = false; 1449 Input *input = NULL; 1450 1451 /*Go through all the input objects, and find the one corresponding to enum_type, if it exists: */ 1452 for (i=0;i<this->inputs->Size();i++){ 1453 input=(Input*)this->inputs->GetObjectByOffset(i); 1454 if (input->EnumType()==enum_type){ 1455 found=true; 1456 break; 1457 } 1458 } 1459 1460 /*If we don't find it, no big deal, just don't do the transfer. Otherwise, build a new Result 1461 * object out of the input, with the additional step and time information: */ 1462 this->results->AddObject((Object*)input->SpawnResult(step,time)); 1463 1464 } 1465 /*}}}*/ 4711 1466 /*FUNCTION Tria::MassFlux {{{1*/ 4712 1467 double Tria::MassFlux( double* segment){ … … 4766 1521 ); 4767 1522 return mass_flux; 1523 } 1524 /*}}}*/ 1525 /*FUNCTION Tria::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/ 1526 void Tria::MaxAbsVx(double* pmaxabsvx, bool process_units){ 1527 1528 int i; 1529 int dim; 1530 const int numgrids=3; 1531 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1532 double vx_values[numgrids]; 1533 double maxabsvx; 1534 1535 /*retrieve dim parameter: */ 1536 parameters->FindParam(&dim,DimEnum); 1537 1538 /*retrive velocity values at nodes */ 1539 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 1540 1541 /*now, compute maximum:*/ 1542 maxabsvx=fabs(vx_values[0]); 1543 for(i=1;i<numgrids;i++){ 1544 if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]); 1545 } 1546 1547 /*Assign output pointers:*/ 1548 *pmaxabsvx=maxabsvx; 1549 } 1550 /*}}}*/ 1551 /*FUNCTION Tria::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/ 1552 void Tria::MaxAbsVy(double* pmaxabsvy, bool process_units){ 1553 1554 int i; 1555 int dim; 1556 const int numgrids=3; 1557 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1558 double vy_values[numgrids]; 1559 double maxabsvy; 1560 1561 /*retrieve dim parameter: */ 1562 parameters->FindParam(&dim,DimEnum); 1563 1564 /*retrive velocity values at nodes */ 1565 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 1566 1567 /*now, compute maximum:*/ 1568 maxabsvy=fabs(vy_values[0]); 1569 for(i=1;i<numgrids;i++){ 1570 if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]); 1571 } 1572 1573 /*Assign output pointers:*/ 1574 *pmaxabsvy=maxabsvy; 1575 } 1576 /*}}}*/ 1577 /*FUNCTION Tria::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/ 1578 void Tria::MaxAbsVz(double* pmaxabsvz, bool process_units){ 1579 1580 int i; 1581 int dim; 1582 const int numgrids=3; 1583 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1584 double vz_values[numgrids]; 1585 double maxabsvz; 1586 1587 /*retrieve dim parameter: */ 1588 parameters->FindParam(&dim,DimEnum); 1589 1590 /*retrive velocity values at nodes */ 1591 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 1592 1593 /*now, compute maximum:*/ 1594 maxabsvz=fabs(vz_values[0]); 1595 for(i=1;i<numgrids;i++){ 1596 if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]); 1597 } 1598 1599 /*Assign output pointers:*/ 1600 *pmaxabsvz=maxabsvz; 1601 } 1602 /*}}}*/ 1603 /*FUNCTION Tria::MaxVel(double* pmaxvel, bool process_units);{{{1*/ 1604 void Tria::MaxVel(double* pmaxvel, bool process_units){ 1605 1606 int i; 1607 int dim; 1608 const int numgrids=3; 1609 double gaussgrids[numgrids][3]={{1,0,0},{0,1,0},{0,0,1}}; 1610 double vx_values[numgrids]; 1611 double vy_values[numgrids]; 1612 double vz_values[numgrids]; 1613 double vel_values[numgrids]; 1614 double maxvel; 1615 1616 /*retrieve dim parameter: */ 1617 parameters->FindParam(&dim,DimEnum); 1618 1619 /*retrive velocity values at nodes */ 1620 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 1621 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 1622 if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 1623 1624 /*now, compute maximum of velocity :*/ 1625 if(dim==2){ 1626 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)); 1627 } 1628 else{ 1629 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2)); 1630 } 1631 1632 /*now, compute maximum:*/ 1633 maxvel=vel_values[0]; 1634 for(i=1;i<numgrids;i++){ 1635 if (vel_values[i]>maxvel)maxvel=vel_values[i]; 1636 } 1637 1638 /*Assign output pointers:*/ 1639 *pmaxvel=maxvel; 1640 1641 } 1642 /*}}}*/ 1643 /*FUNCTION Tria::MaxVx(double* pmaxvx, bool process_units);{{{1*/ 1644 void Tria::MaxVx(double* pmaxvx, bool process_units){ 1645 1646 int i; 1647 int dim; 1648 const int numgrids=3; 1649 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1650 double vx_values[numgrids]; 1651 double maxvx; 1652 1653 /*retrieve dim parameter: */ 1654 parameters->FindParam(&dim,DimEnum); 1655 1656 /*retrive velocity values at nodes */ 1657 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 1658 1659 /*now, compute maximum:*/ 1660 maxvx=vx_values[0]; 1661 for(i=1;i<numgrids;i++){ 1662 if (vx_values[i]>maxvx)maxvx=vx_values[i]; 1663 } 1664 1665 /*Assign output pointers:*/ 1666 *pmaxvx=maxvx; 1667 1668 } 1669 /*}}}*/ 1670 /*FUNCTION Tria::MaxVy(double* pmaxvy, bool process_units);{{{1*/ 1671 void Tria::MaxVy(double* pmaxvy, bool process_units){ 1672 1673 int i; 1674 int dim; 1675 const int numgrids=3; 1676 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1677 double vy_values[numgrids]; 1678 double maxvy; 1679 1680 /*retrieve dim parameter: */ 1681 parameters->FindParam(&dim,DimEnum); 1682 1683 /*retrive velocity values at nodes */ 1684 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 1685 1686 /*now, compute maximum:*/ 1687 maxvy=vy_values[0]; 1688 for(i=1;i<numgrids;i++){ 1689 if (vy_values[i]>maxvy)maxvy=vy_values[i]; 1690 } 1691 1692 /*Assign output pointers:*/ 1693 *pmaxvy=maxvy; 1694 1695 } 1696 /*}}}*/ 1697 /*FUNCTION Tria::MaxVz(double* pmaxvz, bool process_units);{{{1*/ 1698 void Tria::MaxVz(double* pmaxvz, bool process_units){ 1699 1700 int i; 1701 int dim; 1702 const int numgrids=3; 1703 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1704 double vz_values[numgrids]; 1705 double maxvz; 1706 1707 /*retrieve dim parameter: */ 1708 parameters->FindParam(&dim,DimEnum); 1709 1710 /*retrive velocity values at nodes */ 1711 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 1712 1713 /*now, compute maximum:*/ 1714 maxvz=vz_values[0]; 1715 for(i=1;i<numgrids;i++){ 1716 if (vz_values[i]>maxvz)maxvz=vz_values[i]; 1717 } 1718 1719 /*Assign output pointers:*/ 1720 *pmaxvz=maxvz; 1721 1722 } 1723 /*}}}*/ 1724 /*FUNCTION Tria::MinVel(double* pminvel, bool process_units);{{{1*/ 1725 void Tria::MinVel(double* pminvel, bool process_units){ 1726 1727 int i; 1728 int dim; 1729 const int numgrids=3; 1730 double gaussgrids[numgrids][3]={{1,0,0},{0,1,0},{0,0,1}}; 1731 double vx_values[numgrids]; 1732 double vy_values[numgrids]; 1733 double vz_values[numgrids]; 1734 double vel_values[numgrids]; 1735 double minvel; 1736 1737 /*retrieve dim parameter: */ 1738 parameters->FindParam(&dim,DimEnum); 1739 1740 /*retrive velocity values at nodes */ 1741 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 1742 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 1743 if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 1744 1745 /*now, compute minimum of velocity :*/ 1746 if(dim==2){ 1747 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)); 1748 } 1749 else{ 1750 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2)); 1751 } 1752 1753 /*now, compute minimum:*/ 1754 minvel=vel_values[0]; 1755 for(i=1;i<numgrids;i++){ 1756 if (vel_values[i]<minvel)minvel=vel_values[i]; 1757 } 1758 1759 /*Assign output pointers:*/ 1760 *pminvel=minvel; 1761 1762 } 1763 /*}}}*/ 1764 /*FUNCTION Tria::MinVx(double* pminvx, bool process_units);{{{1*/ 1765 void Tria::MinVx(double* pminvx, bool process_units){ 1766 1767 int i; 1768 int dim; 1769 const int numgrids=3; 1770 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1771 double vx_values[numgrids]; 1772 double minvx; 1773 1774 /*retrieve dim parameter: */ 1775 parameters->FindParam(&dim,DimEnum); 1776 1777 /*retrive velocity values at nodes */ 1778 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 1779 1780 /*now, compute minimum:*/ 1781 minvx=vx_values[0]; 1782 for(i=1;i<numgrids;i++){ 1783 if (vx_values[i]<minvx)minvx=vx_values[i]; 1784 } 1785 1786 /*Assign output pointers:*/ 1787 *pminvx=minvx; 1788 1789 } 1790 /*}}}*/ 1791 /*FUNCTION Tria::MinVy(double* pminvy, bool process_units);{{{1*/ 1792 void Tria::MinVy(double* pminvy, bool process_units){ 1793 1794 int i; 1795 int dim; 1796 const int numgrids=3; 1797 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1798 double vy_values[numgrids]; 1799 double minvy; 1800 1801 /*retrieve dim parameter: */ 1802 parameters->FindParam(&dim,DimEnum); 1803 1804 /*retrive velocity values at nodes */ 1805 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 1806 1807 /*now, compute minimum:*/ 1808 minvy=vy_values[0]; 1809 for(i=1;i<numgrids;i++){ 1810 if (vy_values[i]<minvy)minvy=vy_values[i]; 1811 } 1812 1813 /*Assign output pointers:*/ 1814 *pminvy=minvy; 1815 1816 } 1817 /*}}}*/ 1818 /*FUNCTION Tria::MinVz(double* pminvz, bool process_units);{{{1*/ 1819 void Tria::MinVz(double* pminvz, bool process_units){ 1820 1821 int i; 1822 int dim; 1823 const int numgrids=3; 1824 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 1825 double vz_values[numgrids]; 1826 double minvz; 1827 1828 /*retrieve dim parameter: */ 1829 parameters->FindParam(&dim,DimEnum); 1830 1831 /*retrive velocity values at nodes */ 1832 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 1833 1834 /*now, compute minimum:*/ 1835 minvz=vz_values[0]; 1836 for(i=1;i<numgrids;i++){ 1837 if (vz_values[i]<minvz)minvz=vz_values[i]; 1838 } 1839 1840 /*Assign output pointers:*/ 1841 *pminvz=minvz; 1842 4768 1843 } 4769 1844 /*}}}*/ … … 4960 2035 } 4961 2036 /*}}}*/ 4962 /*FUNCTION Tria::SetClone {{{1*/ 4963 void Tria::SetClone(int* minranks){ 4964 4965 ISSMERROR("not implemented yet"); 4966 } 4967 /*}}}1*/ 4968 /*FUNCTION Tria::SurfaceNormal{{{1*/ 4969 4970 void Tria::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ 2037 /*FUNCTION Tria::PatchFill(int* prow, Patch* patch){{{1*/ 2038 void Tria::PatchFill(int* prow, Patch* patch){ 4971 2039 4972 2040 int i; 4973 double v13[3]; 4974 double v23[3]; 4975 double normal[3]; 4976 double normal_norm; 4977 4978 for (i=0;i<3;i++){ 4979 v13[i]=xyz_list[0][i]-xyz_list[2][i]; 4980 v23[i]=xyz_list[1][i]-xyz_list[2][i]; 4981 } 4982 4983 normal[0]=v13[1]*v23[2]-v13[2]*v23[1]; 4984 normal[1]=v13[2]*v23[0]-v13[0]*v23[2]; 4985 normal[2]=v13[0]*v23[1]-v13[1]*v23[0]; 4986 4987 normal_norm=sqrt( pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2) ); 4988 4989 *(surface_normal)=normal[0]/normal_norm; 4990 *(surface_normal+1)=normal[1]/normal_norm; 4991 *(surface_normal+2)=normal[2]/normal_norm; 4992 4993 } 4994 /*}}}*/ 4995 /*FUNCTION Tria::SurfaceArea {{{1*/ 4996 double Tria::SurfaceArea(void){ 4997 4998 int i; 4999 5000 /* output: */ 5001 double S; 5002 5003 /* node data: */ 5004 int numgrids=3; 5005 double xyz_list[numgrids][3]; 5006 double v13[3]; 5007 double v23[3]; 5008 double normal[3]; 5009 5010 /*inputs: */ 5011 bool onwater; 5012 int fit; 5013 5014 /*retrieve inputs :*/ 5015 inputs->GetParameterValue(&fit,FitEnum); 5016 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 5017 5018 /*If fit!=3, do not compute surface: */ 5019 if(fit!=3)return 0; 5020 5021 /*If on water, return 0: */ 5022 if(onwater)return 0; 5023 5024 /* Get node coordinates and dof list: */ 5025 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 5026 5027 for (i=0;i<3;i++){ 5028 v13[i]=xyz_list[0][i]-xyz_list[2][i]; 5029 v23[i]=xyz_list[1][i]-xyz_list[2][i]; 5030 } 5031 5032 normal[0]=v13[1]*v23[2]-v13[2]*v23[1]; 5033 normal[1]=v13[2]*v23[0]-v13[0]*v23[2]; 5034 normal[2]=v13[0]*v23[1]-v13[1]*v23[0]; 5035 5036 S = 0.5 * sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2)); 5037 5038 /*Return: */ 5039 return S; 5040 } 5041 /*}}}*/ 5042 /*FUNCTION Tria::InputUpdateFromVector(double* vector, int name, int type);{{{1*/ 5043 void Tria::InputUpdateFromVector(double* vector, int name, int type){ 5044 5045 /*Check that name is an element input*/ 5046 if (!IsInput(name)) return; 5047 5048 switch(type){ 5049 5050 case VertexEnum: 5051 5052 /*New PentaVertexInpu*/ 5053 double values[3]; 5054 5055 /*Get values on the 6 vertices*/ 5056 for (int i=0;i<3;i++){ 5057 values[i]=vector[this->nodes[i]->GetVertexDof()]; 5058 } 5059 5060 /*update input*/ 5061 this->inputs->AddInput(new TriaVertexInput(name,values)); 5062 return; 5063 5064 default: 5065 5066 ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type)); 5067 } 5068 } 5069 /*}}}*/ 5070 /*FUNCTION Tria::InputUpdateFromVector(int* vector, int name, int type);{{{1*/ 5071 void Tria::InputUpdateFromVector(int* vector, int name, int type){ 5072 ISSMERROR(" not supported yet!"); 5073 } 5074 /*}}}*/ 5075 /*FUNCTION Tria::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/ 5076 void Tria::InputUpdateFromVector(bool* vector, int name, int type){ 5077 ISSMERROR(" not supported yet!"); 5078 } 5079 /*}}}*/ 5080 /*FUNCTION Tria::InputUpdateFromConstant(int value, int name);{{{1*/ 5081 void Tria::InputUpdateFromConstant(int constant, int name){ 5082 /*Nothing updated for now*/ 5083 } 5084 /*}}}*/ 5085 /*FUNCTION Tria::InputUpdateFromConstant(double value, int name);{{{1*/ 5086 void Tria::InputUpdateFromConstant(double constant, int name){ 5087 /*Nothing updated for now*/ 5088 } 5089 /*}}}*/ 5090 /*FUNCTION Tria::InputUpdateFromConstant(bool value, int name);{{{1*/ 5091 void Tria::InputUpdateFromConstant(bool constant, int name){ 5092 /*Nothing updated for now*/ 5093 } 5094 /*}}}*/ 5095 /*FUNCTION Tria::InputDepthAverageAtBase {{{1*/ 5096 void Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type){ 5097 5098 /*New input*/ 5099 Input* oldinput=NULL; 5100 Input* newinput=NULL; 5101 5102 /*copy input of enum_type*/ 5103 oldinput=this->inputs->GetInput(enum_type); 5104 if(!oldinput)ISSMERROR("%s%s"," could not find old input with enum: ",EnumAsString(enum_type)); 5105 newinput=(Input*)oldinput->copy(); 5106 5107 /*Assign new name (average)*/ 5108 newinput->ChangeEnum(average_enum_type); 5109 5110 /*Add new input to current element*/ 5111 this->inputs->AddInput(newinput); 5112 2041 int row; 2042 int vertices_ids[3]; 2043 2044 2045 /*recover pointer: */ 2046 row=*prow; 2047 2048 /*will be needed later: */ 2049 for(i=0;i<3;i++) vertices_ids[i]=nodes[i]->GetVertexId(); //vertices id start at column 3 of the patch. 2050 2051 for(i=0;i<this->results->Size();i++){ 2052 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i); 2053 2054 /*For this result,fill the information in the Patch object (element id + vertices ids), and then hand 2055 *it to the result object, to fill the rest: */ 2056 patch->fillelementinfo(row,this->id,vertices_ids,3); 2057 elementresult->PatchFill(row,patch); 2058 2059 /*increment rower: */ 2060 row++; 2061 } 2062 2063 /*Assign output pointers:*/ 2064 *prow=row; 5113 2065 } 5114 2066 /*}}}*/ … … 5140 2092 } 5141 2093 /*}}}*/ 5142 /*FUNCTION Tria::P atchFill(int* prow, Patch* patch){{{1*/5143 void Tria::P atchFill(int* prow, Patch* patch){2094 /*FUNCTION Tria::ProcessResultsUnits(void){{{1*/ 2095 void Tria::ProcessResultsUnits(void){ 5144 2096 5145 2097 int i; 5146 int row;5147 int vertices_ids[3];5148 5149 5150 /*recover pointer: */5151 row=*prow;5152 5153 /*will be needed later: */5154 for(i=0;i<3;i++) vertices_ids[i]=nodes[i]->GetVertexId(); //vertices id start at column 3 of the patch.5155 2098 5156 2099 for(i=0;i<this->results->Size();i++){ 5157 2100 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i); 5158 5159 /*For this result,fill the information in the Patch object (element id + vertices ids), and then hand 5160 *it to the result object, to fill the rest: */ 5161 patch->fillelementinfo(row,this->id,vertices_ids,3); 5162 elementresult->PatchFill(row,patch); 5163 5164 /*increment rower: */ 5165 row++; 2101 elementresult->ProcessUnits(this->parameters); 2102 } 2103 2104 } 2105 /*}}}*/ 2106 /*FUNCTION Tria::SurfaceArea {{{1*/ 2107 double Tria::SurfaceArea(void){ 2108 2109 int i; 2110 2111 /* output: */ 2112 double S; 2113 2114 /* node data: */ 2115 int numgrids=3; 2116 double xyz_list[numgrids][3]; 2117 double v13[3]; 2118 double v23[3]; 2119 double normal[3]; 2120 2121 /*inputs: */ 2122 bool onwater; 2123 int fit; 2124 2125 /*retrieve inputs :*/ 2126 inputs->GetParameterValue(&fit,FitEnum); 2127 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 2128 2129 /*If fit!=3, do not compute surface: */ 2130 if(fit!=3)return 0; 2131 2132 /*If on water, return 0: */ 2133 if(onwater)return 0; 2134 2135 /* Get node coordinates and dof list: */ 2136 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2137 2138 for (i=0;i<3;i++){ 2139 v13[i]=xyz_list[0][i]-xyz_list[2][i]; 2140 v23[i]=xyz_list[1][i]-xyz_list[2][i]; 2141 } 2142 2143 normal[0]=v13[1]*v23[2]-v13[2]*v23[1]; 2144 normal[1]=v13[2]*v23[0]-v13[0]*v23[2]; 2145 normal[2]=v13[0]*v23[1]-v13[1]*v23[0]; 2146 2147 S = 0.5 * sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2)); 2148 2149 /*Return: */ 2150 return S; 2151 } 2152 /*}}}*/ 2153 /*FUNCTION Tria::Update(IoModel* iomodel,int analysis_counter,int analysis_type){{{1*/ 2154 void Tria::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){ //i is the element index 2155 2156 /*Intermediaries*/ 2157 int i; 2158 int tria_node_ids[3]; 2159 int tria_vertex_ids[3]; 2160 double nodeinputs[3]; 2161 2162 /*Checks if debuging*/ 2163 /*{{{2*/ 2164 ISSMASSERT(iomodel->elements); 2165 /*}}}*/ 2166 2167 /*Recover vertices ids needed to initialize inputs*/ 2168 for(i=0;i<3;i++){ 2169 tria_vertex_ids[i]=(int)iomodel->elements[3*index+i]; //ids for vertices are in the elements array from Matlab 2170 } 2171 2172 /*Recover nodes ids needed to initialize the node hook.*/ 2173 if (analysis_type==Prognostic2AnalysisEnum || analysis_type==Balancedthickness2AnalysisEnum){ 2174 /*Discontinuous Galerkin*/ 2175 tria_node_ids[0]=iomodel->nodecounter+3*index+1; 2176 tria_node_ids[1]=iomodel->nodecounter+3*index+2; 2177 tria_node_ids[2]=iomodel->nodecounter+3*index+3; 2178 } 2179 else{ 2180 /*Continuous Galerkin*/ 2181 for(i=0;i<3;i++){ 2182 tria_node_ids[i]=iomodel->nodecounter+(int)*(iomodel->elements+3*index+i); //ids for vertices are in the elements array from Matlab 2183 } 2184 } 2185 2186 /*hooks: */ 2187 this->SetHookNodes(tria_node_ids,analysis_counter); this->nodes=NULL; //set hook to nodes, for this analysis type 2188 2189 /*add as many inputs per element as requested:*/ 2190 if (iomodel->thickness) { 2191 for(i=0;i<3;i++)nodeinputs[i]=iomodel->thickness[tria_vertex_ids[i]-1]; 2192 this->inputs->AddInput(new TriaVertexInput(ThicknessEnum,nodeinputs)); 2193 } 2194 if (iomodel->surface) { 2195 for(i=0;i<3;i++)nodeinputs[i]=iomodel->surface[tria_vertex_ids[i]-1]; 2196 this->inputs->AddInput(new TriaVertexInput(SurfaceEnum,nodeinputs)); 2197 } 2198 if (iomodel->bed) { 2199 for(i=0;i<3;i++)nodeinputs[i]=iomodel->bed[tria_vertex_ids[i]-1]; 2200 this->inputs->AddInput(new TriaVertexInput(BedEnum,nodeinputs)); 2201 } 2202 if (iomodel->drag_coefficient) { 2203 for(i=0;i<3;i++)nodeinputs[i]=iomodel->drag_coefficient[tria_vertex_ids[i]-1]; 2204 this->inputs->AddInput(new TriaVertexInput(DragCoefficientEnum,nodeinputs)); 2205 2206 if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index])); 2207 if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index])); 2208 this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type)); 2209 } 2210 if (iomodel->melting_rate) { 2211 for(i=0;i<3;i++)nodeinputs[i]=iomodel->melting_rate[tria_vertex_ids[i]-1]/iomodel->yts; 2212 this->inputs->AddInput(new TriaVertexInput(MeltingRateEnum,nodeinputs)); 2213 } 2214 if (iomodel->accumulation_rate) { 2215 for(i=0;i<3;i++)nodeinputs[i]=iomodel->accumulation_rate[tria_vertex_ids[i]-1]/iomodel->yts; 2216 this->inputs->AddInput(new TriaVertexInput(AccumulationRateEnum,nodeinputs)); 2217 } 2218 if (iomodel->geothermalflux) { 2219 for(i=0;i<3;i++)nodeinputs[i]=iomodel->geothermalflux[tria_vertex_ids[i]-1]; 2220 this->inputs->AddInput(new TriaVertexInput(GeothermalFluxEnum,nodeinputs)); 2221 } 2222 if (iomodel->dhdt) { 2223 for(i=0;i<3;i++)nodeinputs[i]=iomodel->dhdt[tria_vertex_ids[i]-1]; 2224 this->inputs->AddInput(new TriaVertexInput(DhDtEnum,nodeinputs)); 2225 } 2226 if (iomodel->pressure) { 2227 for(i=0;i<3;i++)nodeinputs[i]=iomodel->pressure[tria_vertex_ids[i]-1]; 2228 this->inputs->AddInput(new TriaVertexInput(PressureEnum,nodeinputs)); 2229 } 2230 if (iomodel->temperature) { 2231 for(i=0;i<3;i++)nodeinputs[i]=iomodel->temperature[tria_vertex_ids[i]-1]; 2232 this->inputs->AddInput(new TriaVertexInput(TemperatureEnum,nodeinputs)); 2233 } 2234 /*vx,vy and vz: */ 2235 if (iomodel->vx) { 2236 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx[tria_vertex_ids[i]-1]/iomodel->yts; 2237 this->inputs->AddInput(new TriaVertexInput(VxEnum,nodeinputs)); 2238 this->inputs->AddInput(new TriaVertexInput(VxOldEnum,nodeinputs)); 2239 } 2240 if (iomodel->vy) { 2241 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy[tria_vertex_ids[i]-1]/iomodel->yts; 2242 this->inputs->AddInput(new TriaVertexInput(VyEnum,nodeinputs)); 2243 this->inputs->AddInput(new TriaVertexInput(VyOldEnum,nodeinputs)); 2244 } 2245 if (iomodel->vz) { 2246 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz[tria_vertex_ids[i]-1]/iomodel->yts; 2247 this->inputs->AddInput(new TriaVertexInput(VzEnum,nodeinputs)); 2248 this->inputs->AddInput(new TriaVertexInput(VzOldEnum,nodeinputs)); 2249 } 2250 if (iomodel->vx_obs) { 2251 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2252 this->inputs->AddInput(new TriaVertexInput(VxObsEnum,nodeinputs)); 2253 } 2254 if (iomodel->vy_obs) { 2255 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2256 this->inputs->AddInput(new TriaVertexInput(VyObsEnum,nodeinputs)); 2257 } 2258 if (iomodel->vz_obs) { 2259 for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2260 this->inputs->AddInput(new TriaVertexInput(VzObsEnum,nodeinputs)); 2261 } 2262 if (iomodel->weights) { 2263 for(i=0;i<3;i++)nodeinputs[i]=iomodel->weights[tria_vertex_ids[i]-1]; 2264 this->inputs->AddInput(new TriaVertexInput(WeightsEnum,nodeinputs)); 2265 } 2266 if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index])); 2267 if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index])); 2268 if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index])); 2269 if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index])); 2270 2271 /*Defaults if not provided in iomodel*/ 2272 switch(analysis_type){ 2273 2274 case DiagnosticHorizAnalysisEnum: case DiagnosticVertAnalysisEnum: case DiagnosticStokesAnalysisEnum: 2275 2276 /*default vx,vy and vz: either observation or 0 */ 2277 if(!iomodel->vx){ 2278 if (iomodel->vx_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vx_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2279 else for(i=0;i<3;i++)nodeinputs[i]=0; 2280 this->inputs->AddInput(new TriaVertexInput(VxEnum,nodeinputs)); 2281 this->inputs->AddInput(new TriaVertexInput(VxOldEnum,nodeinputs)); 2282 } 2283 if(!iomodel->vy){ 2284 if (iomodel->vy_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vy_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2285 else for(i=0;i<3;i++)nodeinputs[i]=0; 2286 this->inputs->AddInput(new TriaVertexInput(VyEnum,nodeinputs)); 2287 this->inputs->AddInput(new TriaVertexInput(VyOldEnum,nodeinputs)); 2288 } 2289 if(!iomodel->vz){ 2290 if (iomodel->vz_obs) for(i=0;i<3;i++)nodeinputs[i]=iomodel->vz_obs[tria_vertex_ids[i]-1]/iomodel->yts; 2291 else for(i=0;i<3;i++)nodeinputs[i]=0; 2292 this->inputs->AddInput(new TriaVertexInput(VzEnum,nodeinputs)); 2293 this->inputs->AddInput(new TriaVertexInput(VzOldEnum,nodeinputs)); 2294 } 2295 break; 2296 2297 default: 2298 /*No update for other solution types*/ 2299 break; 2300 2301 } 2302 2303 //this->parameters: we still can't point to it, it may not even exist. Configure will handle this. 2304 this->parameters=NULL; 2305 2306 } 2307 /*}}}*/ 2308 /*FUNCTION Tria::UpdateGeometry{{{1*/ 2309 void Tria::UpdateGeometry(void){ 2310 2311 /*Intermediaries*/ 2312 double rho_ice,rho_water; 2313 2314 /*If shelf: hydrostatic equilibrium*/ 2315 if (this->GetShelf()){ 2316 2317 /*recover material parameters: */ 2318 rho_ice=matpar->GetRhoIce(); 2319 rho_water=matpar->GetRhoWater(); 2320 2321 /*Create New Surface: s = (1-rho_ice/rho_water) h*/ 2322 InputDuplicate(ThicknessEnum,SurfaceEnum); //1: copy thickness into surface 2323 InputScale(SurfaceEnum,(1-rho_ice/rho_water)); //2: surface = surface * (1-di) 2324 2325 /*Create New Bed b = -rho_ice/rho_water h*/ 2326 InputDuplicate(ThicknessEnum,BedEnum); //1: copy thickness into bed 2327 InputScale(BedEnum, -rho_ice/rho_water); //2: bed = bed * (-di) 2328 } 2329 2330 /*If sheet: surface = bed + thickness*/ 2331 else{ 2332 2333 /*The bed does not change, update surface only s = b + h*/ 2334 InputDuplicate(BedEnum,SurfaceEnum); //1: copy bed into surface 2335 InputAXPY(SurfaceEnum,1.0,ThicknessEnum); //2: surface = surface + 1 * thickness 2336 } 2337 2338 } 2339 /*}}}*/ 2340 2341 2342 /*Tria specific routines: */ 2343 /*FUNCTION Tria::CreateKMatrixBalancedthickness {{{1*/ 2344 void Tria::CreateKMatrixBalancedthickness(Mat Kgg){ 2345 2346 /* local declarations */ 2347 int i,j; 2348 2349 /* node data: */ 2350 const int numgrids=3; 2351 const int NDOF1=1; 2352 const int numdof=NDOF1*numgrids; 2353 double xyz_list[numgrids][3]; 2354 int doflist[numdof]; 2355 int numberofdofspernode; 2356 2357 /* gaussian points: */ 2358 int num_gauss,ig; 2359 double* first_gauss_area_coord = NULL; 2360 double* second_gauss_area_coord = NULL; 2361 double* third_gauss_area_coord = NULL; 2362 double* gauss_weights = NULL; 2363 double gauss_weight; 2364 double gauss_l1l2l3[3]; 2365 2366 /* matrices: */ 2367 double L[numgrids]; 2368 double B[2][numgrids]; 2369 double Bprime[2][numgrids]; 2370 double DL[2][2]={0.0}; 2371 double DLprime[2][2]={0.0}; 2372 double DL_scalar; 2373 double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix 2374 double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2375 double Ke_gg_thickness1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2376 double Ke_gg_thickness2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2377 2378 double Jdettria; 2379 2380 /*input parameters for structural analysis (diagnostic): */ 2381 double dvx[2]; 2382 double dvy[2]; 2383 double vx,vy; 2384 double dvxdx,dvydy; 2385 double v_gauss[2]={0.0}; 2386 2387 2388 double K[2][2]={0.0}; 2389 double KDL[2][2]={0.0}; 2390 int dofs[2]={0,1}; 2391 int found=0; 2392 2393 /*parameters: */ 2394 bool artdiff; 2395 2396 /* Get node coordinates and dof list: */ 2397 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2398 GetDofList(&doflist[0],&numberofdofspernode); 2399 2400 /*retrieve some parameters: */ 2401 this->parameters->FindParam(&artdiff,ArtDiffEnum); 2402 2403 //Create Artificial diffusivity once for all if requested 2404 if(artdiff){ 2405 //Get the Jacobian determinant 2406 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD; 2407 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 2408 2409 //Build K matrix (artificial diffusivity matrix) 2410 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum); 2411 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum); 2412 2413 K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]); 2414 K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]); 2415 } 2416 2417 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2418 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 2419 2420 /* Start looping on the number of gaussian points: */ 2421 for (ig=0; ig<num_gauss; ig++){ 2422 /*Pick up the gaussian point: */ 2423 gauss_weight=*(gauss_weights+ig); 2424 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 2425 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 2426 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 2427 2428 /* Get Jacobian determinant: */ 2429 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 2430 2431 /*Get B and B prime matrix: */ 2432 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 2433 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 2434 2435 //Get vx, vy and their derivatives at gauss point 2436 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxAverageEnum); 2437 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyAverageEnum); 2438 2439 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum); 2440 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum); 2441 2442 dvxdx=dvx[0]; 2443 dvydy=dvy[1]; 2444 2445 DL_scalar=gauss_weight*Jdettria; 2446 2447 //Create DL and DLprime matrix 2448 DL[0][0]=DL_scalar*dvxdx; 2449 DL[1][1]=DL_scalar*dvydy; 2450 2451 DLprime[0][0]=DL_scalar*vx; 2452 DLprime[1][1]=DL_scalar*vy; 2453 2454 //Do the triple product tL*D*L. 2455 //Ke_gg_thickness=B'*DLprime*Bprime; 2456 2457 TripleMultiply( &B[0][0],2,numdof,1, 2458 &DL[0][0],2,2,0, 2459 &B[0][0],2,numdof,0, 2460 &Ke_gg_thickness1[0][0],0); 2461 2462 TripleMultiply( &B[0][0],2,numdof,1, 2463 &DLprime[0][0],2,2,0, 2464 &Bprime[0][0],2,numdof,0, 2465 &Ke_gg_thickness2[0][0],0); 2466 2467 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 2468 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j]; 2469 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j]; 2470 2471 if(artdiff){ 2472 2473 /* Compute artificial diffusivity */ 2474 KDL[0][0]=DL_scalar*K[0][0]; 2475 KDL[1][1]=DL_scalar*K[1][1]; 2476 2477 TripleMultiply( &Bprime[0][0],2,numdof,1, 2478 &KDL[0][0],2,2,0, 2479 &Bprime[0][0],2,numdof,0, 2480 &Ke_gg_gaussian[0][0],0); 2481 2482 /* Add artificial diffusivity matrix */ 2483 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 2484 2485 } 2486 } // for (ig=0; ig<num_gauss; ig++) 2487 2488 /*Add Ke_gg to global matrix Kgg: */ 2489 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 2490 2491 cleanup_and_return: 2492 xfree((void**)&first_gauss_area_coord); 2493 xfree((void**)&second_gauss_area_coord); 2494 xfree((void**)&third_gauss_area_coord); 2495 xfree((void**)&gauss_weights); 2496 2497 } 2498 /*}}}*/ 2499 /*FUNCTION Tria::CreateKMatrixBalancedthickness2 {{{1*/ 2500 void Tria::CreateKMatrixBalancedthickness2(Mat Kgg){ 2501 2502 /* local declarations */ 2503 int i,j; 2504 2505 /* node data: */ 2506 const int numgrids=3; 2507 const int NDOF1=1; 2508 const int numdof=NDOF1*numgrids; 2509 double xyz_list[numgrids][3]; 2510 int doflist[numdof]; 2511 int numberofdofspernode; 2512 2513 /* gaussian points: */ 2514 int num_gauss,ig; 2515 double* first_gauss_area_coord = NULL; 2516 double* second_gauss_area_coord = NULL; 2517 double* third_gauss_area_coord = NULL; 2518 double* gauss_weights = NULL; 2519 double gauss_weight; 2520 double gauss_l1l2l3[3]; 2521 2522 /* matrices: */ 2523 double B[2][numgrids]; 2524 double Bprime[2][numgrids]; 2525 double DL[2][2]={0.0}; 2526 double DLprime[2][2]={0.0}; 2527 double DL_scalar; 2528 double Ke_gg[numdof][numdof]={0.0}; 2529 double Ke_gg2[numdof][numdof]={0.0}; 2530 double Jdettria; 2531 2532 /*input parameters for structural analysis (diagnostic): */ 2533 double vx,vy; 2534 int dofs[1]={0}; 2535 int found; 2536 2537 /* Get node coordinates and dof list: */ 2538 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2539 GetDofList(&doflist[0],&numberofdofspernode); 2540 2541 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2542 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 2543 2544 /* Start looping on the number of gaussian points: */ 2545 for (ig=0; ig<num_gauss; ig++){ 2546 /*Pick up the gaussian point: */ 2547 gauss_weight=*(gauss_weights+ig); 2548 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 2549 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 2550 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 2551 2552 /* Get Jacobian determinant: */ 2553 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 2554 2555 /*Get B and B prime matrix: */ 2556 /*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/ 2557 GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 2558 GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 2559 2560 //Get vx, vy and their derivatives at gauss point 2561 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum); 2562 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum); 2563 2564 DL_scalar=-gauss_weight*Jdettria; 2565 2566 DLprime[0][0]=DL_scalar*vx; 2567 DLprime[1][1]=DL_scalar*vy; 2568 2569 //Do the triple product tL*D*L. 2570 TripleMultiply( &B[0][0],2,numdof,1, 2571 &DLprime[0][0],2,2,0, 2572 &Bprime[0][0],2,numdof,0, 2573 &Ke_gg2[0][0],0); 2574 2575 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 2576 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j]; 2577 2578 } // for (ig=0; ig<num_gauss; ig++) 2579 2580 /*Add Ke_gg to global matrix Kgg: */ 2581 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 2582 2583 cleanup_and_return: 2584 xfree((void**)&first_gauss_area_coord); 2585 xfree((void**)&second_gauss_area_coord); 2586 xfree((void**)&third_gauss_area_coord); 2587 xfree((void**)&gauss_weights); 2588 2589 } 2590 /*}}}*/ 2591 /*FUNCTION Tria::CreateKMatrixBalancedvelocities {{{1*/ 2592 void Tria::CreateKMatrixBalancedvelocities(Mat Kgg){ 2593 2594 /* local declarations */ 2595 int i,j; 2596 2597 /* node data: */ 2598 const int numgrids=3; 2599 const int NDOF1=1; 2600 const int numdof=NDOF1*numgrids; 2601 double xyz_list[numgrids][3]; 2602 int doflist[numdof]; 2603 int numberofdofspernode; 2604 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 2605 2606 /* gaussian points: */ 2607 int num_gauss,ig; 2608 double* first_gauss_area_coord = NULL; 2609 double* second_gauss_area_coord = NULL; 2610 double* third_gauss_area_coord = NULL; 2611 double* gauss_weights = NULL; 2612 double gauss_weight; 2613 double gauss_l1l2l3[3]; 2614 2615 /* matrices: */ 2616 double L[numgrids]; 2617 double B[2][numgrids]; 2618 double Bprime[2][numgrids]; 2619 double DL[2][2]={0.0}; 2620 double DLprime[2][2]={0.0}; 2621 double DL_scalar; 2622 double Ke_gg[numdof][numdof]={0.0};//local element stiffness matrix 2623 double Ke_gg_gaussian[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2624 double Ke_gg_velocities1[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2625 double Ke_gg_velocities2[numdof][numdof]={0.0}; //stiffness matrix evaluated at the gaussian point. 2626 double Jdettria; 2627 2628 /*input parameters for structural analysis (diagnostic): */ 2629 double surface_normal[3]; 2630 double surface_list[3]; 2631 double nx,ny,norm; 2632 double dvx[2]; 2633 double dvy[2]; 2634 double vx,vy; 2635 double dvxdx,dvydy; 2636 double v_gauss[2]={0.0}; 2637 double K[2][2]={0.0}; 2638 double KDL[2][2]={0.0}; 2639 int dofs[2]={0,1}; 2640 int found=0; 2641 2642 /*parameters: */ 2643 bool artdiff; 2644 2645 /*retrieve some parameters: */ 2646 this->parameters->FindParam(&artdiff,ArtDiffEnum); 2647 2648 /* Get node coordinates and dof list: */ 2649 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2650 GetDofList(&doflist[0],&numberofdofspernode); 2651 2652 /*Modify z so that it reflects the surface*/ 2653 inputs->GetParameterValues(&surface_list[0],&gaussgrids[0][0],3,SurfaceEnum); 2654 for(i=0;i<numgrids;i++) xyz_list[i][2]=surface_list[i]; 2655 2656 /*Get normal vector to the surface*/ 2657 inputs->GetParameterAverage(&nx,VxAverageEnum); 2658 inputs->GetParameterAverage(&ny,VyAverageEnum); 2659 if(nx==0 && ny==0){ 2660 SurfaceNormal(&surface_normal[0],xyz_list); 2661 nx=surface_normal[0]; 2662 ny=surface_normal[1]; 2663 } 2664 if(nx==0 && ny==0){ 2665 nx=0; 2666 ny=1; 2667 } 2668 norm=pow( pow(nx,2)+pow(ny,2) , (double).5); 2669 nx=nx/norm; 2670 ny=ny/norm; 2671 2672 //Create Artificial diffusivity once for all if requested 2673 if(artdiff){ 2674 //Get the Jacobian determinant 2675 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD; 2676 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 2677 2678 //Build K matrix (artificial diffusivity matrix) 2679 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum); 2680 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum); 2681 2682 K[0][0]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]); //pow should be zero!! 2683 K[1][1]=pow(10,2)*pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]); 2684 } 2685 2686 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2687 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 2688 2689 /* Start looping on the number of gaussian points: */ 2690 for (ig=0; ig<num_gauss; ig++){ 2691 /*Pick up the gaussian point: */ 2692 gauss_weight=*(gauss_weights+ig); 2693 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 2694 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 2695 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 2696 2697 /* Get Jacobian determinant: */ 2698 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 2699 2700 /*Get B and B prime matrix: */ 2701 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 2702 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 2703 2704 //Get vx, vy and their derivatives at gauss point 2705 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum); 2706 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum); 2707 2708 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum); 2709 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum); 2710 2711 dvxdx=dvx[0]; 2712 dvydy=dvy[1]; 2713 2714 DL_scalar=gauss_weight*Jdettria; 2715 2716 DLprime[0][0]=DL_scalar*nx; 2717 DLprime[1][1]=DL_scalar*ny; 2718 2719 //Do the triple product tL*D*L. 2720 //Ke_gg_velocities=B'*DLprime*Bprime; 2721 TripleMultiply( &B[0][0],2,numdof,1, 2722 &DLprime[0][0],2,2,0, 2723 &Bprime[0][0],2,numdof,0, 2724 &Ke_gg_velocities2[0][0],0); 2725 2726 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 2727 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_velocities2[i][j]; 2728 2729 if(artdiff){ 2730 2731 /* Compute artificial diffusivity */ 2732 KDL[0][0]=DL_scalar*K[0][0]; 2733 KDL[1][1]=DL_scalar*K[1][1]; 2734 2735 TripleMultiply( &Bprime[0][0],2,numdof,1, 2736 &KDL[0][0],2,2,0, 2737 &Bprime[0][0],2,numdof,0, 2738 &Ke_gg_gaussian[0][0],0); 2739 2740 /* Add artificial diffusivity matrix */ 2741 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 2742 2743 } 2744 2745 } // for (ig=0; ig<num_gauss; ig++) 2746 2747 /*Add Ke_gg to global matrix Kgg: */ 2748 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 2749 2750 2751 cleanup_and_return: 2752 xfree((void**)&first_gauss_area_coord); 2753 xfree((void**)&second_gauss_area_coord); 2754 xfree((void**)&third_gauss_area_coord); 2755 xfree((void**)&gauss_weights); 2756 2757 } 2758 /*}}}*/ 2759 /*FUNCTION Tria::CreateKMatrixDiagnosticHoriz {{{1*/ 2760 void Tria::CreateKMatrixDiagnosticHoriz(Mat Kgg){ 2761 2762 /* local declarations */ 2763 int i,j; 2764 2765 /* node data: */ 2766 const int numgrids=3; 2767 const int numdof=2*numgrids; 2768 double xyz_list[numgrids][3]; 2769 int doflist[numdof]; 2770 int numberofdofspernode; 2771 2772 /* gaussian points: */ 2773 int num_gauss,ig; 2774 double* first_gauss_area_coord = NULL; 2775 double* second_gauss_area_coord = NULL; 2776 double* third_gauss_area_coord = NULL; 2777 double* gauss_weights = NULL; 2778 double gauss_weight; 2779 double gauss_l1l2l3[3]; 2780 2781 /* material data: */ 2782 double viscosity; //viscosity 2783 double newviscosity; //viscosity 2784 double oldviscosity; //viscosity 2785 2786 /* strain rate: */ 2787 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/ 2788 double oldepsilon[3]; /* oldepsilon=[exx,eyy,exy];*/ 2789 2790 /* matrices: */ 2791 double B[3][numdof]; 2792 double Bprime[3][numdof]; 2793 double D[3][3]={0.0}; // material matrix, simple scalar matrix. 2794 double D_scalar; 2795 2796 /*parameters: */ 2797 double viscosity_overshoot; 2798 2799 /* local element matrices: */ 2800 double Ke_gg[numdof][numdof]={0.0}; 2801 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point. 2802 2803 double Jdet; 2804 2805 /*input parameters for structural analysis (diagnostic): */ 2806 double thickness; 2807 int dofs[2]={0,1}; 2808 2809 /*inputs: */ 2810 bool onwater,shelf; 2811 2812 /*retrieve inputs :*/ 2813 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 2814 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum); 2815 2816 /*retrieve some parameters: */ 2817 this->parameters->FindParam(&viscosity_overshoot,ViscosityOvershootEnum); 2818 2819 /*First, if we are on water, return empty matrix: */ 2820 if(onwater) return; 2821 2822 /* Get node coordinates and dof list: */ 2823 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2824 GetDofList(&doflist[0],&numberofdofspernode); 2825 2826 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2827 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 2828 2829 /* Start looping on the number of gaussian points: */ 2830 for (ig=0; ig<num_gauss; ig++){ 2831 /*Pick up the gaussian point: */ 2832 gauss_weight=*(gauss_weights+ig); 2833 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 2834 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 2835 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 2836 2837 2838 /*Compute thickness at gaussian point: */ 2839 inputs->GetParameterValue(&thickness, gauss_l1l2l3,ThicknessEnum); 2840 2841 /*Get strain rate from velocity: */ 2842 inputs->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxEnum,VyEnum); 2843 inputs->GetStrainRate2d(&oldepsilon[0],&xyz_list[0][0],gauss_l1l2l3,VxOldEnum,VyOldEnum); 2844 2845 /*Get viscosity: */ 2846 matice->GetViscosity2d(&viscosity, &epsilon[0]); 2847 matice->GetViscosity2d(&oldviscosity, &oldepsilon[0]); 2848 2849 /* Get Jacobian determinant: */ 2850 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 2851 2852 /* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 2853 onto this scalar matrix, so that we win some computational time: */ 2854 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity); 2855 D_scalar=newviscosity*thickness*gauss_weight*Jdet; 2856 2857 for (i=0;i<3;i++){ 2858 D[i][i]=D_scalar; 2859 } 2860 2861 /*Get B and Bprime matrices: */ 2862 GetB(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 2863 GetBPrime(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 2864 2865 /* Do the triple product tB*D*Bprime: */ 2866 TripleMultiply( &B[0][0],3,numdof,1, 2867 &D[0][0],3,3,0, 2868 &Bprime[0][0],3,numdof,0, 2869 &Ke_gg_gaussian[0][0],0); 2870 2871 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 2872 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 2873 2874 } // for (ig=0; ig<num_gauss; ig++) 2875 2876 /*Add Ke_gg to global matrix Kgg: */ 2877 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 2878 2879 /*Do not forget to include friction: */ 2880 if(!shelf){ 2881 CreateKMatrixDiagnosticHorizFriction(Kgg); 2882 } 2883 2884 cleanup_and_return: 2885 xfree((void**)&first_gauss_area_coord); 2886 xfree((void**)&second_gauss_area_coord); 2887 xfree((void**)&third_gauss_area_coord); 2888 xfree((void**)&gauss_weights); 2889 2890 } 2891 /*}}}*/ 2892 /*FUNCTION Tria::CreateKMatrixDiagnosticHorizFriction {{{1*/ 2893 void Tria::CreateKMatrixDiagnosticHorizFriction(Mat Kgg){ 2894 2895 2896 /* local declarations */ 2897 int i,j; 2898 int analysis_type; 2899 2900 /* node data: */ 2901 const int numgrids=3; 2902 const int numdof=2*numgrids; 2903 double xyz_list[numgrids][3]; 2904 int doflist[numdof]; 2905 int numberofdofspernode; 2906 2907 /* gaussian points: */ 2908 int num_gauss,ig; 2909 double* first_gauss_area_coord = NULL; 2910 double* second_gauss_area_coord = NULL; 2911 double* third_gauss_area_coord = NULL; 2912 double* gauss_weights = NULL; 2913 double gauss_weight; 2914 double gauss_l1l2l3[3]; 2915 2916 /* matrices: */ 2917 double L[2][numdof]; 2918 double DL[2][2]={{ 0,0 },{0,0}}; //for basal drag 2919 double DL_scalar; 2920 2921 /* local element matrices: */ 2922 double Ke_gg[numdof][numdof]={0.0}; 2923 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag 2924 2925 double Jdet; 2926 2927 /*slope: */ 2928 double slope[2]={0.0,0.0}; 2929 double slope_magnitude; 2930 2931 /*friction: */ 2932 Friction* friction=NULL; 2933 double alpha2; 2934 2935 double MAXSLOPE=.06; // 6 % 2936 double MOUNTAINKEXPONENT=10; 2937 2938 /*inputs: */ 2939 bool shelf; 2940 int drag_type; 2941 2942 /*retrive parameters: */ 2943 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 2944 2945 /*retrieve inputs :*/ 2946 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum); 2947 inputs->GetParameterValue(&drag_type,DragTypeEnum); 2948 2949 /* Get node coordinates and dof list: */ 2950 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 2951 GetDofList(&doflist[0],&numberofdofspernode); 2952 2953 if (shelf){ 2954 /*no friction, do nothing*/ 2955 return; 2956 } 2957 2958 /*build friction object, used later on: */ 2959 if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!"); 2960 friction=new Friction("2d",inputs,matpar,analysis_type); 2961 2962 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2963 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 2964 2965 /* Start looping on the number of gaussian points: */ 2966 for (ig=0; ig<num_gauss; ig++){ 2967 /*Pick up the gaussian point: */ 2968 gauss_weight=*(gauss_weights+ig); 2969 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 2970 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 2971 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 2972 2973 /*Friction: */ 2974 friction->GetAlpha2(&alpha2, gauss_l1l2l3,VxEnum,VyEnum,VzEnum); 2975 2976 // If we have a slope > 6% for this element, it means we are on a mountain. In this particular case, 2977 //velocity should be = 0. To achieve this result, we set alpha2_list to a very high value: */ 2978 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum); 2979 slope_magnitude=sqrt(pow(slope[0],2)+pow(slope[1],2)); 2980 2981 if (slope_magnitude>MAXSLOPE){ 2982 alpha2=pow((double)10,MOUNTAINKEXPONENT); 2983 } 2984 2985 /* Get Jacobian determinant: */ 2986 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 2987 2988 /*Get L matrix: */ 2989 GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 2990 2991 2992 DL_scalar=alpha2*gauss_weight*Jdet; 2993 for (i=0;i<2;i++){ 2994 DL[i][i]=DL_scalar; 2995 } 2996 2997 /* Do the triple producte tL*D*L: */ 2998 TripleMultiply( &L[0][0],2,numdof,1, 2999 &DL[0][0],2,2,0, 3000 &L[0][0],2,numdof,0, 3001 &Ke_gg_gaussian[0][0],0); 3002 3003 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 3004 3005 } // for (ig=0; ig<num_gauss; ig++) 3006 3007 /*Add Ke_gg to global matrix Kgg: */ 3008 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 3009 3010 cleanup_and_return: 3011 xfree((void**)&first_gauss_area_coord); 3012 xfree((void**)&second_gauss_area_coord); 3013 xfree((void**)&third_gauss_area_coord); 3014 xfree((void**)&gauss_weights); 3015 delete friction; 3016 3017 } 3018 /*}}}*/ 3019 /*FUNCTION Tria::CreateKMatrixDiagnosticHutter{{{1*/ 3020 void Tria::CreateKMatrixDiagnosticHutter(Mat Kgg){ 3021 3022 /*Collapsed formulation: */ 3023 Sing* sing=NULL; 3024 int i; 3025 3026 /*flags: */ 3027 bool onwater; 3028 3029 /*recover some inputs: */ 3030 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 3031 3032 /*If on water, skip: */ 3033 if(onwater)return; 3034 3035 /*Spawn 3 sing elements: */ 3036 for(i=0;i<3;i++){ 3037 sing=(Sing*)SpawnSing(i); 3038 sing->CreateKMatrix(Kgg); 3039 } 3040 3041 /*clean up*/ 3042 delete sing; 3043 3044 } 3045 /*}}}*/ 3046 /*FUNCTION Tria::CreateKMatrixDiagnosticSurfaceVert {{{1*/ 3047 void Tria::CreateKMatrixDiagnosticSurfaceVert(Mat Kgg){ 3048 3049 int i,j; 3050 3051 /* node data: */ 3052 const int numgrids=3; 3053 const int NDOF1=1; 3054 const int numdof=NDOF1*numgrids; 3055 double xyz_list[numgrids][3]; 3056 int doflist[numdof]; 3057 int numberofdofspernode; 3058 3059 /* gaussian points: */ 3060 int num_gauss,ig; 3061 double* first_gauss_area_coord = NULL; 3062 double* second_gauss_area_coord = NULL; 3063 double* third_gauss_area_coord = NULL; 3064 double* gauss_weights = NULL; 3065 double gauss_weight; 3066 double gauss_l1l2l3[3]; 3067 3068 3069 /* surface normal: */ 3070 double x4,y4,z4; 3071 double x5,y5,z5; 3072 double x6,y6,z6; 3073 double v46[3]; 3074 double v56[3]; 3075 double normal[3]; 3076 double norm_normal; 3077 double nz; 3078 3079 /*Matrices: */ 3080 double DL_scalar; 3081 double L[3]; 3082 double Jdet; 3083 3084 /* local element matrices: */ 3085 double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix 3086 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point. 3087 3088 /* Get node coordinates and dof list: */ 3089 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3090 GetDofList(&doflist[0],&numberofdofspernode); 3091 3092 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3093 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3094 3095 /*Build normal vector to the surface:*/ 3096 3097 x4=xyz_list[0][0]; 3098 y4=xyz_list[0][1]; 3099 z4=xyz_list[0][2]; 3100 3101 x5=xyz_list[1][0]; 3102 y5=xyz_list[1][1]; 3103 z5=xyz_list[1][2]; 3104 3105 x6=xyz_list[2][0]; 3106 y6=xyz_list[2][1]; 3107 z6=xyz_list[2][2]; 3108 3109 v46[0]=x4-x6; 3110 v46[1]=y4-y6; 3111 v46[2]=z4-z6; 3112 3113 v56[0]=x5-x6; 3114 v56[1]=y5-y6; 3115 v56[2]=z5-z6; 3116 3117 normal[0]=(y4-y6)*(z5-z6)-(z4-z6)*(y5-y6); 3118 normal[1]=(z4-z6)*(x5-x6)-(x4-x6)*(z5-z6); 3119 normal[2]=(x4-x6)*(y5-y6)-(y4-y6)*(x5-x6); 3120 3121 norm_normal=sqrt(pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2)); 3122 nz=1.0/norm_normal*normal[2]; 3123 3124 /* Start looping on the number of gaussian points: */ 3125 for (ig=0; ig<num_gauss; ig++){ 3126 /*Pick up the gaussian point: */ 3127 gauss_weight=*(gauss_weights+ig); 3128 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3129 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3130 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3131 3132 /* Get Jacobian determinant: */ 3133 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 3134 3135 //Get L matrix if viscous basal drag present: 3136 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1); 3137 3138 /**********************Do not forget the sign**********************************/ 3139 DL_scalar=- gauss_weight*Jdet*nz; 3140 /******************************************************************************/ 3141 3142 /* Do the triple producte tL*D*L: */ 3143 TripleMultiply( L,1,3,1, 3144 &DL_scalar,1,1,0, 3145 L,1,3,0, 3146 &Ke_gg_gaussian[0][0],0); 3147 3148 /* Add the Ke_gg_gaussian, onto Ke_gg: */ 3149 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 3150 3151 3152 } //for (ig=0; ig<num_gauss; ig++) 3153 3154 /*Add Ke_gg to global matrix Kgg: */ 3155 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 3156 3157 cleanup_and_return: 3158 xfree((void**)&first_gauss_area_coord); 3159 xfree((void**)&second_gauss_area_coord); 3160 xfree((void**)&third_gauss_area_coord); 3161 xfree((void**)&gauss_weights); 3162 } 3163 /*}}}*/ 3164 /*FUNCTION Tria::CreateKMatrixMelting {{{1*/ 3165 void Tria::CreateKMatrixMelting(Mat Kgg){ 3166 3167 /*indexing: */ 3168 int i,j; 3169 3170 const int numgrids=3; 3171 const int NDOF1=1; 3172 const int numdof=numgrids*NDOF1; 3173 int doflist[numdof]; 3174 int numberofdofspernode; 3175 3176 /*Grid data: */ 3177 double xyz_list[numgrids][3]; 3178 3179 /*Material constants */ 3180 double heatcapacity,latentheat; 3181 3182 /* gaussian points: */ 3183 int num_area_gauss,ig; 3184 double* gauss_weights = NULL; 3185 double* first_gauss_area_coord = NULL; 3186 double* second_gauss_area_coord = NULL; 3187 double* third_gauss_area_coord = NULL; 3188 double gauss_weight; 3189 double gauss_coord[3]; 3190 3191 /*matrices: */ 3192 double Jdet; 3193 double D_scalar; 3194 double K_terms[numdof][numdof]={0.0}; 3195 double L[3]; 3196 double tLD[3]; 3197 double Ke_gaussian[numdof][numdof]={0.0}; 3198 3199 /*Recover constants of ice */ 3200 latentheat=matpar->GetLatentHeat(); 3201 heatcapacity=matpar->GetHeatCapacity(); 3202 3203 /* Get node coordinates and dof list: */ 3204 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3205 GetDofList(&doflist[0],&numberofdofspernode); 3206 3207 /* Get gaussian points and weights: */ 3208 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3209 3210 /* Start looping on the number of gauss (nodes on the bedrock) */ 3211 for (ig=0; ig<num_area_gauss; ig++){ 3212 gauss_weight=*(gauss_weights+ig); 3213 gauss_coord[0]=*(first_gauss_area_coord+ig); 3214 gauss_coord[1]=*(second_gauss_area_coord+ig); 3215 gauss_coord[2]=*(third_gauss_area_coord+ig); 3216 3217 //Get the Jacobian determinant 3218 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord); 3219 3220 /*Get L matrix : */ 3221 GetL(&L[0], &xyz_list[0][0], gauss_coord,NDOF1); 3222 3223 /*Calculate DL on gauss point */ 3224 D_scalar=latentheat/heatcapacity*gauss_weight*Jdet; 3225 3226 /* Do the triple product tL*D*L: */ 3227 MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0); 3228 MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian[0][0],0); 3229 3230 for(i=0;i<numgrids;i++){ 3231 for(j=0;j<numgrids;j++){ 3232 K_terms[i][j]+=Ke_gaussian[i][j]; 3233 } 3234 } 3235 } 3236 3237 /*Add Ke_gg to global matrix Kgg: */ 3238 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 3239 3240 cleanup_and_return: 3241 xfree((void**)&first_gauss_area_coord); 3242 xfree((void**)&second_gauss_area_coord); 3243 xfree((void**)&third_gauss_area_coord); 3244 xfree((void**)&gauss_weights); 3245 3246 } 3247 /*}}}*/ 3248 /*FUNCTION Tria::CreateKMatrixPrognostic {{{1*/ 3249 void Tria::CreateKMatrixPrognostic(Mat Kgg){ 3250 3251 /* local declarations */ 3252 int i,j; 3253 3254 /* node data: */ 3255 const int numgrids=3; 3256 const int NDOF1=1; 3257 const int numdof=NDOF1*numgrids; 3258 double xyz_list[numgrids][3]; 3259 int doflist[numdof]; 3260 int numberofdofspernode; 3261 3262 /* gaussian points: */ 3263 int num_gauss,ig; 3264 double* first_gauss_area_coord = NULL; 3265 double* second_gauss_area_coord = NULL; 3266 double* third_gauss_area_coord = NULL; 3267 double* gauss_weights = NULL; 3268 double gauss_weight; 3269 double gauss_l1l2l3[3]; 3270 3271 /* matrices: */ 3272 double L[numgrids]; 3273 double B[2][numgrids]; 3274 double Bprime[2][numgrids]; 3275 double DL[2][2]={0.0}; 3276 double DLprime[2][2]={0.0}; 3277 double DL_scalar; 3278 double Ke_gg[numdof][numdof]={0.0}; 3279 double Ke_gg_gaussian[numdof][numdof]={0.0}; 3280 double Ke_gg_thickness1[numdof][numdof]={0.0}; 3281 double Ke_gg_thickness2[numdof][numdof]={0.0}; 3282 double Jdettria; 3283 3284 /*input parameters for structural analysis (diagnostic): */ 3285 double dvx[2]; 3286 double dvy[2]; 3287 double vx,vy; 3288 double dvxdx,dvydy; 3289 double v_gauss[2]={0.0}; 3290 double K[2][2]={0.0}; 3291 double KDL[2][2]={0.0}; 3292 int dofs[2]={0,1}; 3293 int found; 3294 3295 /*parameters: */ 3296 double dt; 3297 bool artdiff; 3298 3299 /*retrieve some parameters: */ 3300 this->parameters->FindParam(&dt,DtEnum); 3301 this->parameters->FindParam(&artdiff,ArtDiffEnum); 3302 3303 /* Get node coordinates and dof list: */ 3304 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3305 GetDofList(&doflist[0],&numberofdofspernode); 3306 3307 //Create Artificial diffusivity once for all if requested 3308 if(artdiff){ 3309 //Get the Jacobian determinant 3310 gauss_l1l2l3[0]=ONETHIRD; gauss_l1l2l3[1]=ONETHIRD; gauss_l1l2l3[2]=ONETHIRD; 3311 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3312 3313 //Build K matrix (artificial diffusivity matrix) 3314 inputs->GetParameterAverage(&v_gauss[0],VxAverageEnum); 3315 inputs->GetParameterAverage(&v_gauss[1],VyAverageEnum); 3316 3317 K[0][0]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[0]); 3318 K[1][1]=pow(Jdettria,(double).5)/2.0*fabs(v_gauss[1]); 3319 } 3320 3321 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3322 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3323 3324 /* Start looping on the number of gaussian points: */ 3325 for (ig=0; ig<num_gauss; ig++){ 3326 3327 /*Pick up the gaussian point: */ 3328 gauss_weight=*(gauss_weights+ig); 3329 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3330 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3331 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3332 3333 /* Get Jacobian determinant: */ 3334 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3335 3336 /*Get L matrix: */ 3337 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 3338 3339 DL_scalar=gauss_weight*Jdettria; 3340 3341 /* Do the triple product tL*D*L: */ 3342 TripleMultiply( &L[0],1,numdof,1, 3343 &DL_scalar,1,1,0, 3344 &L[0],1,numdof,0, 3345 &Ke_gg_gaussian[0][0],0); 3346 3347 /*Get B and B prime matrix: */ 3348 GetB_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 3349 GetBPrime_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 3350 3351 //Get vx, vy and their derivatives at gauss point 3352 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum); 3353 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum); 3354 3355 inputs->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],&gauss_l1l2l3[0],VxAverageEnum); 3356 inputs->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],&gauss_l1l2l3[0],VyAverageEnum); 3357 3358 dvxdx=dvx[0]; 3359 dvydy=dvy[1]; 3360 3361 DL_scalar=dt*gauss_weight*Jdettria; 3362 3363 //Create DL and DLprime matrix 3364 DL[0][0]=DL_scalar*dvxdx; 3365 DL[1][1]=DL_scalar*dvydy; 3366 3367 DLprime[0][0]=DL_scalar*vx; 3368 DLprime[1][1]=DL_scalar*vy; 3369 3370 //Do the triple product tL*D*L. 3371 //Ke_gg_thickness=B'*DL*B+B'*DLprime*Bprime; 3372 3373 TripleMultiply( &B[0][0],2,numdof,1, 3374 &DL[0][0],2,2,0, 3375 &B[0][0],2,numdof,0, 3376 &Ke_gg_thickness1[0][0],0); 3377 3378 TripleMultiply( &B[0][0],2,numdof,1, 3379 &DLprime[0][0],2,2,0, 3380 &Bprime[0][0],2,numdof,0, 3381 &Ke_gg_thickness2[0][0],0); 3382 3383 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 3384 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 3385 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness1[i][j]; 3386 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_thickness2[i][j]; 3387 3388 if(artdiff){ 3389 3390 /* Compute artificial diffusivity */ 3391 KDL[0][0]=DL_scalar*K[0][0]; 3392 KDL[1][1]=DL_scalar*K[1][1]; 3393 3394 TripleMultiply( &Bprime[0][0],2,numdof,1, 3395 &KDL[0][0],2,2,0, 3396 &Bprime[0][0],2,numdof,0, 3397 &Ke_gg_gaussian[0][0],0); 3398 3399 /* Add artificial diffusivity matrix */ 3400 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 3401 3402 } 3403 3404 } // for (ig=0; ig<num_gauss; ig++) 3405 3406 /*Add Ke_gg to global matrix Kgg: */ 3407 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 3408 3409 3410 cleanup_and_return: 3411 xfree((void**)&first_gauss_area_coord); 3412 xfree((void**)&second_gauss_area_coord); 3413 xfree((void**)&third_gauss_area_coord); 3414 xfree((void**)&gauss_weights); 3415 3416 } 3417 /*}}}*/ 3418 /*FUNCTION Tria::CreateKMatrixPrognostic2 {{{1*/ 3419 void Tria::CreateKMatrixPrognostic2(Mat Kgg){ 3420 3421 /* local declarations */ 3422 int i,j; 3423 3424 /* node data: */ 3425 const int numgrids=3; 3426 const int NDOF1=1; 3427 const int numdof=NDOF1*numgrids; 3428 double xyz_list[numgrids][3]; 3429 int doflist[numdof]; 3430 int numberofdofspernode; 3431 3432 /* gaussian points: */ 3433 int num_gauss,ig; 3434 double* first_gauss_area_coord = NULL; 3435 double* second_gauss_area_coord = NULL; 3436 double* third_gauss_area_coord = NULL; 3437 double* gauss_weights = NULL; 3438 double gauss_weight; 3439 double gauss_l1l2l3[3]; 3440 3441 /* matrices: */ 3442 double L[numgrids]; 3443 double B[2][numgrids]; 3444 double Bprime[2][numgrids]; 3445 double DL[2][2]={0.0}; 3446 double DLprime[2][2]={0.0}; 3447 double DL_scalar; 3448 double Ke_gg[numdof][numdof]={0.0}; 3449 double Ke_gg1[numdof][numdof]={0.0}; 3450 double Ke_gg2[numdof][numdof]={0.0}; 3451 double Jdettria; 3452 3453 /*input parameters for structural analysis (diagnostic): */ 3454 double vx,vy; 3455 int dofs[1]={0}; 3456 int found; 3457 3458 /*parameters: */ 3459 double dt; 3460 3461 /*retrieve some parameters: */ 3462 this->parameters->FindParam(&dt,DtEnum); 3463 3464 /* Get node coordinates and dof list: */ 3465 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3466 GetDofList(&doflist[0],&numberofdofspernode); 3467 3468 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3469 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3470 3471 /* Start looping on the number of gaussian points: */ 3472 for (ig=0; ig<num_gauss; ig++){ 3473 3474 /*Pick up the gaussian point: */ 3475 gauss_weight=*(gauss_weights+ig); 3476 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3477 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3478 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3479 3480 /* Get Jacobian determinant: */ 3481 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3482 3483 /*Get L matrix: */ 3484 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 3485 3486 DL_scalar=gauss_weight*Jdettria; 3487 3488 /* Do the triple product tL*D*L: */ 3489 TripleMultiply( &L[0],1,numdof,1, 3490 &DL_scalar,1,1,0, 3491 &L[0],1,numdof,0, 3492 &Ke_gg1[0][0],0); 3493 3494 /*Get B and B prime matrix: */ 3495 /*WARNING: B and Bprime are inverted compared to usual prognostic!!!!*/ 3496 GetB_prog(&Bprime[0][0], &xyz_list[0][0], gauss_l1l2l3); 3497 GetBPrime_prog(&B[0][0], &xyz_list[0][0], gauss_l1l2l3); 3498 3499 //Get vx, vy and their derivatives at gauss point 3500 inputs->GetParameterValue(&vx,&gauss_l1l2l3[0],VxAverageEnum); 3501 inputs->GetParameterValue(&vy,&gauss_l1l2l3[0],VyAverageEnum); 3502 3503 DL_scalar=-dt*gauss_weight*Jdettria; 3504 3505 DLprime[0][0]=DL_scalar*vx; 3506 DLprime[1][1]=DL_scalar*vy; 3507 3508 //Do the triple product tL*D*L. 3509 TripleMultiply( &B[0][0],2,numdof,1, 3510 &DLprime[0][0],2,2,0, 3511 &Bprime[0][0],2,numdof,0, 3512 &Ke_gg2[0][0],0); 3513 3514 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 3515 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg1[i][j]; 3516 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg2[i][j]; 3517 3518 } // for (ig=0; ig<num_gauss; ig++) 3519 3520 /*Add Ke_gg to global matrix Kgg: */ 3521 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 3522 3523 3524 cleanup_and_return: 3525 xfree((void**)&first_gauss_area_coord); 3526 xfree((void**)&second_gauss_area_coord); 3527 xfree((void**)&third_gauss_area_coord); 3528 xfree((void**)&gauss_weights); 3529 3530 } 3531 /*}}}*/ 3532 /*FUNCTION Tria::CreateKMatrixSlopeCompute {{{1*/ 3533 3534 void Tria::CreateKMatrixSlopeCompute(Mat Kgg){ 3535 3536 /* local declarations */ 3537 int i,j; 3538 3539 /* node data: */ 3540 const int numgrids=3; 3541 const int NDOF1=1; 3542 const int numdof=NDOF1*numgrids; 3543 double xyz_list[numgrids][3]; 3544 int doflist[numdof]; 3545 int numberofdofspernode; 3546 3547 /* gaussian points: */ 3548 int num_gauss,ig; 3549 double* first_gauss_area_coord = NULL; 3550 double* second_gauss_area_coord = NULL; 3551 double* third_gauss_area_coord = NULL; 3552 double* gauss_weights = NULL; 3553 double gauss_weight; 3554 double gauss_l1l2l3[3]; 3555 3556 /* matrices: */ 3557 double L[1][3]; 3558 double DL_scalar; 3559 3560 /* local element matrices: */ 3561 double Ke_gg[numdof][numdof]={0.0}; //local element stiffness matrix 3562 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point. 3563 3564 double Jdet; 3565 3566 /* Get node coordinates and dof list: */ 3567 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3568 GetDofList(&doflist[0],&numberofdofspernode); 3569 3570 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3571 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3572 3573 /* Start looping on the number of gaussian points: */ 3574 for (ig=0; ig<num_gauss; ig++){ 3575 /*Pick up the gaussian point: */ 3576 gauss_weight=*(gauss_weights+ig); 3577 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3578 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3579 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3580 3581 3582 /*Get L matrix: */ 3583 GetL(&L[0][0], &xyz_list[0][0], gauss_l1l2l3,NDOF1); 3584 3585 /* Get Jacobian determinant: */ 3586 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 3587 3588 DL_scalar=gauss_weight*Jdet; 3589 3590 /* Do the triple producte tL*D*L: */ 3591 TripleMultiply( &L[0][0],1,3,1, 3592 &DL_scalar,1,1,0, 3593 &L[0][0],1,3,0, 3594 &Ke_gg_gaussian[0][0],0); 3595 3596 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 3597 for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 3598 } //for (ig=0; ig<num_gauss; ig++ 3599 3600 /*Add Ke_gg to global matrix Kgg: */ 3601 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 3602 3603 cleanup_and_return: 3604 xfree((void**)&first_gauss_area_coord); 3605 xfree((void**)&second_gauss_area_coord); 3606 xfree((void**)&third_gauss_area_coord); 3607 xfree((void**)&gauss_weights); 3608 } 3609 /*}}}*/ 3610 /*FUNCTION Tria::CreateKMatrixThermal {{{1*/ 3611 void Tria::CreateKMatrixThermal(Mat Kgg){ 3612 3613 int i,j; 3614 int found=0; 3615 3616 /* node data: */ 3617 const int numgrids=3; 3618 const int NDOF1=1; 3619 const int numdof=NDOF1*numgrids; 3620 double xyz_list[numgrids][3]; 3621 int doflist[numdof]; 3622 int numberofdofspernode; 3623 3624 double mixed_layer_capacity; 3625 double thermal_exchange_velocity; 3626 double rho_water; 3627 double rho_ice; 3628 double heatcapacity; 3629 3630 int num_gauss,ig; 3631 double* first_gauss_area_coord = NULL; 3632 double* second_gauss_area_coord = NULL; 3633 double* third_gauss_area_coord = NULL; 3634 double* gauss_weights = NULL; 3635 double gauss_weight; 3636 double gauss_coord[3]; 3637 3638 /*matrices: */ 3639 double Jdet; 3640 double K_terms[numdof][numdof]={0.0}; 3641 double Ke_gaussian[numdof][numdof]={0.0}; 3642 double l1l2l3[numgrids]; 3643 double tl1l2l3D[3]; 3644 double D_scalar; 3645 3646 /*parameters: */ 3647 double dt; 3648 3649 /*retrieve some parameters: */ 3650 this->parameters->FindParam(&dt,DtEnum); 3651 3652 /* Get node coordinates and dof list: */ 3653 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3654 GetDofList(&doflist[0],&numberofdofspernode); 3655 3656 //recover material parameters 3657 mixed_layer_capacity=matpar->GetMixedLayerCapacity(); 3658 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity(); 3659 rho_water=matpar->GetRhoWater(); 3660 rho_ice=matpar->GetRhoIce(); 3661 heatcapacity=matpar->GetHeatCapacity(); 3662 3663 3664 GaussTria (&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3665 3666 /* Start looping on the number of gauss (nodes on the bedrock) */ 3667 for (ig=0; ig<num_gauss; ig++){ 3668 gauss_weight=*(gauss_weights+ig); 3669 gauss_coord[0]=*(first_gauss_area_coord+ig); 3670 gauss_coord[1]=*(second_gauss_area_coord+ig); 3671 gauss_coord[2]=*(third_gauss_area_coord+ig); 3672 3673 //Get the Jacobian determinant 3674 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord); 3675 3676 /*Get nodal functions values: */ 3677 GetNodalFunctions(&l1l2l3[0], gauss_coord); 3678 3679 /*Calculate DL on gauss point */ 3680 D_scalar=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice); 3681 if(dt){ 3682 D_scalar=dt*D_scalar; 3683 } 3684 3685 /* Do the triple product tL*D*L: */ 3686 MatrixMultiply(&l1l2l3[0],numdof,1,0,&D_scalar,1,1,0,&tl1l2l3D[0],0); 3687 MatrixMultiply(&tl1l2l3D[0],numdof,1,0,&l1l2l3[0],1,numdof,0,&Ke_gaussian[0][0],0); 3688 3689 for(i=0;i<3;i++){ 3690 for(j=0;j<3;j++){ 3691 K_terms[i][j]+=Ke_gaussian[i][j]; 3692 } 3693 } 3694 } 3695 3696 /*Add Ke_gg to global matrix Kgg: */ 3697 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 3698 3699 cleanup_and_return: 3700 xfree((void**)&first_gauss_area_coord); 3701 xfree((void**)&second_gauss_area_coord); 3702 xfree((void**)&third_gauss_area_coord); 3703 xfree((void**)&gauss_weights); 3704 3705 } 3706 /*}}}*/ 3707 /*FUNCTION Tria::CreatePVectorBalancedthickness {{{1*/ 3708 void Tria::CreatePVectorBalancedthickness(Vec pg ){ 3709 3710 3711 /* local declarations */ 3712 int i,j; 3713 3714 /* node data: */ 3715 const int numgrids=3; 3716 const int NDOF1=1; 3717 const int numdof=NDOF1*numgrids; 3718 double xyz_list[numgrids][3]; 3719 int doflist[numdof]; 3720 int numberofdofspernode; 3721 3722 /* gaussian points: */ 3723 int num_gauss,ig; 3724 double* first_gauss_area_coord = NULL; 3725 double* second_gauss_area_coord = NULL; 3726 double* third_gauss_area_coord = NULL; 3727 double* gauss_weights = NULL; 3728 double gauss_weight; 3729 double gauss_l1l2l3[3]; 3730 3731 /* matrix */ 3732 double pe_g[numgrids]={0.0}; 3733 double L[numgrids]; 3734 double Jdettria; 3735 3736 /*input parameters for structural analysis (diagnostic): */ 3737 double accumulation_g; 3738 double melting_g; 3739 3740 /* Get node coordinates and dof list: */ 3741 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3742 GetDofList(&doflist[0],&numberofdofspernode); 3743 3744 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3745 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3746 3747 /* Start looping on the number of gaussian points: */ 3748 for (ig=0; ig<num_gauss; ig++){ 3749 /*Pick up the gaussian point: */ 3750 gauss_weight=*(gauss_weights+ig); 3751 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3752 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3753 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3754 3755 /* Get Jacobian determinant: */ 3756 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3757 3758 /*Get L matrix: */ 3759 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 3760 3761 /* Get accumulation, melting at gauss point */ 3762 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum); 3763 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum); 3764 3765 /* Add value into pe_g: */ 3766 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i]; 3767 3768 } // for (ig=0; ig<num_gauss; ig++) 3769 3770 /*Add pe_g to global matrix Kgg: */ 3771 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 3772 3773 cleanup_and_return: 3774 xfree((void**)&first_gauss_area_coord); 3775 xfree((void**)&second_gauss_area_coord); 3776 xfree((void**)&third_gauss_area_coord); 3777 xfree((void**)&gauss_weights); 3778 3779 } 3780 /*}}}*/ 3781 /*FUNCTION Tria::CreatePVectorBalancedthickness2 {{{1*/ 3782 void Tria::CreatePVectorBalancedthickness2(Vec pg){ 3783 3784 3785 /* local declarations */ 3786 int i,j; 3787 3788 /* node data: */ 3789 const int numgrids=3; 3790 const int NDOF1=1; 3791 const int numdof=NDOF1*numgrids; 3792 double xyz_list[numgrids][3]; 3793 int doflist[numdof]; 3794 int numberofdofspernode; 3795 3796 /* gaussian points: */ 3797 int num_gauss,ig; 3798 double* first_gauss_area_coord = NULL; 3799 double* second_gauss_area_coord = NULL; 3800 double* third_gauss_area_coord = NULL; 3801 double* gauss_weights = NULL; 3802 double gauss_weight; 3803 double gauss_l1l2l3[3]; 3804 3805 /* matrix */ 3806 double pe_g[numgrids]={0.0}; 3807 double L[numgrids]; 3808 double Jdettria; 3809 3810 /*input parameters for structural analysis (diagnostic): */ 3811 double accumulation_g; 3812 double melting_g; 3813 double dhdt_g; 3814 3815 /* Get node coordinates and dof list: */ 3816 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3817 GetDofList(&doflist[0],&numberofdofspernode); 3818 3819 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3820 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3821 3822 /* Start looping on the number of gaussian points: */ 3823 for (ig=0; ig<num_gauss; ig++){ 3824 /*Pick up the gaussian point: */ 3825 gauss_weight=*(gauss_weights+ig); 3826 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3827 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3828 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3829 3830 /* Get Jacobian determinant: */ 3831 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3832 3833 /*Get L matrix: */ 3834 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 3835 3836 /* Get accumulation, melting and thickness at gauss point */ 3837 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum); 3838 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum); 3839 inputs->GetParameterValue(&dhdt_g, &gauss_l1l2l3[0],DhDtEnum); 3840 3841 /* Add value into pe_g: */ 3842 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g+dhdt_g)*L[i]; 3843 3844 } // for (ig=0; ig<num_gauss; ig++) 3845 3846 /*Add pe_g to global matrix Kgg: */ 3847 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 3848 3849 cleanup_and_return: 3850 xfree((void**)&first_gauss_area_coord); 3851 xfree((void**)&second_gauss_area_coord); 3852 xfree((void**)&third_gauss_area_coord); 3853 xfree((void**)&gauss_weights); 3854 3855 } 3856 /*}}}*/ 3857 /*FUNCTION Tria::CreatePVectorBalancedvelocities {{{1*/ 3858 void Tria::CreatePVectorBalancedvelocities(Vec pg){ 3859 3860 3861 /* local declarations */ 3862 int i,j; 3863 3864 /* node data: */ 3865 const int numgrids=3; 3866 const int NDOF1=1; 3867 const int numdof=NDOF1*numgrids; 3868 double xyz_list[numgrids][3]; 3869 int doflist[numdof]; 3870 int numberofdofspernode; 3871 3872 /* gaussian points: */ 3873 int num_gauss,ig; 3874 double* first_gauss_area_coord = NULL; 3875 double* second_gauss_area_coord = NULL; 3876 double* third_gauss_area_coord = NULL; 3877 double* gauss_weights = NULL; 3878 double gauss_weight; 3879 double gauss_l1l2l3[3]; 3880 3881 /* matrix */ 3882 double pe_g[numgrids]={0.0}; 3883 double L[numgrids]; 3884 double Jdettria; 3885 3886 /*input parameters for structural analysis (diagnostic): */ 3887 double accumulation_g; 3888 double melting_g; 3889 3890 /* Get node coordinates and dof list: */ 3891 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3892 GetDofList(&doflist[0],&numberofdofspernode); 3893 3894 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3895 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3896 3897 /* Start looping on the number of gaussian points: */ 3898 for (ig=0; ig<num_gauss; ig++){ 3899 /*Pick up the gaussian point: */ 3900 gauss_weight=*(gauss_weights+ig); 3901 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3902 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3903 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3904 3905 /* Get Jacobian determinant: */ 3906 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 3907 3908 /*Get L matrix: */ 3909 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 3910 3911 /* Get accumulation, melting at gauss point */ 3912 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum); 3913 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum); 3914 3915 /* Add value into pe_g: */ 3916 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(accumulation_g-melting_g)*L[i]; 3917 3918 } // for (ig=0; ig<num_gauss; ig++) 3919 3920 /*Add pe_g to global matrix Kgg: */ 3921 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 3922 3923 cleanup_and_return: 3924 xfree((void**)&first_gauss_area_coord); 3925 xfree((void**)&second_gauss_area_coord); 3926 xfree((void**)&third_gauss_area_coord); 3927 xfree((void**)&gauss_weights); 3928 3929 } 3930 /*}}}*/ 3931 /*FUNCTION Tria::CreatePVectorDiagnosticBaseVert {{{1*/ 3932 void Tria::CreatePVectorDiagnosticBaseVert(Vec pg){ 3933 3934 int i,j; 3935 3936 /* node data: */ 3937 const int numgrids=3; 3938 const int NDOF1=1; 3939 const int numdof=NDOF1*numgrids; 3940 double xyz_list[numgrids][3]; 3941 int doflist[numdof]; 3942 int numberofdofspernode; 3943 3944 /* gaussian points: */ 3945 int num_gauss,ig; 3946 double* first_gauss_area_coord = NULL; 3947 double* second_gauss_area_coord = NULL; 3948 double* third_gauss_area_coord = NULL; 3949 double* gauss_weights = NULL; 3950 double gauss_weight; 3951 double gauss_l1l2l3[3]; 3952 3953 /* Jacobian: */ 3954 double Jdet; 3955 3956 /*nodal functions: */ 3957 double l1l2l3[3]; 3958 3959 /*element vector at the gaussian points: */ 3960 double pe_g[numdof]={0.0}; 3961 double pe_g_gaussian[numdof]; 3962 3963 /* matrices: */ 3964 double L[numgrids]; 3965 3966 /*input parameters for structural analysis (diagnostic): */ 3967 double vx,vy; 3968 double meltingvalue; 3969 double slope[2]; 3970 double dbdx,dbdy; 3971 3972 /* Get node coordinates and dof list: */ 3973 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 3974 GetDofList(&doflist[0],&numberofdofspernode); 3975 3976 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 3977 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 3978 3979 /*For icesheets: */ 3980 /* Start looping on the number of gaussian points: */ 3981 for (ig=0; ig<num_gauss; ig++){ 3982 3983 /*Pick up the gaussian point: */ 3984 gauss_weight=*(gauss_weights+ig); 3985 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 3986 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 3987 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 3988 3989 /*Get melting at gaussian point: */ 3990 inputs->GetParameterValue(&meltingvalue, &gauss_l1l2l3[0],MeltingRateEnum); 3991 3992 /*Get velocity at gaussian point: */ 3993 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum); 3994 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum); 3995 3996 /*Get bed slope: */ 3997 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum); 3998 dbdx=slope[0]; 3999 dbdy=slope[1]; 4000 4001 /* Get Jacobian determinant: */ 4002 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 4003 4004 //Get L matrix if viscous basal drag present: 4005 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,NDOF1); 4006 4007 4008 /*Build gaussian vector: */ 4009 for(i=0;i<numgrids;i++){ 4010 pe_g_gaussian[i]=-Jdet*gauss_weight*(vx*dbdx+vy*dbdy-meltingvalue)*L[i]; 4011 } 4012 4013 /*Add pe_g_gaussian vector to pe_g: */ 4014 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i]; 4015 4016 } 4017 4018 /*Add pe_g to global vector pg: */ 4019 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 4020 4021 cleanup_and_return: 4022 xfree((void**)&first_gauss_area_coord); 4023 xfree((void**)&second_gauss_area_coord); 4024 xfree((void**)&third_gauss_area_coord); 4025 xfree((void**)&gauss_weights); 4026 4027 } 4028 /*}}}*/ 4029 /*FUNCTION Tria::CreatePVectorDiagnosticHoriz {{{1*/ 4030 void Tria::CreatePVectorDiagnosticHoriz( Vec pg){ 4031 4032 int i,j; 4033 4034 /* node data: */ 4035 const int numgrids=3; 4036 const int numdof=2*numgrids; 4037 const int NDOF2=2; 4038 double xyz_list[numgrids][3]; 4039 int doflist[numdof]; 4040 int numberofdofspernode; 4041 4042 /* parameters: */ 4043 double plastic_stress; 4044 double slope[NDOF2]; 4045 double driving_stress_baseline; 4046 4047 /* gaussian points: */ 4048 int num_gauss,ig; 4049 double* first_gauss_area_coord = NULL; 4050 double* second_gauss_area_coord = NULL; 4051 double* third_gauss_area_coord = NULL; 4052 double* gauss_weights = NULL; 4053 double gauss_weight; 4054 double gauss_l1l2l3[3]; 4055 4056 /* Jacobian: */ 4057 double Jdet; 4058 4059 /*nodal functions: */ 4060 double l1l2l3[3]; 4061 4062 /*element vector at the gaussian points: */ 4063 double pe_g[numdof]={0.0}; 4064 double pe_g_gaussian[numdof]; 4065 4066 /*input parameters for structural analysis (diagnostic): */ 4067 double thickness; 4068 4069 /*inputs: */ 4070 bool onwater; 4071 int drag_type; 4072 4073 /*retrieve inputs :*/ 4074 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 4075 inputs->GetParameterValue(&drag_type,DragTypeEnum); 4076 4077 /*First, if we are on water, return empty vector: */ 4078 if(onwater)return; 4079 4080 /* Get node coordinates and dof list: */ 4081 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4082 GetDofList(&doflist[0],&numberofdofspernode); 4083 4084 4085 /* Get gaussian points and weights: */ 4086 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/ 4087 4088 /* Start looping on the number of gaussian points: */ 4089 for (ig=0; ig<num_gauss; ig++){ 4090 /*Pick up the gaussian point: */ 4091 gauss_weight=*(gauss_weights+ig); 4092 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 4093 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 4094 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 4095 4096 /*Compute thickness at gaussian point: */ 4097 inputs->GetParameterValue(&thickness, &gauss_l1l2l3[0],ThicknessEnum); 4098 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum); 4099 4100 /*In case we have plastic basal drag, compute plastic stress at gaussian point from k1, k2 and k3 fields in the 4101 * element itself: */ 4102 if(drag_type==1){ 4103 inputs->GetParameterValue(&plastic_stress, &gauss_l1l2l3[0],DragCoefficientEnum); 4104 } 4105 4106 /* Get Jacobian determinant: */ 4107 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 4108 4109 /*Get nodal functions: */ 4110 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 4111 4112 /*Compute driving stress: */ 4113 driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG()*thickness; 4114 4115 /*Build pe_g_gaussian vector: */ 4116 if(drag_type==1){ 4117 for (i=0;i<numgrids;i++){ 4118 for (j=0;j<NDOF2;j++){ 4119 pe_g_gaussian[i*NDOF2+j]=(-driving_stress_baseline*slope[j]-plastic_stress)*Jdet*gauss_weight*l1l2l3[i]; 4120 } 4121 } 4122 } 4123 else { 4124 for (i=0;i<numgrids;i++){ 4125 for (j=0;j<NDOF2;j++){ 4126 pe_g_gaussian[i*NDOF2+j]=-driving_stress_baseline*slope[j]*Jdet*gauss_weight*l1l2l3[i]; 4127 } 4128 } 4129 } 4130 4131 /*Add pe_g_gaussian vector to pe_g: */ 4132 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i]; 4133 4134 } //for (ig=0; ig<num_gauss; ig++) 4135 4136 /*Add pe_g to global vector pg: */ 4137 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 4138 4139 cleanup_and_return: 4140 xfree((void**)&first_gauss_area_coord); 4141 xfree((void**)&second_gauss_area_coord); 4142 xfree((void**)&third_gauss_area_coord); 4143 xfree((void**)&gauss_weights); 4144 4145 } 4146 /*}}}*/ 4147 /*FUNCTION Tria::CreatePVectorDiagnosticHutter{{{1*/ 4148 void Tria::CreatePVectorDiagnosticHutter(Vec pg){ 4149 4150 /*Collapsed formulation: */ 4151 Sing* sing=NULL; 4152 int i; 4153 4154 /*flags: */ 4155 bool onwater; 4156 4157 /*recover some inputs: */ 4158 inputs->GetParameterValue(&onwater,ElementOnWaterEnum); 4159 4160 /*If on water, skip: */ 4161 if(onwater)return; 4162 4163 /*Spawn 3 sing elements: */ 4164 for(i=0;i<3;i++){ 4165 sing=(Sing*)SpawnSing(i); 4166 sing->CreatePVector(pg); 4167 } 4168 4169 /*clean up*/ 4170 delete sing; 4171 4172 } 4173 /*}}}*/ 4174 /*FUNCTION Tria::CreatePVectorPrognostic {{{1*/ 4175 void Tria::CreatePVectorPrognostic(Vec pg){ 4176 4177 4178 /* local declarations */ 4179 int i,j; 4180 4181 /* node data: */ 4182 const int numgrids=3; 4183 const int NDOF1=1; 4184 const int numdof=NDOF1*numgrids; 4185 double xyz_list[numgrids][3]; 4186 int doflist[numdof]; 4187 int numberofdofspernode; 4188 4189 /* gaussian points: */ 4190 int num_gauss,ig; 4191 double* first_gauss_area_coord = NULL; 4192 double* second_gauss_area_coord = NULL; 4193 double* third_gauss_area_coord = NULL; 4194 double* gauss_weights = NULL; 4195 double gauss_weight; 4196 double gauss_l1l2l3[3]; 4197 4198 /* matrix */ 4199 double pe_g[numgrids]={0.0}; 4200 double L[numgrids]; 4201 double Jdettria; 4202 4203 /*input parameters for structural analysis (diagnostic): */ 4204 double accumulation_g; 4205 double melting_g; 4206 double thickness_g; 4207 4208 /*parameters: */ 4209 double dt; 4210 4211 /*retrieve some parameters: */ 4212 this->parameters->FindParam(&dt,DtEnum); 4213 4214 /* Get node coordinates and dof list: */ 4215 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4216 GetDofList(&doflist[0],&numberofdofspernode); 4217 4218 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 4219 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 4220 4221 /* Start looping on the number of gaussian points: */ 4222 for (ig=0; ig<num_gauss; ig++){ 4223 /*Pick up the gaussian point: */ 4224 gauss_weight=*(gauss_weights+ig); 4225 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 4226 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 4227 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 4228 4229 /* Get Jacobian determinant: */ 4230 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 4231 4232 /*Get L matrix: */ 4233 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 4234 4235 /* Get accumulation, melting and thickness at gauss point */ 4236 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum); 4237 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum); 4238 inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum); 4239 4240 /* Add value into pe_g: */ 4241 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i]; 4242 4243 } // for (ig=0; ig<num_gauss; ig++) 4244 4245 /*Add pe_g to global matrix Kgg: */ 4246 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 4247 4248 cleanup_and_return: 4249 xfree((void**)&first_gauss_area_coord); 4250 xfree((void**)&second_gauss_area_coord); 4251 xfree((void**)&third_gauss_area_coord); 4252 xfree((void**)&gauss_weights); 4253 4254 } 4255 /*}}}*/ 4256 /*FUNCTION Tria::CreatePVectorPrognostic2 {{{1*/ 4257 void Tria::CreatePVectorPrognostic2(Vec pg){ 4258 4259 /* local declarations */ 4260 int i,j; 4261 4262 /* node data: */ 4263 const int numgrids=3; 4264 const int NDOF1=1; 4265 const int numdof=NDOF1*numgrids; 4266 double xyz_list[numgrids][3]; 4267 int doflist[numdof]; 4268 int numberofdofspernode; 4269 4270 /* gaussian points: */ 4271 int num_gauss,ig; 4272 double* first_gauss_area_coord = NULL; 4273 double* second_gauss_area_coord = NULL; 4274 double* third_gauss_area_coord = NULL; 4275 double* gauss_weights = NULL; 4276 double gauss_weight; 4277 double gauss_l1l2l3[3]; 4278 4279 /* matrix */ 4280 double pe_g[numgrids]={0.0}; 4281 double L[numgrids]; 4282 double Jdettria; 4283 4284 /*input parameters for structural analysis (diagnostic): */ 4285 double accumulation_g; 4286 double melting_g; 4287 double thickness_g; 4288 double dt; 4289 4290 /*retrieve some parameters: */ 4291 this->parameters->FindParam(&dt,DtEnum); 4292 4293 /* Get node coordinates and dof list: */ 4294 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4295 GetDofList(&doflist[0],&numberofdofspernode); 4296 4297 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 4298 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 4299 4300 /* Start looping on the number of gaussian points: */ 4301 for (ig=0; ig<num_gauss; ig++){ 4302 /*Pick up the gaussian point: */ 4303 gauss_weight=*(gauss_weights+ig); 4304 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 4305 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 4306 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 4307 4308 /* Get Jacobian determinant: */ 4309 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss_l1l2l3); 4310 4311 /*Get L matrix: */ 4312 GetL(&L[0], &xyz_list[0][0], gauss_l1l2l3,numberofdofspernode); 4313 4314 /* Get accumulation, melting and thickness at gauss point */ 4315 inputs->GetParameterValue(&accumulation_g, &gauss_l1l2l3[0],AccumulationRateEnum); 4316 inputs->GetParameterValue(&melting_g, &gauss_l1l2l3[0],MeltingRateEnum); 4317 inputs->GetParameterValue(&thickness_g, &gauss_l1l2l3[0],ThicknessEnum); 4318 4319 /* Add value into pe_g: */ 4320 for( i=0; i<numdof; i++) pe_g[i]+=Jdettria*gauss_weight*(thickness_g+dt*(accumulation_g-melting_g))*L[i]; 4321 4322 } // for (ig=0; ig<num_gauss; ig++) 4323 4324 /*Add pe_g to global matrix Kgg: */ 4325 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 4326 4327 cleanup_and_return: 4328 xfree((void**)&first_gauss_area_coord); 4329 xfree((void**)&second_gauss_area_coord); 4330 xfree((void**)&third_gauss_area_coord); 4331 xfree((void**)&gauss_weights); 4332 4333 } 4334 /*}}}*/ 4335 /*FUNCTION Tria::CreatePVectorSlopeCompute {{{1*/ 4336 4337 void Tria::CreatePVectorSlopeCompute( Vec pg){ 4338 4339 int i,j; 4340 4341 /* node data: */ 4342 const int numgrids=3; 4343 const int NDOF1=1; 4344 const int numdof=NDOF1*numgrids; 4345 double xyz_list[numgrids][3]; 4346 int doflist[numdof]; 4347 int numberofdofspernode; 4348 4349 /* gaussian points: */ 4350 int num_gauss,ig; 4351 double* first_gauss_area_coord = NULL; 4352 double* second_gauss_area_coord = NULL; 4353 double* third_gauss_area_coord = NULL; 4354 double* gauss_weights = NULL; 4355 double gauss_weight; 4356 double gauss_l1l2l3[3]; 4357 4358 /* Jacobian: */ 4359 double Jdet; 4360 4361 /*nodal functions: */ 4362 double l1l2l3[3]; 4363 4364 /*element vector at the gaussian points: */ 4365 double pe_g[numdof]={0.0}; 4366 double pe_g_gaussian[numdof]; 4367 double slope[2]; 4368 int sub_analysis_type; 4369 4370 /*retrive parameters: */ 4371 parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum); 4372 4373 /* Get node coordinates and dof list: */ 4374 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4375 GetDofList(&doflist[0],&numberofdofspernode); 4376 4377 4378 /* Get gaussian points and weights: */ 4379 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); /*We need higher order because our load is order 2*/ 4380 4381 4382 /* Start looping on the number of gaussian points: */ 4383 for (ig=0; ig<num_gauss; ig++){ 4384 /*Pick up the gaussian point: */ 4385 gauss_weight=*(gauss_weights+ig); 4386 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 4387 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 4388 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 4389 4390 if ( (sub_analysis_type==SurfaceSlopeXAnalysisEnum) || (sub_analysis_type==SurfaceSlopeYAnalysisEnum)){ 4391 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],SurfaceEnum); 4392 } 4393 if ( (sub_analysis_type==BedSlopeXAnalysisEnum) || (sub_analysis_type==BedSlopeYAnalysisEnum)){ 4394 inputs->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],&gauss_l1l2l3[0],BedEnum); 4395 } 4396 4397 /* Get Jacobian determinant: */ 4398 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 4399 4400 /*Get nodal functions: */ 4401 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 4402 4403 /*Build pe_g_gaussian vector: */ 4404 if ( (sub_analysis_type==SurfaceSlopeXAnalysisEnum) || (sub_analysis_type==BedSlopeXAnalysisEnum)){ 4405 for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[0]*l1l2l3[i]; 4406 } 4407 if ( (sub_analysis_type==SurfaceSlopeYAnalysisEnum) || (sub_analysis_type==BedSlopeYAnalysisEnum)){ 4408 for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[1]*l1l2l3[i]; 4409 } 4410 4411 /*Add pe_g_gaussian vector to pe_g: */ 4412 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i]; 4413 4414 } //for (ig=0; ig<num_gauss; ig++) 4415 4416 /*Add pe_g to global vector pg: */ 4417 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 4418 4419 cleanup_and_return: 4420 xfree((void**)&first_gauss_area_coord); 4421 xfree((void**)&second_gauss_area_coord); 4422 xfree((void**)&third_gauss_area_coord); 4423 xfree((void**)&gauss_weights); 4424 4425 } 4426 /*}}}*/ 4427 /*FUNCTION Tria::CreatePVectorThermalShelf {{{1*/ 4428 void Tria::CreatePVectorThermalShelf( Vec pg){ 4429 4430 int i,found; 4431 4432 const int numgrids=3; 4433 const int NDOF1=1; 4434 const int numdof=numgrids*NDOF1; 4435 int doflist[numdof]; 4436 int numberofdofspernode; 4437 double xyz_list[numgrids][3]; 4438 4439 double mixed_layer_capacity; 4440 double thermal_exchange_velocity; 4441 double rho_water; 4442 double rho_ice; 4443 double heatcapacity; 4444 double beta; 4445 double meltingpoint; 4446 4447 /*inputs: */ 4448 double dt; 4449 double pressure; 4450 4451 /* gaussian points: */ 4452 int num_area_gauss,ig; 4453 double* gauss_weights = NULL; 4454 double* first_gauss_area_coord = NULL; 4455 double* second_gauss_area_coord = NULL; 4456 double* third_gauss_area_coord = NULL; 4457 double gauss_weight; 4458 double gauss_coord[3]; 4459 int dofs1[1]={0}; 4460 4461 /*matrices: */ 4462 double Jdet; 4463 double P_terms[numdof]={0.0}; 4464 double l1l2l3[numgrids]; 4465 4466 double t_pmp; 4467 double scalar_ocean; 4468 4469 /* Get node coordinates and dof list: */ 4470 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4471 GetDofList(&doflist[0],&numberofdofspernode); 4472 4473 //recover material parameters 4474 mixed_layer_capacity=matpar->GetMixedLayerCapacity(); 4475 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity(); 4476 rho_water=matpar->GetRhoWater(); 4477 rho_ice=matpar->GetRhoIce(); 4478 heatcapacity=matpar->GetHeatCapacity(); 4479 beta=matpar->GetBeta(); 4480 meltingpoint=matpar->GetMeltingPoint(); 4481 4482 /*retrieve some solution parameters: */ 4483 this->parameters->FindParam(&dt,DtEnum); 4484 4485 /* Ice/ocean heat exchange flux on ice shelf base */ 4486 4487 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 4488 4489 /* Start looping on the number of gauss 2d (nodes on the bedrock) */ 4490 for (ig=0; ig<num_area_gauss; ig++){ 4491 gauss_weight=*(gauss_weights+ig); 4492 gauss_coord[0]=*(first_gauss_area_coord+ig); 4493 gauss_coord[1]=*(second_gauss_area_coord+ig); 4494 gauss_coord[2]=*(third_gauss_area_coord+ig); 4495 4496 //Get the Jacobian determinant 4497 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0], gauss_coord); 4498 4499 /*Get nodal functions values: */ 4500 GetNodalFunctions(&l1l2l3[0], gauss_coord); 4501 4502 /*Get geothermal flux and basal friction */ 4503 inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum); 4504 t_pmp=meltingpoint-beta*pressure; 4505 4506 /*Calculate scalar parameter*/ 4507 scalar_ocean=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity*(t_pmp)/(heatcapacity*rho_ice); 4508 if(dt){ 4509 scalar_ocean=dt*scalar_ocean; 4510 } 4511 4512 for(i=0;i<3;i++){ 4513 P_terms[i]+=scalar_ocean*l1l2l3[i]; 4514 } 4515 } 4516 4517 /*Add pe_g to global vector pg: */ 4518 VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES); 4519 4520 cleanup_and_return: 4521 xfree((void**)&first_gauss_area_coord); 4522 xfree((void**)&second_gauss_area_coord); 4523 xfree((void**)&third_gauss_area_coord); 4524 xfree((void**)&gauss_weights); 4525 4526 } 4527 /*}}}*/ 4528 /*FUNCTION Tria::CreatePVectorThermalSheet {{{1*/ 4529 void Tria::CreatePVectorThermalSheet( Vec pg){ 4530 4531 int i,found; 4532 4533 const int numgrids=3; 4534 const int NDOF1=1; 4535 const int numdof=numgrids*NDOF1; 4536 int doflist[numdof]; 4537 int numberofdofspernode; 4538 double xyz_list[numgrids][3]; 4539 4540 double rho_ice; 4541 double heatcapacity; 4542 4543 /*inputs: */ 4544 double dt; 4545 double pressure_list[3]; 4546 double pressure; 4547 int drag_type; 4548 double basalfriction; 4549 Friction* friction=NULL; 4550 double alpha2,vx,vy; 4551 double geothermalflux_value; 4552 4553 /* gaussian points: */ 4554 int num_area_gauss,ig; 4555 double* gauss_weights = NULL; 4556 double* first_gauss_area_coord = NULL; 4557 double* second_gauss_area_coord = NULL; 4558 double* third_gauss_area_coord = NULL; 4559 double gauss_weight; 4560 double gauss_coord[3]; 4561 4562 /*matrices: */ 4563 double Jdet; 4564 double P_terms[numdof]={0.0}; 4565 double l1l2l3[numgrids]; 4566 double scalar; 4567 4568 int analysis_type; 4569 4570 /*retrive parameters: */ 4571 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 4572 4573 4574 /* Get node coordinates and dof list: */ 4575 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4576 GetDofList(&doflist[0],&numberofdofspernode); 4577 4578 //recover material parameters 4579 rho_ice=matpar->GetRhoIce(); 4580 heatcapacity=matpar->GetHeatCapacity(); 4581 4582 /*retrieve some parameters: */ 4583 this->parameters->FindParam(&dt,DtEnum); 4584 4585 /*Build frictoin element, needed later: */ 4586 inputs->GetParameterValue(&drag_type,DragTypeEnum); 4587 if (drag_type!=2)ISSMERROR(" non-viscous friction not supported yet!"); 4588 friction=new Friction("3d",inputs,matpar,analysis_type); 4589 4590 /* Ice/ocean heat exchange flux on ice shelf base */ 4591 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2); 4592 4593 /* Start looping on the number of gauss 2d (nodes on the bedrock) */ 4594 for (ig=0; ig<num_area_gauss; ig++){ 4595 gauss_weight=*(gauss_weights+ig); 4596 gauss_coord[0]=*(first_gauss_area_coord+ig); 4597 gauss_coord[1]=*(second_gauss_area_coord+ig); 4598 gauss_coord[2]=*(third_gauss_area_coord+ig); 4599 4600 //Get the Jacobian determinant 4601 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord); 4602 4603 /*Get nodal functions values: */ 4604 GetNodalFunctions(&l1l2l3[0], gauss_coord); 4605 4606 /*Get geothermal flux and basal friction */ 4607 inputs->GetParameterValue(&geothermalflux_value, &gauss_coord[0],GeothermalFluxEnum); 4608 4609 friction->GetAlpha2(&alpha2,&gauss_coord[0],VxEnum,VyEnum,VzEnum); 4610 inputs->GetParameterValue(&vx, &gauss_coord[0],VxEnum); 4611 inputs->GetParameterValue(&vy, &gauss_coord[0],VyEnum); 4612 basalfriction= alpha2*(pow(vx,(double)2.0)+pow(vy,(double)2.0)); 4613 4614 /*Calculate scalar parameter*/ 4615 scalar=gauss_weight*Jdet*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice); 4616 if(dt){ 4617 scalar=dt*scalar; 4618 } 4619 4620 for(i=0;i<3;i++){ 4621 P_terms[i]+=scalar*l1l2l3[i]; 4622 } 4623 } 4624 4625 /*Add pe_g to global vector pg: */ 4626 VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES); 4627 4628 cleanup_and_return: 4629 xfree((void**)&first_gauss_area_coord); 4630 xfree((void**)&second_gauss_area_coord); 4631 xfree((void**)&third_gauss_area_coord); 4632 xfree((void**)&gauss_weights); 4633 delete friction; 4634 4635 } 4636 /*}}}*/ 4637 /*FUNCTION Tria::GetArea {{{1*/ 4638 double Tria::GetArea(void){ 4639 4640 double area=0; 4641 const int numgrids=3; 4642 double xyz_list[numgrids][3]; 4643 double x1,y1,x2,y2,x3,y3; 4644 4645 /*Get xyz list: */ 4646 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4647 x1=xyz_list[0][0]; y1=xyz_list[0][1]; 4648 x2=xyz_list[1][0]; y2=xyz_list[1][1]; 4649 x3=xyz_list[2][0]; y3=xyz_list[2][1]; 4650 4651 return x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1; 4652 } 4653 /*}}}*/ 4654 /*FUNCTION Tria::GetAreaCoordinate {{{1*/ 4655 double Tria::GetAreaCoordinate(double x, double y, int which_one){ 4656 4657 double area=0; 4658 const int numgrids=3; 4659 double xyz_list[numgrids][3]; 4660 double x1,y1,x2,y2,x3,y3; 4661 4662 /*Get area: */ 4663 area=this->GetArea(); 4664 4665 /*Get xyz list: */ 4666 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 4667 x1=xyz_list[0][0]; y1=xyz_list[0][1]; 4668 x2=xyz_list[1][0]; y2=xyz_list[1][1]; 4669 x3=xyz_list[2][0]; y3=xyz_list[2][1]; 4670 4671 if(which_one==1){ 4672 /*Get first area coordinate = det(x-x3 x2-x3 ; y-y3 y2-y3)/area*/ 4673 return ((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area; 4674 } 4675 else if(which_one==2){ 4676 /*Get second area coordinate = det(x1-x3 x-x3 ; y1-y3 y-y3)/area*/ 4677 return ((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area; 4678 } 4679 else if(which_one==3){ 4680 /*Get third area coordinate 1-area1-area2: */ 4681 return 1-((x-x3)*(y2-y3)-(x2-x3)*(y-y3))/area -((x1-x3)*(y-y3)-(x-x3)*(y1-y3))/area; 4682 } 4683 else ISSMERROR("%s%i%s\n"," error message: area coordinate ",which_one," done not exist!"); 4684 } 4685 /*}}}*/ 4686 /*FUNCTION Tria::GetB {{{1*/ 4687 4688 void Tria::GetB(double* B, double* xyz_list, double* gauss_l1l2l3){ 4689 4690 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 4691 * For grid i, Bi can be expressed in the actual coordinate system 4692 * by: 4693 * Bi=[ dh/dx 0 ] 4694 * [ 0 dh/dy ] 4695 * [ 1/2*dh/dy 1/2*dh/dx ] 4696 * where h is the interpolation function for grid i. 4697 * 4698 * We assume B has been allocated already, of size: 3x(NDOF2*numgrids) 4699 */ 4700 4701 int i; 4702 const int NDOF2=2; 4703 const int numgrids=3; 4704 4705 double dh1dh3[NDOF2][numgrids]; 4706 4707 4708 /*Get dh1dh2dh3 in actual coordinate system: */ 4709 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3); 4710 4711 /*Build B: */ 4712 for (i=0;i<numgrids;i++){ 4713 *(B+NDOF2*numgrids*0+NDOF2*i)=dh1dh3[0][i]; //B[0][NDOF2*i]=dh1dh3[0][i]; 4714 *(B+NDOF2*numgrids*0+NDOF2*i+1)=0; 4715 *(B+NDOF2*numgrids*1+NDOF2*i)=0; 4716 *(B+NDOF2*numgrids*1+NDOF2*i+1)=dh1dh3[1][i]; 4717 *(B+NDOF2*numgrids*2+NDOF2*i)=(float).5*dh1dh3[1][i]; 4718 *(B+NDOF2*numgrids*2+NDOF2*i+1)=(float).5*dh1dh3[0][i]; 4719 } 4720 } 4721 /*}}}*/ 4722 /*FUNCTION Tria::GetB_prog {{{1*/ 4723 4724 void Tria::GetB_prog(double* B_prog, double* xyz_list, double* gauss_l1l2l3){ 4725 4726 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 4727 * For grid i, Bi can be expressed in the actual coordinate system 4728 * by: 4729 * Bi=[ h ] 4730 * [ h ] 4731 * where h is the interpolation function for grid i. 4732 * 4733 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numgrids) 4734 */ 4735 4736 int i; 4737 const int NDOF1=1; 4738 const int numgrids=3; 4739 4740 double l1l2l3[numgrids]; 4741 4742 4743 /*Get dh1dh2dh3 in actual coordinate system: */ 4744 GetNodalFunctions(&l1l2l3[0],gauss_l1l2l3); 4745 4746 /*Build B_prog: */ 4747 for (i=0;i<numgrids;i++){ 4748 *(B_prog+NDOF1*numgrids*0+NDOF1*i)=l1l2l3[i]; 4749 *(B_prog+NDOF1*numgrids*1+NDOF1*i)=l1l2l3[i]; 4750 } 4751 } 4752 /*}}}*/ 4753 /*FUNCTION Tria::GetBPrime {{{1*/ 4754 4755 void Tria::GetBPrime(double* Bprime, double* xyz_list, double* gauss_l1l2l3){ 4756 4757 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 4758 * For grid i, Bi' can be expressed in the actual coordinate system 4759 * by: 4760 * Bi_prime=[ 2*dh/dx dh/dy ] 4761 * [ dh/dx 2*dh/dy] 4762 * [dh/dy dh/dx] 4763 * where h is the interpolation function for grid i. 4764 * 4765 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids) 4766 */ 4767 4768 int i; 4769 const int NDOF2=2; 4770 const int numgrids=3; 4771 4772 /*Same thing in the actual coordinate system: */ 4773 double dh1dh3[NDOF2][numgrids]; 4774 4775 4776 /*Get dh1dh2dh3 in actual coordinates system : */ 4777 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3); 4778 4779 /*Build B': */ 4780 for (i=0;i<numgrids;i++){ 4781 *(Bprime+NDOF2*numgrids*0+NDOF2*i)=2*dh1dh3[0][i]; 4782 *(Bprime+NDOF2*numgrids*0+NDOF2*i+1)=dh1dh3[1][i]; 4783 *(Bprime+NDOF2*numgrids*1+NDOF2*i)=dh1dh3[0][i]; 4784 *(Bprime+NDOF2*numgrids*1+NDOF2*i+1)=2*dh1dh3[1][i]; 4785 *(Bprime+NDOF2*numgrids*2+NDOF2*i)=dh1dh3[1][i]; 4786 *(Bprime+NDOF2*numgrids*2+NDOF2*i+1)=dh1dh3[0][i]; 4787 } 4788 } 4789 /*}}}*/ 4790 /*FUNCTION Tria::GetBPrime_prog {{{1*/ 4791 4792 void Tria::GetBPrime_prog(double* Bprime_prog, double* xyz_list, double* gauss_l1l2l3){ 4793 4794 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 4795 * For grid i, Bi' can be expressed in the actual coordinate system 4796 * by: 4797 * Bi_prime=[ dh/dx ] 4798 * [ dh/dy ] 4799 * where h is the interpolation function for grid i. 4800 * 4801 * We assume B' has been allocated already, of size: 3x(NDOF2*numgrids) 4802 */ 4803 4804 int i; 4805 const int NDOF1=1; 4806 const int NDOF2=2; 4807 const int numgrids=3; 4808 4809 /*Same thing in the actual coordinate system: */ 4810 double dh1dh3[NDOF2][numgrids]; 4811 4812 /*Get dh1dh2dh3 in actual coordinates system : */ 4813 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list,gauss_l1l2l3); 4814 4815 /*Build B': */ 4816 for (i=0;i<numgrids;i++){ 4817 *(Bprime_prog+NDOF1*numgrids*0+NDOF1*i)=dh1dh3[0][i]; 4818 *(Bprime_prog+NDOF1*numgrids*1+NDOF1*i)=dh1dh3[1][i]; 4819 } 4820 } 4821 /*}}}*/ 4822 /*FUNCTION Tria::GetDofList {{{1*/ 4823 void Tria::GetDofList(int* doflist,int* pnumberofdofspernode){ 4824 4825 int i,j; 4826 int doflist_per_node[MAXDOFSPERNODE]; 4827 int numberofdofspernode; 4828 4829 /*Some checks for debugging*/ 4830 ISSMASSERT(doflist); 4831 ISSMASSERT(pnumberofdofspernode); 4832 ISSMASSERT(nodes); 4833 4834 /*Build doflist from nodes*/ 4835 for(i=0;i<3;i++){ 4836 nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode); 4837 for(j=0;j<numberofdofspernode;j++){ 4838 doflist[i*numberofdofspernode+j]=doflist_per_node[j]; 4839 } 5166 4840 } 5167 4841 5168 4842 /*Assign output pointers:*/ 5169 *prow=row; 5170 } 5171 /*FUNCTION Tria::MinVel(double* pminvel, bool process_units);{{{1*/ 5172 void Tria::MinVel(double* pminvel, bool process_units){ 4843 *pnumberofdofspernode=numberofdofspernode; 4844 4845 } 4846 /*}}}*/ 4847 /*FUNCTION Tria::GetDofList1 {{{1*/ 4848 void Tria::GetDofList1(int* doflist){ 5173 4849 5174 4850 int i; 5175 int dim; 4851 for(i=0;i<3;i++){ 4852 doflist[i]=nodes[i]->GetDofList1(); 4853 } 4854 4855 } 4856 /*}}}*/ 4857 /*FUNCTION Tria::GetJacobian {{{1*/ 4858 void Tria::GetJacobian(double* J, double* xyz_list,double* gauss_l1l2l3){ 4859 4860 /*The Jacobian is constant over the element, discard the gaussian points. 4861 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ 4862 4863 const int NDOF2=2; 5176 4864 const int numgrids=3; 5177 double gaussgrids[numgrids][3]={{1,0,0},{0,1,0},{0,0,1}}; 5178 double vx_values[numgrids]; 5179 double vy_values[numgrids]; 5180 double vz_values[numgrids]; 5181 double vel_values[numgrids]; 5182 double minvel; 5183 5184 /*retrieve dim parameter: */ 5185 parameters->FindParam(&dim,DimEnum); 5186 5187 /*retrive velocity values at nodes */ 5188 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 5189 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 5190 if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 5191 5192 /*now, compute minimum of velocity :*/ 5193 if(dim==2){ 5194 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)); 4865 double x1,y1,x2,y2,x3,y3; 4866 4867 x1=*(xyz_list+numgrids*0+0); 4868 y1=*(xyz_list+numgrids*0+1); 4869 x2=*(xyz_list+numgrids*1+0); 4870 y2=*(xyz_list+numgrids*1+1); 4871 x3=*(xyz_list+numgrids*2+0); 4872 y3=*(xyz_list+numgrids*2+1); 4873 4874 4875 *(J+NDOF2*0+0)=0.5*(x2-x1); 4876 *(J+NDOF2*1+0)=SQRT3/6.0*(2*x3-x1-x2); 4877 *(J+NDOF2*0+1)=0.5*(y2-y1); 4878 *(J+NDOF2*1+1)=SQRT3/6.0*(2*y3-y1-y2); 4879 } 4880 /*}}}*/ 4881 /*FUNCTION Tria::GetJacobianDeterminant2d {{{1*/ 4882 void Tria::GetJacobianDeterminant2d(double* Jdet, double* xyz_list,double* gauss_l1l2l3){ 4883 4884 /*The Jacobian determinant is constant over the element, discard the gaussian points. 4885 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ 4886 4887 double x1,x2,x3,y1,y2,y3; 4888 4889 x1=*(xyz_list+3*0+0); 4890 y1=*(xyz_list+3*0+1); 4891 x2=*(xyz_list+3*1+0); 4892 y2=*(xyz_list+3*1+1); 4893 x3=*(xyz_list+3*2+0); 4894 y3=*(xyz_list+3*2+1); 4895 4896 4897 *Jdet=SQRT3/6.0*((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)); 4898 4899 4900 if(Jdet<0){ 4901 ISSMERROR("negative jacobian determinant!"); 4902 } 4903 4904 } 4905 /*}}}*/ 4906 /*FUNCTION Tria::GetJacobianDeterminant3d {{{1*/ 4907 void Tria::GetJacobianDeterminant3d(double* Jdet, double* xyz_list,double* gauss_l1l2l3){ 4908 4909 /*The Jacobian determinant is constant over the element, discard the gaussian points. 4910 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ 4911 4912 double x1,x2,x3,y1,y2,y3,z1,z2,z3; 4913 4914 x1=*(xyz_list+3*0+0); 4915 y1=*(xyz_list+3*0+1); 4916 z1=*(xyz_list+3*0+2); 4917 x2=*(xyz_list+3*1+0); 4918 y2=*(xyz_list+3*1+1); 4919 z2=*(xyz_list+3*1+2); 4920 x3=*(xyz_list+3*2+0); 4921 y3=*(xyz_list+3*2+1); 4922 z3=*(xyz_list+3*2+2); 4923 4924 4925 *Jdet=SQRT3/6.0*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2.0)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2.0)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2.0),0.5); 4926 4927 if(Jdet<0){ 4928 ISSMERROR("negative jacobian determinant!"); 4929 } 4930 4931 } 4932 /*}}}*/ 4933 /*FUNCTION Tria::GetJacobianInvert {{{1*/ 4934 void Tria::GetJacobianInvert(double* Jinv, double* xyz_list,double* gauss_l1l2l3){ 4935 4936 double Jdet; 4937 const int NDOF2=2; 4938 const int numgrids=3; 4939 4940 /*Call Jacobian routine to get the jacobian:*/ 4941 GetJacobian(Jinv, xyz_list, gauss_l1l2l3); 4942 4943 /*Invert Jacobian matrix: */ 4944 MatrixInverse(Jinv,NDOF2,NDOF2,NULL,0,&Jdet); 4945 4946 } 4947 /*}}}*/ 4948 /*FUNCTION Tria::GetL {{{1*/ 4949 4950 void Tria::GetL(double* L, double* xyz_list, double* gauss_l1l2l3,int numdof){ 4951 4952 /*Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof. 4953 * For grid i, Li can be expressed in the actual coordinate system 4954 * by: 4955 * numdof=1: 4956 * Li=h; 4957 * numdof=2: 4958 * Li=[ h 0 ] 4959 * [ 0 h ] 4960 * where h is the interpolation function for grid i. 4961 * 4962 * We assume L has been allocated already, of size: numgrids (numdof=1), or numdofx(numdof*numgrids) (numdof=2) 4963 */ 4964 4965 int i; 4966 const int NDOF2=2; 4967 const int numgrids=3; 4968 4969 double l1l2l3[3]; 4970 4971 4972 /*Get l1l2l3 in actual coordinate system: */ 4973 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 4974 4975 #ifdef _DELUG_ 4976 for (i=0;i<3;i++){ 4977 printf("Node %i h=%lf \n",i,l1l2l3[i]); 4978 } 4979 #endif 4980 4981 /*Build L: */ 4982 if(numdof==1){ 4983 for (i=0;i<numgrids;i++){ 4984 L[i]=l1l2l3[i]; 4985 } 5195 4986 } 5196 4987 else{ 5197 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2)); 5198 } 5199 5200 /*now, compute minimum:*/ 5201 minvel=vel_values[0]; 5202 for(i=1;i<numgrids;i++){ 5203 if (vel_values[i]<minvel)minvel=vel_values[i]; 5204 } 4988 for (i=0;i<numgrids;i++){ 4989 *(L+numdof*numgrids*0+numdof*i)=l1l2l3[i]; //L[0][NDOF2*i]=dh1dh3[0][i]; 4990 *(L+numdof*numgrids*0+numdof*i+1)=0; 4991 *(L+numdof*numgrids*1+numdof*i)=0; 4992 *(L+numdof*numgrids*1+numdof*i+1)=l1l2l3[i]; 4993 } 4994 } 4995 } 4996 /*}}}*/ 4997 /*FUNCTION Tria::GetNodalFunctions {{{1*/ 4998 void Tria::GetNodalFunctions(double* l1l2l3, double* gauss_l1l2l3){ 4999 5000 /*This routine returns the values of the nodal functions at the gaussian point.*/ 5001 5002 /*First nodal function: */ 5003 l1l2l3[0]=gauss_l1l2l3[0]; 5004 5005 /*Second nodal function: */ 5006 l1l2l3[1]=gauss_l1l2l3[1]; 5007 5008 /*Third nodal function: */ 5009 l1l2l3[2]=gauss_l1l2l3[2]; 5010 5011 } 5012 /*}}}*/ 5013 /*FUNCTION Tria::GetNodalFunctionsDerivatives {{{1*/ 5014 void Tria::GetNodalFunctionsDerivatives(double* dh1dh3,double* xyz_list, double* gauss_l1l2l3){ 5015 5016 /*This routine returns the values of the nodal functions derivatives (with respect to the 5017 * actual coordinate system: */ 5018 5019 int i; 5020 const int NDOF2=2; 5021 const int numgrids=3; 5022 5023 double dh1dh3_ref[NDOF2][numgrids]; 5024 double Jinv[NDOF2][NDOF2]; 5025 5026 5027 /*Get derivative values with respect to parametric coordinate system: */ 5028 GetNodalFunctionsDerivativesReference(&dh1dh3_ref[0][0], gauss_l1l2l3); 5029 5030 /*Get Jacobian invert: */ 5031 GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_l1l2l3); 5032 5033 /*Build dh1dh3: 5034 * 5035 * [dhi/dx]= Jinv*[dhi/dr] 5036 * [dhi/dy] [dhi/ds] 5037 */ 5038 5039 for (i=0;i<numgrids;i++){ 5040 *(dh1dh3+numgrids*0+i)=Jinv[0][0]*dh1dh3_ref[0][i]+Jinv[0][1]*dh1dh3_ref[1][i]; 5041 *(dh1dh3+numgrids*1+i)=Jinv[1][0]*dh1dh3_ref[0][i]+Jinv[1][1]*dh1dh3_ref[1][i]; 5042 } 5043 5044 } 5045 /*}}}*/ 5046 /*FUNCTION Tria::GetNodalFunctionsDerivativesReference {{{1*/ 5047 void Tria::GetNodalFunctionsDerivativesReference(double* dl1dl3,double* gauss_l1l2l3){ 5048 5049 /*This routine returns the values of the nodal functions derivatives (with respect to the 5050 * natural coordinate system) at the gaussian point. */ 5051 5052 const int NDOF2=2; 5053 const int numgrids=3; 5054 5055 /*First nodal function: */ 5056 *(dl1dl3+numgrids*0+0)=-0.5; 5057 *(dl1dl3+numgrids*1+0)=-1.0/(2.0*SQRT3); 5058 5059 /*Second nodal function: */ 5060 *(dl1dl3+numgrids*0+1)=0.5; 5061 *(dl1dl3+numgrids*1+1)=-1.0/(2.0*SQRT3); 5062 5063 /*Third nodal function: */ 5064 *(dl1dl3+numgrids*0+2)=0; 5065 *(dl1dl3+numgrids*1+2)=1.0/SQRT3; 5066 5067 } 5068 /*}}}*/ 5069 /*FUNCTION Tria::GetParameterDerivativeValue {{{1*/ 5070 void Tria::GetParameterDerivativeValue(double* p, double* plist,double* xyz_list, double* gauss_l1l2l3){ 5071 5072 const int NDOF2=2; 5073 const int numgrids=3; 5074 /*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter derivative value at gaussian 5075 * point specified by gauss_l1l2l3: 5076 * dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx 5077 * dp/dx=plist[0]*dh1/dx+plist[1]*dh2/dx+plist[2]*dh3/dx 5078 * 5079 * p is a vector of size 2x1 already allocated. 5080 */ 5081 5082 double dh1dh3[NDOF2][numgrids]; //nodal derivative functions in actual coordinate system. 5083 5084 /*Get dh1dh2dh3 in actual coordinate system: */ 5085 GetNodalFunctionsDerivatives(&dh1dh3[0][0],xyz_list, gauss_l1l2l3); 5086 5087 *(p+0)=plist[0]*dh1dh3[0][0]+plist[1]*dh1dh3[0][1]+plist[2]*dh1dh3[0][2]; 5088 *(p+1)=plist[0]*dh1dh3[1][0]+plist[1]*dh1dh3[1][1]+plist[2]*dh1dh3[1][2]; 5089 5090 } 5091 /*}}}*/ 5092 /*FUNCTION Tria::GetParameterValue {{{1*/ 5093 void Tria::GetParameterValue(double* pp, double* plist, double* gauss_l1l2l3){ 5094 5095 /*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter value at gaussian 5096 * point specifie by gauss_l1l2l3: */ 5097 5098 /*nodal functions: */ 5099 double l1l2l3[3]; 5100 5101 /*output: */ 5102 double p; 5103 5104 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 5105 5106 p=l1l2l3[0]*plist[0]+l1l2l3[1]*plist[1]+l1l2l3[2]*plist[2]; 5205 5107 5206 5108 /*Assign output pointers:*/ 5207 *pminvel=minvel; 5208 5209 } 5210 /*}}}*/ 5211 /*FUNCTION Tria::MaxVel(double* pmaxvel, bool process_units);{{{1*/ 5212 void Tria::MaxVel(double* pmaxvel, bool process_units){ 5109 *pp=p; 5110 } 5111 /*}}}*/ 5112 /*FUNCTION Tria::GradjDragStokes {{{1*/ 5113 void Tria::GradjDragStokes(Vec gradient){ 5213 5114 5214 5115 int i; 5215 int dim; 5216 const int numgrids=3; 5217 double gaussgrids[numgrids][3]={{1,0,0},{0,1,0},{0,0,1}}; 5218 double vx_values[numgrids]; 5219 double vy_values[numgrids]; 5220 double vz_values[numgrids]; 5221 double vel_values[numgrids]; 5222 double maxvel; 5223 5224 /*retrieve dim parameter: */ 5225 parameters->FindParam(&dim,DimEnum); 5226 5227 /*retrive velocity values at nodes */ 5228 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 5229 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 5230 if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 5231 5232 /*now, compute maximum of velocity :*/ 5233 if(dim==2){ 5234 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)); 5235 } 5236 else{ 5237 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2)); 5238 } 5239 5240 /*now, compute maximum:*/ 5241 maxvel=vel_values[0]; 5242 for(i=1;i<numgrids;i++){ 5243 if (vel_values[i]>maxvel)maxvel=vel_values[i]; 5244 } 5245 5246 /*Assign output pointers:*/ 5247 *pmaxvel=maxvel; 5248 5249 } 5250 /*}}}*/ 5251 /*FUNCTION Tria::MinVx(double* pminvx, bool process_units);{{{1*/ 5252 void Tria::MinVx(double* pminvx, bool process_units){ 5116 5117 /* node data: */ 5118 const int numgrids=3; 5119 const int NDOF2=2; 5120 double xyz_list[numgrids][3]; 5121 int doflist1[numgrids]; 5122 double dh1dh3[NDOF2][numgrids]; 5123 5124 /* grid data: */ 5125 double drag; 5126 double alpha_complement; 5127 Friction* friction=NULL; 5128 5129 /* gaussian points: */ 5130 int num_gauss,ig; 5131 double* first_gauss_area_coord = NULL; 5132 double* second_gauss_area_coord = NULL; 5133 double* third_gauss_area_coord = NULL; 5134 double* gauss_weights = NULL; 5135 double gauss_weight; 5136 double gauss_l1l2l3[3]; 5137 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5138 5139 /* parameters: */ 5140 double vx,vy,vz; 5141 double lambda,mu,xi; 5142 double bed,thickness,Neff; 5143 double surface_normal[3]; 5144 double bed_normal[3]; 5145 double dk[NDOF2]; 5146 5147 /*element vector at the gaussian points: */ 5148 double grade_g[numgrids]={0.0}; 5149 double grade_g_gaussian[numgrids]; 5150 5151 /* Jacobian: */ 5152 double Jdet; 5153 5154 /*nodal functions: */ 5155 double l1l2l3[3]; 5156 5157 /* strain rate: */ 5158 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/ 5159 5160 /*inputs: */ 5161 bool shelf; 5162 int drag_type; 5163 5164 /*parameters: */ 5165 double cm_noisedmp; 5166 double cm_mindmp_slope; 5167 double cm_mindmp_value; 5168 double cm_maxdmp_value; 5169 double cm_maxdmp_slope; 5170 5171 int analysis_type; 5172 5173 /*retrive parameters: */ 5174 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 5175 5176 /*retrieve inputs :*/ 5177 inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum); 5178 inputs->GetParameterValue(&drag_type,DragTypeEnum); 5179 5180 /*retrieve some parameters: */ 5181 this->parameters->FindParam(&cm_noisedmp,CmNoiseDmpEnum); 5182 this->parameters->FindParam(&cm_mindmp_value,CmMinDmpValueEnum); 5183 this->parameters->FindParam(&cm_mindmp_slope,CmMinDmpSlopeEnum); 5184 this->parameters->FindParam(&cm_maxdmp_value,CmMaxDmpValueEnum); 5185 this->parameters->FindParam(&cm_maxdmp_slope,CmMaxDmpSlopeEnum); 5186 5187 /*Get out if shelf*/ 5188 if(shelf)return; 5189 5190 /* Get node coordinates and dof list: */ 5191 GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids); 5192 GetDofList1(&doflist1[0]); 5193 5194 /*Build frictoin element, needed later: */ 5195 inputs->GetParameterValue(&drag_type,DragTypeEnum); 5196 friction=new Friction("2d",inputs,matpar,analysis_type); 5197 5198 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 5199 GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 4); 5200 5201 /* Start looping on the number of gaussian points: */ 5202 for (ig=0; ig<num_gauss; ig++){ 5203 /*Pick up the gaussian point: */ 5204 gauss_weight=*(gauss_weights+ig); 5205 gauss_l1l2l3[0]=*(first_gauss_area_coord+ig); 5206 gauss_l1l2l3[1]=*(second_gauss_area_coord+ig); 5207 gauss_l1l2l3[2]=*(third_gauss_area_coord+ig); 5208 5209 /*Recover alpha_complement and drag: */ 5210 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss_l1l2l3,VxAverageEnum,VyAverageEnum); 5211 else alpha_complement=0; 5212 inputs->GetParameterValue(&drag, &gauss_l1l2l3[0],DragCoefficientEnum); 5213 5214 /*recover lambda mu and xi: */ 5215 inputs->GetParameterValue(&lambda, &gauss_l1l2l3[0],AdjointxEnum); 5216 inputs->GetParameterValue(&mu, &gauss_l1l2l3[0],AdjointyEnum); 5217 inputs->GetParameterValue(&xi, &gauss_l1l2l3[0],AdjointzEnum); 5218 5219 /*recover vx vy and vz: */ 5220 inputs->GetParameterValue(&vx, &gauss_l1l2l3[0],VxEnum); 5221 inputs->GetParameterValue(&vy, &gauss_l1l2l3[0],VyEnum); 5222 inputs->GetParameterValue(&vz, &gauss_l1l2l3[0],VzEnum); 5223 5224 /*Get normal vector to the bed */ 5225 SurfaceNormal(&surface_normal[0],xyz_list); 5226 5227 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 5228 bed_normal[1]=-surface_normal[1]; 5229 bed_normal[2]=-surface_normal[2]; 5230 5231 /* Get Jacobian determinant: */ 5232 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss_l1l2l3); 5233 5234 /* Get nodal functions value at gaussian point:*/ 5235 GetNodalFunctions(l1l2l3, gauss_l1l2l3); 5236 5237 /*Get nodal functions derivatives*/ 5238 GetNodalFunctionsDerivatives(&dh1dh3[0][0],&xyz_list[0][0],gauss_l1l2l3); 5239 5240 /*Get k derivative: dk/dx */ 5241 inputs->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],&gauss_l1l2l3[0],DragCoefficientEnum); 5242 5243 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */ 5244 for (i=0;i<numgrids;i++){ 5245 //standard gradient dJ/dki 5246 grade_g_gaussian[i]=( 5247 -lambda*(2*drag*alpha_complement*(vx - vz*bed_normal[0]*bed_normal[2])) 5248 -mu *(2*drag*alpha_complement*(vy - vz*bed_normal[1]*bed_normal[2])) 5249 -xi *(2*drag*alpha_complement*(-vx*bed_normal[0]*bed_normal[2]-vy*bed_normal[1]*bed_normal[2])) 5250 )*Jdet*gauss_weight*l1l2l3[i]; 5251 5252 //Add regularization term 5253 grade_g_gaussian[i]+= - cm_noisedmp*Jdet*gauss_weight*(dh1dh3[0][i]*dk[0]+dh1dh3[1][i]*dk[1]); 5254 5255 //min dampening 5256 if(drag<cm_mindmp_value){ 5257 grade_g_gaussian[i]+= cm_mindmp_slope*Jdet*gauss_weight*l1l2l3[i]; 5258 } 5259 5260 //max dampening 5261 if(drag>cm_maxdmp_value){ 5262 grade_g_gaussian[i]+= - cm_maxdmp_slope*Jdet*gauss_weight*l1l2l3[i]; 5263 } 5264 } 5265 5266 /*Add gradje_g_gaussian vector to gradje_g: */ 5267 for( i=0; i<numgrids; i++)grade_g[i]+=grade_g_gaussian[i]; 5268 } 5269 5270 /*Add grade_g to global vector gradient: */ 5271 VecSetValues(gradient,numgrids,doflist1,(const double*)grade_g,ADD_VALUES); 5272 5273 /*Add grade_g to the inputs of this element: */ 5274 this->inputs->AddInput(new TriaVertexInput(GradientEnum,&grade_g[0])); 5275 5276 cleanup_and_return: 5277 xfree((void**)&first_gauss_area_coord); 5278 xfree((void**)&second_gauss_area_coord); 5279 xfree((void**)&third_gauss_area_coord); 5280 xfree((void**)&gauss_weights); 5281 delete friction; 5282 5283 } 5284 /*}}}*/ 5285 /*FUNCTION Tria::SetClone {{{1*/ 5286 void Tria::SetClone(int* minranks){ 5287 5288 ISSMERROR("not implemented yet"); 5289 } 5290 /*}}}1*/ 5291 /*FUNCTION Tria::SpawnBeam {{{1*/ 5292 void* Tria::SpawnBeam(int g0, int g1){ 5253 5293 5254 5294 int i; 5255 int dim; 5256 const int numgrids=3; 5257 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5258 double vx_values[numgrids]; 5259 double minvx; 5260 5261 /*retrieve dim parameter: */ 5262 parameters->FindParam(&dim,DimEnum); 5263 5264 /*retrive velocity values at nodes */ 5265 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 5266 5267 /*now, compute minimum:*/ 5268 minvx=vx_values[0]; 5269 for(i=1;i<numgrids;i++){ 5270 if (vx_values[i]<minvx)minvx=vx_values[i]; 5271 } 5272 5273 /*Assign output pointers:*/ 5274 *pminvx=minvx; 5275 5276 } 5277 /*}}}*/ 5278 /*FUNCTION Tria::MaxVx(double* pmaxvx, bool process_units);{{{1*/ 5279 void Tria::MaxVx(double* pmaxvx, bool process_units){ 5295 5296 /*out of grids g0,g1 and g2 from Tria, build a beam element: */ 5297 Beam* beam=NULL; 5298 int indices[2]; 5299 int zero=0; 5300 Parameters *beam_parameters = NULL; 5301 Inputs *beam_inputs = NULL; 5302 5303 indices[0]=g0; 5304 indices[1]=g1; 5305 5306 beam_parameters=this->parameters; 5307 beam_inputs=(Inputs*)this->inputs->SpawnBeamInputs(indices); 5308 5309 beam=new Beam(); 5310 beam->id=this->id; 5311 beam->inputs=beam_inputs; 5312 beam->parameters=beam_parameters; 5313 5314 /*now deal with nodes, matice and matpar: */ 5315 beam->nodes=(Node**)xmalloc(2*sizeof(Node*)); 5316 for(i=0;i<2;i++)beam->nodes[i]=this->nodes[indices[i]]; 5317 beam->matice=this->matice; 5318 beam->matpar=this->matpar; 5319 5320 5321 return beam; 5322 } 5323 /*}}}*/ 5324 /*FUNCTION Tria::SpawnSing {{{1*/ 5325 void* Tria::SpawnSing(int index){ 5326 5327 Sing* sing=NULL; 5328 int zero=0; 5329 Parameters *sing_parameters = NULL; 5330 Inputs *sing_inputs = NULL; 5331 5332 sing_parameters=this->parameters; 5333 sing_inputs=(Inputs*)this->inputs->SpawnSingInputs(index); 5334 5335 sing=new Sing(); 5336 sing->id=this->id; 5337 sing->inputs=sing_inputs; 5338 sing->parameters=sing_parameters; 5339 5340 /*now deal with node,matice and matpar: */ 5341 sing->node=this->nodes[index]; 5342 sing->matice=this->matice; 5343 sing->matpar=this->matpar; 5344 5345 return sing; 5346 } 5347 /*}}}*/ 5348 /*FUNCTION Tria::SurfaceNormal{{{1*/ 5349 5350 void Tria::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ 5280 5351 5281 5352 int i; 5282 int dim; 5283 const int numgrids=3; 5284 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5285 double vx_values[numgrids]; 5286 double maxvx; 5287 5288 /*retrieve dim parameter: */ 5289 parameters->FindParam(&dim,DimEnum); 5290 5291 /*retrive velocity values at nodes */ 5292 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 5293 5294 /*now, compute maximum:*/ 5295 maxvx=vx_values[0]; 5296 for(i=1;i<numgrids;i++){ 5297 if (vx_values[i]>maxvx)maxvx=vx_values[i]; 5298 } 5299 5300 /*Assign output pointers:*/ 5301 *pmaxvx=maxvx; 5302 5303 } 5304 /*}}}*/ 5305 /*FUNCTION Tria::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/ 5306 void Tria::MaxAbsVx(double* pmaxabsvx, bool process_units){ 5307 5308 int i; 5309 int dim; 5310 const int numgrids=3; 5311 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5312 double vx_values[numgrids]; 5313 double maxabsvx; 5314 5315 /*retrieve dim parameter: */ 5316 parameters->FindParam(&dim,DimEnum); 5317 5318 /*retrive velocity values at nodes */ 5319 inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum); 5320 5321 /*now, compute maximum:*/ 5322 maxabsvx=fabs(vx_values[0]); 5323 for(i=1;i<numgrids;i++){ 5324 if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]); 5325 } 5326 5327 /*Assign output pointers:*/ 5328 *pmaxabsvx=maxabsvx; 5329 } 5330 /*}}}*/ 5331 /*FUNCTION Tria::MinVy(double* pminvy, bool process_units);{{{1*/ 5332 void Tria::MinVy(double* pminvy, bool process_units){ 5333 5334 int i; 5335 int dim; 5336 const int numgrids=3; 5337 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5338 double vy_values[numgrids]; 5339 double minvy; 5340 5341 /*retrieve dim parameter: */ 5342 parameters->FindParam(&dim,DimEnum); 5343 5344 /*retrive velocity values at nodes */ 5345 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 5346 5347 /*now, compute minimum:*/ 5348 minvy=vy_values[0]; 5349 for(i=1;i<numgrids;i++){ 5350 if (vy_values[i]<minvy)minvy=vy_values[i]; 5351 } 5352 5353 /*Assign output pointers:*/ 5354 *pminvy=minvy; 5355 5356 } 5357 /*}}}*/ 5358 /*FUNCTION Tria::MaxVy(double* pmaxvy, bool process_units);{{{1*/ 5359 void Tria::MaxVy(double* pmaxvy, bool process_units){ 5360 5361 int i; 5362 int dim; 5363 const int numgrids=3; 5364 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5365 double vy_values[numgrids]; 5366 double maxvy; 5367 5368 /*retrieve dim parameter: */ 5369 parameters->FindParam(&dim,DimEnum); 5370 5371 /*retrive velocity values at nodes */ 5372 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 5373 5374 /*now, compute maximum:*/ 5375 maxvy=vy_values[0]; 5376 for(i=1;i<numgrids;i++){ 5377 if (vy_values[i]>maxvy)maxvy=vy_values[i]; 5378 } 5379 5380 /*Assign output pointers:*/ 5381 *pmaxvy=maxvy; 5382 5383 } 5384 /*}}}*/ 5385 /*FUNCTION Tria::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/ 5386 void Tria::MaxAbsVy(double* pmaxabsvy, bool process_units){ 5387 5388 int i; 5389 int dim; 5390 const int numgrids=3; 5391 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5392 double vy_values[numgrids]; 5393 double maxabsvy; 5394 5395 /*retrieve dim parameter: */ 5396 parameters->FindParam(&dim,DimEnum); 5397 5398 /*retrive velocity values at nodes */ 5399 inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum); 5400 5401 /*now, compute maximum:*/ 5402 maxabsvy=fabs(vy_values[0]); 5403 for(i=1;i<numgrids;i++){ 5404 if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]); 5405 } 5406 5407 /*Assign output pointers:*/ 5408 *pmaxabsvy=maxabsvy; 5409 } 5410 /*}}}*/ 5411 /*FUNCTION Tria::MinVz(double* pminvz, bool process_units);{{{1*/ 5412 void Tria::MinVz(double* pminvz, bool process_units){ 5413 5414 int i; 5415 int dim; 5416 const int numgrids=3; 5417 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5418 double vz_values[numgrids]; 5419 double minvz; 5420 5421 /*retrieve dim parameter: */ 5422 parameters->FindParam(&dim,DimEnum); 5423 5424 /*retrive velocity values at nodes */ 5425 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 5426 5427 /*now, compute minimum:*/ 5428 minvz=vz_values[0]; 5429 for(i=1;i<numgrids;i++){ 5430 if (vz_values[i]<minvz)minvz=vz_values[i]; 5431 } 5432 5433 /*Assign output pointers:*/ 5434 *pminvz=minvz; 5435 5436 } 5437 /*}}}*/ 5438 /*FUNCTION Tria::MaxVz(double* pmaxvz, bool process_units);{{{1*/ 5439 void Tria::MaxVz(double* pmaxvz, bool process_units){ 5440 5441 int i; 5442 int dim; 5443 const int numgrids=3; 5444 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5445 double vz_values[numgrids]; 5446 double maxvz; 5447 5448 /*retrieve dim parameter: */ 5449 parameters->FindParam(&dim,DimEnum); 5450 5451 /*retrive velocity values at nodes */ 5452 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 5453 5454 /*now, compute maximum:*/ 5455 maxvz=vz_values[0]; 5456 for(i=1;i<numgrids;i++){ 5457 if (vz_values[i]>maxvz)maxvz=vz_values[i]; 5458 } 5459 5460 /*Assign output pointers:*/ 5461 *pmaxvz=maxvz; 5462 5463 } 5464 /*}}}*/ 5465 /*FUNCTION Tria::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/ 5466 void Tria::MaxAbsVz(double* pmaxabsvz, bool process_units){ 5467 5468 int i; 5469 int dim; 5470 const int numgrids=3; 5471 double gaussgrids[numgrids][numgrids]={{1,0,0},{0,1,0},{0,0,1}}; 5472 double vz_values[numgrids]; 5473 double maxabsvz; 5474 5475 /*retrieve dim parameter: */ 5476 parameters->FindParam(&dim,DimEnum); 5477 5478 /*retrive velocity values at nodes */ 5479 inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum); 5480 5481 /*now, compute maximum:*/ 5482 maxabsvz=fabs(vz_values[0]); 5483 for(i=1;i<numgrids;i++){ 5484 if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]); 5485 } 5486 5487 /*Assign output pointers:*/ 5488 *pmaxabsvz=maxabsvz; 5489 } 5490 /*}}}*/ 5491 /*FUNCTION Tria::InputDuplicate(int original_enum,int new_enum){{{1*/ 5492 void Tria::InputDuplicate(int original_enum,int new_enum){ 5493 5494 Input* original=NULL; 5495 Input* copy=NULL; 5496 5497 /*Make a copy of the original input: */ 5498 original=(Input*)this->inputs->GetInput(original_enum); 5499 copy=(Input*)original->copy(); 5500 5501 /*Change copy enum to reinitialized_enum: */ 5502 copy->ChangeEnum(new_enum); 5503 5504 /*Add copy into inputs, it will wipe off the one already there: */ 5505 inputs->AddObject((Input*)copy); 5506 } 5507 /*}}}*/ 5508 /*FUNCTION Tria::InputScale(int enum_type,double scale_factor){{{1*/ 5509 void Tria::InputScale(int enum_type,double scale_factor){ 5510 5511 Input* input=NULL; 5512 5513 /*Make a copy of the original input: */ 5514 input=(Input*)this->inputs->GetInput(enum_type); 5515 5516 /*Scale: */ 5517 input->Scale(scale_factor); 5518 } 5519 /*}}}*/ 5520 /*FUNCTION Tria::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/ 5521 void Tria::InputAXPY(int YEnum, double scalar, int XEnum){ 5522 5523 Input* xinput=NULL; 5524 Input* yinput=NULL; 5525 5526 /*Find x and y inputs: */ 5527 xinput=(Input*)this->inputs->GetInput(XEnum); 5528 yinput=(Input*)this->inputs->GetInput(YEnum); 5529 5530 /*some checks: */ 5531 if(!xinput || !yinput) ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!"); 5532 5533 /*Scale: */ 5534 yinput->AXPY(xinput,scalar); 5535 } 5536 /*}}}*/ 5537 /*FUNCTION Tria::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/ 5538 void Tria::InputControlConstrain(int control_type, double cm_min, double cm_max){ 5539 5540 Input* input=NULL; 5541 5542 /*Find input: */ 5543 input=(Input*)this->inputs->GetInput(control_type); 5544 5545 /*Do nothing if we don't find it: */ 5546 if(!input)return; 5547 5548 /*Constrain input using cm_min and cm_max: */ 5549 input->Constrain(cm_min,cm_max); 5550 5551 } 5552 /*}}}*/ 5553 /*FUNCTION Tria::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/ 5554 void Tria::GetVectorFromInputs(Vec vector,int NameEnum){ 5555 5556 int i; 5557 const int numvertices=3; 5558 int doflist1[numvertices]; 5559 5560 /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */ 5561 for(i=0;i<this->inputs->Size();i++){ 5562 Input* input=(Input*)this->inputs->GetObjectByOffset(i); 5563 if(input->EnumType()==NameEnum){ 5564 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */ 5565 this->GetDofList1(&doflist1[0]); 5566 input->GetVectorFromInputs(vector,&doflist1[0]); 5567 break; 5568 } 5569 } 5570 } 5571 /*}}}*/ 5572 /*FUNCTION Tria::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/ 5573 void Tria::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){ 5574 5575 int i; 5576 Input** new_inputs=NULL; 5577 Input** old_inputs=NULL; 5578 int converged=1; 5579 5580 new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs 5581 old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs 5582 5583 for(i=0;i<num_enums/2;i++){ 5584 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]); 5585 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]); 5586 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 5587 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0])); 5588 } 5589 5590 /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/ 5591 for(i=0;i<num_criterionenums;i++){ 5592 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]); 5593 if(eps[i]>criterionvalues[i]) converged=0; 5594 } 5595 5596 /*Assign output pointers:*/ 5597 *pconverged=converged; 5598 5599 } 5600 /*}}}*/ 5353 double v13[3]; 5354 double v23[3]; 5355 double normal[3]; 5356 double normal_norm; 5357 5358 for (i=0;i<3;i++){ 5359 v13[i]=xyz_list[0][i]-xyz_list[2][i]; 5360 v23[i]=xyz_list[1][i]-xyz_list[2][i]; 5361 } 5362 5363 normal[0]=v13[1]*v23[2]-v13[2]*v23[1]; 5364 normal[1]=v13[2]*v23[0]-v13[0]*v23[2]; 5365 normal[2]=v13[0]*v23[1]-v13[1]*v23[0]; 5366 5367 normal_norm=sqrt( pow(normal[0],(double)2)+pow(normal[1],(double)2)+pow(normal[2],(double)2) ); 5368 5369 *(surface_normal)=normal[0]/normal_norm; 5370 *(surface_normal+1)=normal[1]/normal_norm; 5371 *(surface_normal+2)=normal[2]/normal_norm; 5372 5373 } 5374 /*}}}*/ 5375 /*FUNCTION Tria::UpdateFromDakota {{{1*/ 5376 void Tria::UpdateFromDakota(void* vinputs){ 5377 5378 int i; 5379 int dofs[1]={0}; 5380 double temperature_list[3]; 5381 double temperature_average; 5382 double B_list[3]; 5383 double B_average; 5384 double new_h[3]; 5385 5386 /*Update internal data if inputs holds new values: */ 5387 /*inputs->Recover("thickness",&this->properties.h[0],1,dofs,3,(void**)nodes); 5388 if(inputs->Recover("thickness",&new_h[0],1,dofs,3,(void**)nodes)){ 5389 //density, needed later: 5390 double di=(this->matpar->GetRhoIce()/this->matpar->GetRhoWater()); 5391 //Go through grids: 5392 for (i=0;i<3;i++){ 5393 if(nodes[i]->IsOnShelf()){ 5394 this->b[i]=this->b[i]-di*(new_h[i]-h[i]); //hydrostatic equilibrium; 5395 } 5396 this->s[i]=this->b[i]+new_h[i]; 5397 this->h[i]=new_h[i]; 5398 } 5399 }*/ 5400 5401 ISSMERROR("not supported yet!"); 5402 5403 } 5404 /*}}}*/ -
issm/trunk/src/c/objects/Elements/Tria.h
r4249 r4285 54 54 /*Update virtual functions resolution: {{{1*/ 55 55 void InputUpdateFromSolution(double* solutiong); 56 void InputUpdateFromSolutionDiagnosticHoriz( double* solution);57 void InputUpdateFromSolutionSlopeCompute( double* solution);58 void InputUpdateFromSolutionPrognostic( double* solution);59 void InputUpdateFromSolutionPrognostic2(double* solution);60 void InputUpdateFromSolutionBalancedthickness( double* solution);61 void InputUpdateFromSolutionBalancedthickness2( double* solution);62 void InputUpdateFromSolutionBalancedvelocities( double* solution);63 56 void InputUpdateFromVector(double* vector, int name, int type); 64 57 void InputUpdateFromVector(int* vector, int name, int type); … … 67 60 void InputUpdateFromConstant(int constant, int name); 68 61 void InputUpdateFromConstant(bool constant, int name); 69 void UpdateFromDakota(void* inputs);70 62 /*}}}*/ 71 63 /*Element virtual functions definitions: {{{1*/ … … 160 152 void GetSolutionFromInputsDiagnosticHoriz(Vec solution); 161 153 void GradjDragStokes(Vec gradient); 154 void InputUpdateFromSolutionDiagnosticHoriz( double* solution); 155 void InputUpdateFromSolutionSlopeCompute( double* solution); 156 void InputUpdateFromSolutionPrognostic( double* solution); 157 void InputUpdateFromSolutionPrognostic2(double* solution); 158 void InputUpdateFromSolutionBalancedthickness( double* solution); 159 void InputUpdateFromSolutionBalancedthickness2( double* solution); 160 void InputUpdateFromSolutionBalancedvelocities( double* solution); 162 161 bool IsInput(int name); 163 162 void SetClone(int* minranks); … … 165 164 void* SpawnSing(int g0); 166 165 void SurfaceNormal(double* surface_normal, double xyz_list[3][3]); 166 void UpdateFromDakota(void* inputs); 167 167 /*}}}*/ 168 168 -
issm/trunk/src/c/objects/Node.cpp
r4248 r4285 151 151 analysis_type==PrognosticAnalysisEnum || 152 152 analysis_type==MeltingAnalysisEnum || 153 analysis_type==SlopeAnalysisEnum || 153 analysis_type==BedSlopeAnalysisEnum || 154 analysis_type==SurfaceSlopeAnalysisEnum || 154 155 analysis_type==BalancedvelocitiesAnalysisEnum || 155 156 analysis_type==BalancedthicknessAnalysisEnum -
issm/trunk/src/c/shared/Dofs/DistributeNumDofs.cpp
r4055 r4285 25 25 numdofs=2; 26 26 } 27 else if (analysis_type== SlopeAnalysisEnum){27 else if (analysis_type==BedSlopeAnalysisEnum || analysis_type==SurfaceSlopeAnalysisEnum){ 28 28 numdofs=1; 29 29 } -
issm/trunk/src/c/solutions/adjoint_core.cpp
r4085 r4285 20 20 char* solverstring=NULL; 21 21 bool isstokes=false; 22 bool conserve_loads=true; 22 bool conserve_loads=true; 23 int dim; 24 int solution_type; 23 25 24 26 /*intermediary: */ … … 37 39 femmodel->parameters->FindParam(&verbose,VerboseEnum); 38 40 femmodel->parameters->FindParam(&isstokes,IsStokesEnum); 41 femmodel->parameters->FindParam(&dim,DimEnum); 42 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 39 43 40 44 /*set analysis type to compute velocity: */ … … 72 76 InputUpdateFromSolutionx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,adjoint_g); 73 77 78 if(verbose)_printf_("saving results:\n"); 79 if(solution_type==AdjointAnalysisEnum){ 80 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,AdjointxEnum); 81 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,AdjointyEnum); 82 if(dim==3) InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,AdjointzEnum); 83 } 84 74 85 /*Free ressources:*/ 75 86 xfree((void**)&solverstring); -
issm/trunk/src/c/solutions/balancedthickness2_core.cpp
r4073 r4285 17 17 int verbose=0; 18 18 int dim; 19 int solution_type; 19 20 20 21 /*activate formulation: */ … … 24 25 femmodel->parameters->FindParam(&verbose,VerboseEnum); 25 26 femmodel->parameters->FindParam(&dim,DimEnum); 27 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 26 28 27 29 _printf_("depth averaging velocity...\n"); … … 42 44 43 45 if(verbose)_printf_("saving results:\n"); 44 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 46 if(solution_type==Balancedthickness2AnalysisEnum){ 47 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 48 } 49 45 50 46 51 } -
issm/trunk/src/c/solutions/balancedthickness_core.cpp
r4073 r4285 17 17 int verbose=0; 18 18 int dim; 19 int solution_type; 19 20 20 21 /*activate formulation: */ … … 24 25 femmodel->parameters->FindParam(&verbose,VerboseEnum); 25 26 femmodel->parameters->FindParam(&dim,DimEnum); 27 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 26 28 27 29 _printf_("depth averaging velocity...\n"); … … 37 39 38 40 if(verbose)_printf_("saving results:\n"); 39 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 41 if(solution_type==BalancedthicknessAnalysisEnum){ 42 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 43 } 40 44 41 45 } -
issm/trunk/src/c/solutions/balancedvelocities_core.cpp
r4073 r4285 16 16 int verbose=0; 17 17 int dim; 18 int solution_type; 18 19 19 20 /*activate formulation: */ … … 23 24 femmodel->parameters->FindParam(&verbose,VerboseEnum); 24 25 femmodel->parameters->FindParam(&dim,DimEnum); 26 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 25 27 26 28 _printf_("depth averaging velocity...\n"); … … 37 39 38 40 if(verbose)_printf_("saving results:\n"); 39 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 40 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 41 if(solution_type==BalancedvelocitiesAnalysisEnum){ 42 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 43 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 44 } 41 45 42 46 } -
issm/trunk/src/c/solutions/bedslope.cpp
r4236 r4285 37 37 double start_init, finish_init; 38 38 39 int analyses[1]={ SlopeAnalysisEnum};40 int solution_type= SlopeAnalysisEnum;39 int analyses[1]={BedSlopeAnalysisEnum}; 40 int solution_type=BedSlopeAnalysisEnum; 41 41 42 42 MODULEBOOT(); -
issm/trunk/src/c/solutions/bedslope_core.cpp
r4064 r4285 13 13 14 14 /*parameters: */ 15 int verbose;16 int dim;15 int verbose; 16 int dim; 17 17 bool isstokes; 18 18 bool ishutter; 19 int solution_type; 19 20 20 21 /*Recover some parameters: */ 21 22 femmodel->parameters->FindParam(&verbose,VerboseEnum); 22 23 femmodel->parameters->FindParam(&dim,DimEnum); 24 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 23 25 24 26 if(verbose)_printf_("%s\n","computing slope..."); … … 38 40 39 41 if(verbose)_printf_("saving results:\n"); 40 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedSlopeXEnum); 41 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedSlopeYEnum); 42 if(solution_type==BedSlopeAnalysisEnum){ 43 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedSlopeXEnum); 44 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedSlopeYEnum); 45 } 42 46 43 47 } -
issm/trunk/src/c/solutions/control_core.cpp
r4079 r4285 26 26 double cm_max; 27 27 int cm_gradient; 28 int dim; 28 29 29 30 double* fit=NULL; … … 57 58 femmodel->parameters->FindParam(&cm_gradient,CmGradientEnum); 58 59 femmodel->parameters->FindParam(&control_steady,ControlSteadyEnum); 60 femmodel->parameters->FindParam(&dim,DimEnum); 59 61 /*}}}*/ 60 62 … … 116 118 /*some results not computed by steadystate_core or diagnostic_core: */ 117 119 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,control_type); //the parameter itself! 120 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 121 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 122 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VelEnum); 123 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,GradientEnum); 124 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,AdjointxEnum); 125 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,AdjointyEnum); 126 if(dim==3)InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum); 118 127 femmodel->results->AddObject(new DoubleVecExternalResult(femmodel->results->Size()+1,JEnum,J,nsteps,1,0)); 119 128 femmodel->results->AddObject(new StringExternalResult(femmodel->results->Size()+1,ControlTypeEnum,EnumAsString(control_type),1,0)); -
issm/trunk/src/c/solutions/diagnostic_core.cpp
r4253 r4285 24 24 bool conserve_loads=true; 25 25 bool modify_loads=true; 26 int solution_type; 26 27 27 28 /* recover parameters:*/ … … 33 34 femmodel->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum); 34 35 femmodel->parameters->FindParam(&qmu_analysis,QmuAnalysisEnum); 36 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 35 37 36 38 /*for qmu analysis, reinitialize velocity so that fake sensitivities do not show up as a result of a different restart of the convergence at each trial.*/ … … 85 87 86 88 if(verbose)_printf_("saving results:\n"); 87 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 88 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 89 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VelEnum); 90 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum); 91 if(dim==3) InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum); 92 89 if(solution_type==DiagnosticAnalysisEnum){ 90 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 91 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 92 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VelEnum); 93 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum); 94 if(dim==3) InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum); 95 } 93 96 } -
issm/trunk/src/c/solutions/prognostic2_core.cpp
r4055 r4285 15 15 /*flags: */ 16 16 int verbose=0; 17 int solution_type; 17 18 18 19 /*activate formulation: */ … … 21 22 /*recover parameters: */ 22 23 femmodel->parameters->FindParam(&verbose,VerboseEnum); 24 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 23 25 24 26 _printf_("depth averaging velocity...\n"); … … 35 37 36 38 if(verbose)_printf_("saving results:\n"); 37 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 39 if(solution_type==Prognostic2AnalysisEnum){ 40 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 41 } 38 42 39 43 } -
issm/trunk/src/c/solutions/prognostic_core.cpp
r4073 r4285 15 15 /*parameters: */ 16 16 int verbose=0; 17 int solution_type; 17 18 18 19 /*activate formulation: */ … … 21 22 /*recover parameters: */ 22 23 femmodel->parameters->FindParam(&verbose,VerboseEnum); 24 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 23 25 24 26 _printf_("depth averaging velocity...\n"); … … 33 35 34 36 if(verbose)_printf_("saving results:\n"); 35 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 37 if(solution_type==PrognosticAnalysisEnum){ 38 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum); 39 } 36 40 37 41 } -
issm/trunk/src/c/solutions/steadystate_core.cpp
r4125 r4285 20 20 int verbose; 21 21 int dim; 22 int solution_type; 22 23 23 24 /* recover parameters:*/ 24 25 femmodel->parameters->FindParam(&verbose,VerboseEnum); 25 26 femmodel->parameters->FindParam(&dim,DimEnum); 27 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 26 28 27 29 /*intialize counters: */ … … 56 58 57 59 if(verbose)_printf_("saving results:\n"); 58 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 59 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 60 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum); 61 if(dim==3) InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum); 62 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum); 60 if(solution_type==SteadystateAnalysisEnum){ 61 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum); 62 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum); 63 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum); 64 if(dim==3) InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum); 65 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum); 66 } 63 67 } -
issm/trunk/src/c/solutions/surfaceslope.cpp
r4236 r4285 37 37 double start_init, finish_init; 38 38 39 int analyses[1]={S lopeAnalysisEnum};40 int solution_type=S lopeAnalysisEnum;39 int analyses[1]={SurfaceSlopeAnalysisEnum}; 40 int solution_type=SurfaceSlopeAnalysisEnum; 41 41 42 42 MODULEBOOT(); -
issm/trunk/src/c/solutions/surfaceslope_core.cpp
r4064 r4285 17 17 bool isstokes; 18 18 bool ishutter; 19 int solution_type; 19 20 20 21 /*Recover some parameters: */ 21 22 femmodel->parameters->FindParam(&verbose,VerboseEnum); 22 23 femmodel->parameters->FindParam(&dim,DimEnum); 24 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 23 25 24 26 if(verbose)_printf_("%s\n","computing slope..."); … … 38 40 39 41 if(verbose)_printf_("saving results:\n"); 40 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceSlopeXEnum); 41 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceSlopeYEnum); 42 if(solution_type==SurfaceSlopeAnalysisEnum){ 43 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceSlopeXEnum); 44 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceSlopeYEnum); 45 } 42 46 43 47 } -
issm/trunk/src/c/solutions/thermal_core.cpp
r4055 r4285 23 23 double dt; 24 24 double melting_offset; 25 int solution_type; 25 26 26 27 //first recover parameters common to all solutions … … 28 29 femmodel->parameters->FindParam(&ndt,NdtEnum); 29 30 femmodel->parameters->FindParam(&dt,DtEnum); 31 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 30 32 31 33 /*Compute number of time steps: */ … … 46 48 47 49 if(verbose)_printf_("saving results:\n"); 48 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum,i,time); 49 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,MeltingRateEnum,i,time); 50 if(solution_type==ThermalAnalysisEnum){ 51 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum,i,time); 52 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,MeltingRateEnum,i,time); 53 } 50 54 51 55 } -
issm/trunk/src/c/solutions/transient2d_core.cpp
r4055 r4285 18 18 double finaltime; 19 19 double dt; 20 int solution_type; 20 21 21 22 /*intermediary: */ … … 27 28 femmodel->parameters->FindParam(&finaltime,NdtEnum); 28 29 femmodel->parameters->FindParam(&dt,DtEnum); 30 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 29 31 30 32 /*initialize: */ … … 36 38 _printf_("%s%g%s%i%s%g\n","time [yr]: ",time," iteration number: ",step,"/",floor(finaltime/dt)); 37 39 40 /*Set step and time: */ 41 time+=dt; 38 42 step+=1; 39 time+=dt;40 43 41 44 if(verbose)_printf_("%s\n","computing new velocity"); … … 49 52 50 53 if(verbose)_printf_("%s\n","saving results:\n"); 51 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum,step,time); 52 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum,step,time); 53 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum,step,time); 54 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum,step,time); 55 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceEnum,step,time); 56 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedEnum,step,time); 54 if(solution_type==Transient2DAnalysisEnum){ 55 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum,step,time); 56 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum,step,time); 57 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VelEnum,step,time); 58 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum,step,time); 59 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum,step,time); 60 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceEnum,step,time); 61 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedEnum,step,time); 62 } 57 63 } 58 64 -
issm/trunk/src/c/solutions/transient3d_core.cpp
r4211 r4285 18 18 double finaltime; 19 19 double dt; 20 int solution_type; 20 21 21 22 /*intermediary: */ … … 27 28 femmodel->parameters->FindParam(&finaltime,NdtEnum); 28 29 femmodel->parameters->FindParam(&dt,DtEnum); 30 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 29 31 30 32 /*initialize: */ … … 58 60 59 61 if(verbose)_printf_("%s\n","saving results:\n"); 60 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum,step,time); 61 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum,step,time); 62 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum,step,time); 63 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum,step,time); 64 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum,step,time); 65 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceEnum,step,time); 66 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedEnum,step,time); 67 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum,step,time); 68 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,MeltingRateEnum,step,time); 62 if(solution_type==Transient3DAnalysisEnum){ 63 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum,step,time); 64 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum,step,time); 65 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum,step,time); 66 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum,step,time); 67 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,ThicknessEnum,step,time); 68 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,SurfaceEnum,step,time); 69 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,BedEnum,step,time); 70 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum,step,time); 71 InputToResultx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,MeltingRateEnum,step,time); 72 } 69 73 70 74 if (step%5==0){
Note:
See TracChangeset
for help on using the changeset viewer.