Changeset 23189 for issm/trunk/src/c/classes
- Timestamp:
- 08/28/18 09:45:51 (7 years ago)
- Location:
- issm/trunk
- Files:
-
- 61 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
- Property svn:mergeinfo changed
/issm/trunk-jpl merged: 22823-22871,22873-22887,22894-22903,22905-23090,23092-23185,23187
- Property svn:mergeinfo changed
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/c/classes/AdaptiveMeshRefinement.cpp
r22758 r23189 100 100 101 101 /*Mesh refinement methods*/ 102 void AdaptiveMeshRefinement::ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist){/*{{{*/103 102 void AdaptiveMeshRefinement::ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int** pdatalist,double** pxylist,int** pelementslist){/*{{{*/ 103 104 104 /*IMPORTANT! pelementslist are in Matlab indexing*/ 105 105 /*NEOPZ works only in C indexing*/ … … 118 118 /*Intermediaries*/ 119 119 bool verbose=VerboseSolution(); 120 120 121 121 /*Execute refinement*/ 122 122 this->RefineMeshOneLevel(verbose,gl_distance,if_distance,deviatoricerror,thicknesserror); 123 123 124 124 /*Get new geometric mesh in ISSM data structure*/ 125 this->GetMesh(this->previousmesh,p newnumberofvertices,pnewnumberofelements,px,py,pelementslist);125 this->GetMesh(this->previousmesh,pdatalist,pxylist,pelementslist); 126 126 127 127 /*Verify the new geometry*/ 128 this->CheckMesh(p newnumberofvertices,pnewnumberofelements,px,py,pelementslist);128 this->CheckMesh(pdatalist,pxylist,pelementslist); 129 129 } 130 130 /*}}}*/ 131 131 void AdaptiveMeshRefinement::RefineMeshOneLevel(bool &verbose,double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror){/*{{{*/ 132 132 133 133 /*Intermediaries*/ 134 134 int nelem =-1; … … 204 204 } 205 205 /*}}}*/ 206 206 207 207 /*Now, detele the special elements{{{*/ 208 208 if(this->refinement_type==1) this->DeleteSpecialElements(verbose,gmesh); … … 216 216 } 217 217 /*}}}*/ 218 218 219 219 /*Unrefinement process: loop over level of refinements{{{*/ 220 220 if(verbose) _printf_("\tunrefinement process...\n"); 221 221 if(verbose) _printf_("\ttotal: "); 222 222 count=0; 223 223 224 224 nelem=gmesh->NElements();//must keep here 225 225 for(int i=0;i<nelem;i++){ … … 266 266 gmesh->BuildConnectivity(); 267 267 /*}}}*/ 268 268 269 269 /*Refinement process: loop over level of refinements{{{*/ 270 270 if(verbose) _printf_("\trefinement process (level max = "<<this->level_max<<")\n"); … … 320 320 * */ 321 321 if(!geoel) _error_("geoel is NULL!\n"); 322 322 323 323 /*Output*/ 324 324 int type=0; 325 325 int count=0; 326 326 327 327 /*Intermediaries*/ 328 328 TPZVec<TPZGeoEl*> sons; 329 329 330 330 /*Loop over neighboors (sides 3, 4 and 5)*/ 331 331 for(int j=3;j<6;j++){ … … 335 335 if(sons.size()>4) count++; //if neighbour's level is > element level+1 336 336 } 337 337 338 338 /*Verify and return*/ 339 339 if(count>1) type=2; 340 340 else type=count; 341 341 342 342 return type; 343 343 } … … 391 391 /*}}}*/ 392 392 void AdaptiveMeshRefinement::RefineMeshToAvoidHangingNodes(bool &verbose,TPZGeoMesh* gmesh){/*{{{*/ 393 393 394 394 /*Now, insert special elements to avoid hanging nodes*/ 395 395 if(verbose) _printf_("\trefining to avoid hanging nodes (total: "); 396 396 397 397 /*Intermediaries*/ 398 398 int nelem=-1; 399 399 int count= 1; 400 400 401 401 while(count>0){ 402 402 nelem=gmesh->NElements();//must keep here … … 449 449 } 450 450 /*}}}*/ 451 void AdaptiveMeshRefinement::GetMesh(TPZGeoMesh* gmesh,int* nvertices,int* nelements,double** px,double** py, int** pelements){/*{{{*/451 void AdaptiveMeshRefinement::GetMesh(TPZGeoMesh* gmesh,int** pdata,double** pxy, int** pelements){/*{{{*/ 452 452 453 453 /* IMPORTANT! pelements are in Matlab indexing … … 462 462 int ntotalvertices = gmesh->NNodes(); 463 463 int* newelements = NULL; 464 double* newmeshX= NULL;465 double* newmesh Y = NULL;464 int* newdata = NULL; 465 double* newmeshXY = NULL; 466 466 TPZGeoEl* geoel = NULL; 467 467 long* vertex_index2sid = xNew<long>(ntotalvertices); 468 468 this->index2sid.clear(); this->index2sid.resize(gmesh->NElements()); 469 469 this->sid2index.clear(); 470 470 471 471 /*Fill in the vertex_index2sid vector with non usual index value*/ 472 472 for(int i=0;i<gmesh->NNodes();i++) vertex_index2sid[i]=-1; 473 473 474 474 /*Fill in the this->index2sid vector with non usual index value*/ 475 475 for(int i=0;i<gmesh->NElements();i++) this->index2sid[i]=-1; 476 476 477 477 /*Get elements without sons and fill in the vertex_index2sid with used vertices (indexes) */ 478 478 sid=0; … … 494 494 } 495 495 496 /* Create new mesh structure and fill it */ 496 497 nconformelements = (int)this->sid2index.size(); 497 498 nconformvertices = (int)sid; 498 499 newelements = xNew<int>(nconformelements*this->GetNumberOfNodes()); 499 newmeshX = xNew<double>(nconformvertices); 500 newmeshY = xNew<double>(nconformvertices); 500 newmeshXY = xNew<double>(nconformvertices*2); 501 newdata = xNew<int>(2); 502 newdata[0] = nconformvertices; 503 newdata[1] = nconformelements; 501 504 502 505 for(int i=0;i<ntotalvertices;i++){//over the TPZNode index (fill in the ISSM vertices coords) … … 505 508 TPZVec<REAL> coords(3,0.); 506 509 gmesh->NodeVec()[i].GetCoordinates(coords); 507 newmeshX [sid] = coords[0];508 newmesh Y[sid] = coords[1];509 } 510 510 newmeshXY[2*sid] = coords[0]; // X 511 newmeshXY[2*sid+1] = coords[1]; // Y 512 } 513 511 514 for(int i=0;i<this->sid2index.size();i++){//over the sid (fill the ISSM elements) 512 515 for(int j=0;j<this->GetNumberOfNodes();j++) { … … 525 528 c=newelements[i*this->GetNumberOfNodes()+2]-1; 526 529 527 xa=newmeshX [a]; ya=newmeshY[a];528 xb=newmeshX [b]; yb=newmeshY[b];529 xc=newmeshX [c]; yc=newmeshY[c];530 xa=newmeshXY[2*a]; ya=newmeshXY[2*a+1]; 531 xb=newmeshXY[2*b]; yb=newmeshXY[2*b+1]; 532 xc=newmeshXY[2*c]; yc=newmeshXY[2*c+1]; 530 533 531 534 detJ=(xb-xa)*(yc-ya)-(xc-xa)*(yb-ya); 532 535 533 536 /*verify and swap, if necessary*/ 534 537 if(detJ<0) { … … 539 542 540 543 /*Setting outputs*/ 541 *nvertices = nconformvertices; 542 *nelements = nconformelements; 543 *px = newmeshX; 544 *py = newmeshY; 544 *pdata = newdata; 545 *pxy = newmeshXY; 545 546 *pelements = newelements; 546 547 547 548 /*Cleanup*/ 548 549 xDelete<long>(vertex_index2sid); … … 553 554 /* IMPORTANT! elements come in Matlab indexing 554 555 NEOPZ works only in C indexing*/ 555 556 556 557 if(nvertices<=0) _error_("Impossible to create initial mesh: nvertices is <= 0!\n"); 557 558 if(nelements<=0) _error_("Impossible to create initial mesh: nelements is <= 0!\n"); … … 560 561 /*Verify and creating initial mesh*/ 561 562 if(this->fathermesh || this->previousmesh) _error_("Initial mesh already exists!"); 562 563 563 564 this->fathermesh = new TPZGeoMesh(); 564 565 this->fathermesh->NodeVec().Resize(nvertices); … … 575 576 this->fathermesh->NodeVec()[i].SetNodeId(i); 576 577 } 577 578 578 579 /*Generate the elements*/ 579 580 long index; … … 603 604 /*}}}*/ 604 605 TPZGeoMesh* AdaptiveMeshRefinement::CreateRefPatternMesh(TPZGeoMesh* gmesh){/*{{{*/ 605 606 606 607 TPZGeoMesh *newgmesh = new TPZGeoMesh(); 607 608 newgmesh->CleanUp(); 608 609 609 610 int nnodes = gmesh->NNodes(); 610 611 int nelem = gmesh->NElements(); … … 616 617 newgmesh->NodeVec().Resize(nnodes); 617 618 for(int i=0;i<nnodes;i++) newgmesh->NodeVec()[i] = gmesh->NodeVec()[i]; 618 619 619 620 //elements 620 621 for(int i=0;i<nelem;i++){ 621 622 TPZGeoEl * geoel = gmesh->Element(i); 622 623 623 624 if(!geoel){ 624 625 index=newgmesh->ElementVec().AllocateNewElement(); … … 626 627 continue; 627 628 } 628 629 629 630 TPZManVector<long> elem(3,0); 630 631 for(int j=0;j<3;j++) elem[j] = geoel->NodeIndex(j); 631 632 632 633 newgmesh->CreateGeoElement(ETriangle,elem,mat,index,reftype); 633 634 newgmesh->ElementVec()[index]->SetId(geoel->Id()); 634 635 635 636 TPZGeoElRefPattern<TPZGeoTriangle>* newgeoel = dynamic_cast<TPZGeoElRefPattern<TPZGeoTriangle>*>(newgmesh->ElementVec()[index]); 636 637 637 638 //old neighbourhood 638 639 const int nsides = TPZGeoTriangle::NSides; … … 653 654 } 654 655 } 655 656 656 657 //inserting in new element 657 658 for(int s = 0; s < nsides; s++){ … … 667 668 tempEl->SetNeighbour(byside, tempSide); 668 669 } 669 670 670 671 long fatherindex = geoel->FatherIndex(); 671 672 if(fatherindex>-1) newgeoel->SetFather(fatherindex); 672 673 673 674 if(!geoel->HasSubElement()) continue; 674 675 675 676 int nsons = geoel->NSubElements(); 676 677 677 678 TPZAutoPointer<TPZRefPattern> ref = gRefDBase.GetUniformRefPattern(ETriangle); 678 679 newgeoel->SetRefPattern(ref); 679 680 680 681 for(int j=0;j<nsons;j++){ 681 682 TPZGeoEl* son = geoel->SubElement(j); … … 689 690 /*Now, build connectivities*/ 690 691 newgmesh->BuildConnectivity(); 691 692 692 693 return newgmesh; 693 694 } 694 695 /*}}}*/ 695 void AdaptiveMeshRefinement::CheckMesh(int* nvertices,int* nelements,double** px,double** py,int** pelements){/*{{{*/696 void AdaptiveMeshRefinement::CheckMesh(int** pdata,double** pxy,int** pelements){/*{{{*/ 696 697 697 698 /*Basic verification*/ 698 if( nvertices<=0) _error_("Impossible to continue: nvertices <=0!\n");699 if( nelements<=0) _error_("Impossible to continue: nelements <=0!\n");700 if( !px) _error_("Impossible to continue: px is NULL!\n");701 if(!p y) _error_("Impossible to continue: py is NULL!\n");699 if(!pdata) _error_("Impossible to continue: pdata is NULL!\n"); 700 if(pdata[0]<=0) _error_("Impossible to continue: nvertices <=0!\n"); 701 if(pdata[1]<=0) _error_("Impossible to continue: nelements <=0!\n"); 702 if(!pxy) _error_("Impossible to continue: pxy is NULL!\n"); 702 703 if(!pelements) _error_("Impossible to continue: pelements is NULL!\n"); 703 704 /*Verify if there are orphan nodes*/705 std::set<int> elemvertices;706 elemvertices.clear();707 for(int i=0;i<*nelements;i++){708 for(int j=0;j<this->GetNumberOfNodes();j++) {709 elemvertices.insert((*pelements)[i*this->GetNumberOfNodes()+j]);710 }711 }712 if(elemvertices.size()!=*nvertices) _error_("Impossible to continue: elemvertices.size() != nvertices!\n");713 714 //Verify if there are inf or NaN in coords715 for(int i=0;i<*nvertices;i++){716 if(std::isnan((*px)[i]) || std::isinf((*px)[i])) _error_("Impossible to continue: px i=" << i <<" is NaN or Inf!\n");717 if(std::isnan((*py)[i]) || std::isinf((*py)[i])) _error_("Impossible to continue: py i=" << i <<" is NaN or Inf!\n");718 }719 for(int i=0;i<*nelements;i++){720 for(int j=0;j<this->GetNumberOfNodes();j++){721 if(std::isnan((*pelements)[i*GetNumberOfNodes()+j])) _error_("Impossible to continue: px i=" << i <<" is NaN!\n");722 if(std::isinf((*pelements)[i*GetNumberOfNodes()+j])) _error_("Impossible to continue: px i=" << i <<" is Inf!\n");723 }724 }725 726 704 } 727 705 /*}}}*/ 728 706 void AdaptiveMeshRefinement::PrintGMeshVTK(TPZGeoMesh* gmesh,std::ofstream &file,bool matColor){/*{{{*/ 729 707 730 708 file.clear(); 731 709 long nelements = gmesh->NElements(); … … 753 731 MElementType elt = gel->Type(); 754 732 int elNnodes = MElementType_NNodes(elt); 755 733 756 734 size += (1+elNnodes); 757 735 connectivity << elNnodes; 758 736 759 737 for(int t = 0; t < elNnodes; t++) 760 738 { … … 765 743 } 766 744 node << std::endl; 767 745 768 746 actualNode++; 769 747 connectivity << " " << actualNode; 770 748 } 771 749 connectivity << std::endl; 772 750 773 751 int elType = this->GetVTK_ElType(gel); 774 752 type << elType << std::endl; 775 753 776 754 if(matColor == true) 777 755 { … … 782 760 material << gel->Index() << std::endl; 783 761 } 784 762 785 763 nVALIDelements++; 786 764 } … … 812 790 /*}}}*/ 813 791 int AdaptiveMeshRefinement::GetVTK_ElType(TPZGeoEl * gel){/*{{{*/ 814 792 815 793 MElementType pzElType = gel->Type(); 816 794 817 795 int elType = -1; 818 796 switch (pzElType) … … 871 849 DebugStop(); 872 850 } 873 851 874 852 return elType; 875 853 } 876 854 /*}}}*/ 877 -
issm/trunk/src/c/classes/AdaptiveMeshRefinement.h
r22758 r23189 67 67 void CleanUp(); 68 68 void Initialize(); 69 void ExecuteRefinement(int numberofpoints,double* xylist,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist); 70 void ExecuteRefinement(int numberofpoints,double* xylist,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist); 71 void ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist); 69 void ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int** pdatalist,double** pxy,int** pelementslist); 72 70 void CreateInitialMesh(int &nvertices,int &nelements,double* x,double* y,int* elements); 73 void CheckMesh(int* nvertices,int* nelements,double** px,double** py,int** pelements);71 void CheckMesh(int** pdata,double** pxy,int** pelements); 74 72 /*}}}*/ 75 73 private: … … 86 84 void RefineMeshToAvoidHangingNodes(bool &verbose,TPZGeoMesh* gmesh); 87 85 void DeleteSpecialElements(bool &verbose,TPZGeoMesh* gmesh); 88 void GetMesh(TPZGeoMesh* gmesh,int* nvertices,int* nelements,double** px,double** py,int** pelements);86 void GetMesh(TPZGeoMesh* gmesh,int** pdata,double** pxy,int** pelements); 89 87 TPZGeoMesh* CreateRefPatternMesh(TPZGeoMesh* gmesh); 90 88 inline int GetElemMaterialID(){return 1;} -
issm/trunk/src/c/classes/AmrBamg.cpp
r22758 r23189 34 34 this->deviatoricerror_groupthreshold = -1; 35 35 this->deviatoricerror_maximum = -1; 36 36 37 37 /*Geometry and mesh as NULL*/ 38 38 this->geometry = NULL; … … 98 98 delete Th; 99 99 }/*}}}*/ 100 void AmrBamg::ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int* pnewnumberofvertices,int *pnewnumberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist){/*{{{*/100 void AmrBamg::ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int** pdatalist,IssmDouble** pxylist,int** pelementslist){/*{{{*/ 101 101 102 102 /*Intermediaries*/ … … 137 137 this->options->hmaxVerticesSize[0] = 0; 138 138 this->options->hmaxVerticesSize[1] = 0; 139 139 140 140 /*verify if the metric will be reseted or not*/ 141 141 if(this->keepmetric==0){ … … 150 150 151 151 /*Prepare output*/ 152 int nbv = meshout->VerticesSize[0]; 153 int nbt = meshout->TrianglesSize[0]; 154 IssmDouble *x = xNew<IssmDouble>(nbv); 155 IssmDouble *y = xNew<IssmDouble>(nbv); 156 IssmDouble *z = xNew<IssmDouble>(nbv); 152 int nbv = meshout->VerticesSize[0]; 153 int nbt = meshout->TrianglesSize[0]; 154 int *datalist = xNew<int>(2); 155 IssmDouble *xylist= xNew<IssmDouble>(nbv*2); 156 int* elementslist = xNew<int>(nbt*3); 157 158 datalist[0] = nbv; 159 datalist[1] = nbt; 160 157 161 for(int i=0;i<nbv;i++){ 158 x[i] = meshout->Vertices[i*3+0]; 159 y[i] = meshout->Vertices[i*3+1]; 160 z[i] = 0.; 162 xylist[2*i] = meshout->Vertices[i*3+0]; 163 xylist[2*i+1] = meshout->Vertices[i*3+1]; 161 164 } 162 int* elementslist= xNew<int>(nbt*3); 165 163 166 for(int i=0;i<nbt;i++){ 164 167 elementslist[3*i+0] = reCast<int>(meshout->Triangles[4*i+0]); … … 167 170 } 168 171 172 /*Assign pointers*/ 173 *pdatalist = datalist; 174 *pxylist = xylist; 175 *pelementslist = elementslist; 176 169 177 /*Cleanup and return*/ 170 178 delete geomout; 171 *pnewnumberofvertices = nbv;172 *pnewnumberofelements = nbt;173 *px = x;174 *py = y;175 *pz = z;176 *pelementslist = elementslist;177 179 }/*}}}*/ 178 180 void AmrBamg::SetBamgOpts(IssmDouble hmin_in,IssmDouble hmax_in,IssmDouble err_in,IssmDouble gradation_in){/*{{{*/ 179 181 180 182 if(!this->options) _error_("AmrBamg->options is NULL!"); 181 183 182 184 this->options->hmin = hmin_in; 183 185 this->options->hmax = hmax_in; -
issm/trunk/src/c/classes/AmrBamg.h
r22758 r23189 35 35 /*General methods*/ 36 36 void Initialize(int* elements,IssmDouble* x,IssmDouble* y,int numberofvertices,int numberofelements); 37 void ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int* pnewnumberofvertices,int *pnewnumberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist);37 void ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int** pdatalist,IssmDouble** pxylist,int** pelementslist); 38 38 void SetBamgOpts(IssmDouble hmin_in,IssmDouble hmax_in,IssmDouble err_in,IssmDouble gradation_in); 39 39 -
issm/trunk/src/c/classes/Cfdragcoeffabsgrad.cpp
r22758 r23189 23 23 #include "../classes/gauss/Gauss.h" 24 24 /*}}}*/ 25 25 26 26 /*Cfdragcoeffabsgrad constructors, destructors :*/ 27 27 Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(){/*{{{*/ … … 32 32 this->misfit=0; 33 33 this->lock=0; 34 this->datatime=0.;35 34 this->timepassedflag = false; 36 35 this->last_time = 0.; … … 38 37 } 39 38 /*}}}*/ 40 Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, IssmDouble in_datatime,bool in_timepassedflag){/*{{{*/39 Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, bool in_timepassedflag){/*{{{*/ 41 40 42 41 this->definitionenum=in_definitionenum; 43 42 44 43 this->name = xNew<char>(strlen(in_name)+1); 45 44 xMemCpy<char>(this->name,in_name,strlen(in_name)+1); 46 45 47 46 this->weights_enum=in_weights_enum; 48 this->datatime=in_datatime;49 47 this->timepassedflag=in_timepassedflag; 50 48 51 49 this->misfit=0; 52 50 this->lock=0; … … 61 59 /*Object virtual function resolutoin: */ 62 60 Object* Cfdragcoeffabsgrad::copy() {/*{{{*/ 63 Cfdragcoeffabsgrad* mf = new Cfdragcoeffabsgrad(this->name,this->definitionenum, this->weights_enum,this-> datatime,this->timepassedflag);61 Cfdragcoeffabsgrad* mf = new Cfdragcoeffabsgrad(this->name,this->definitionenum, this->weights_enum,this->timepassedflag); 64 62 mf->misfit=this->misfit; 65 63 mf->lock=this->lock; … … 74 72 _printf_(" Cfdragcoeffabsgrad: " << name << " " << this->definitionenum << "\n"); 75 73 _printf_(" weights_enum: " << weights_enum << " " << EnumToStringx(weights_enum) << "\n"); 76 _printf_(" datatime: " << datatime << "\n");77 74 _printf_(" timepassedflag: "<<timepassedflag<<"\n"); 78 75 } … … 105 102 /*diverse: */ 106 103 IssmDouble time; 107 104 108 105 /*recover time parameters: */ 109 femmodel->parameters->FindParam(&time,TimeEnum);110 if(time < last_time) timepassedflag = false;111 last_time = time;112 113 106 int i; 114 107 IssmDouble J=0.; 115 108 IssmDouble J_sum=0.; 116 109 117 if(datatime<=time && !timepassedflag){118 110 for(i=0;i<femmodel->elements->Size();i++){ 119 111 Element* element=(Element*)femmodel->elements->GetObjectByOffset(i); … … 124 116 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 125 117 J=J_sum; 126 118 127 119 timepassedflag = true; 128 120 return J; 129 }130 else return J;131 121 } 132 122 /*}}}*/ … … 193 183 return Jelem; 194 184 }/*}}}*/ 195 -
issm/trunk/src/c/classes/Cfdragcoeffabsgrad.h
r22758 r23189 20 20 char* name; 21 21 int weights_enum; 22 IssmDouble datatime;23 22 bool timepassedflag; 24 23 IssmDouble last_time; … … 29 28 /*Cfdragcoeffabsgrad constructors, destructors :*/ 30 29 Cfdragcoeffabsgrad(); 31 Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, IssmDouble in_datatime,bool timepassedflag);30 Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, bool timepassedflag); 32 31 ~Cfdragcoeffabsgrad(); 33 32 -
issm/trunk/src/c/classes/Cfsurfacelogvel.cpp
r22758 r23189 23 23 #include "../classes/gauss/Gauss.h" 24 24 /*}}}*/ 25 25 26 26 /*Cfsurfacelogvel constructors, destructors :*/ 27 27 Cfsurfacelogvel::Cfsurfacelogvel(){/*{{{*/ … … 40 40 41 41 this->definitionenum=in_definitionenum; 42 42 43 43 this->name = xNew<char>(strlen(in_name)+1); 44 44 xMemCpy<char>(this->name,in_name,strlen(in_name)+1); … … 46 46 this->datatime=in_datatime; 47 47 this->timepassedflag=in_timepassedflag; 48 48 49 49 this->misfit=0; 50 50 this->lock=0; … … 100 100 /*}}}*/ 101 101 IssmDouble Cfsurfacelogvel::Response(FemModel* femmodel){/*{{{*/ 102 102 103 103 /*diverse: */ 104 104 IssmDouble time; 105 105 106 106 /*recover time parameters: */ 107 107 femmodel->parameters->FindParam(&time,TimeEnum); … … 112 112 IssmDouble J=0.; 113 113 IssmDouble J_sum=0.; 114 114 115 115 if(datatime<=time && !timepassedflag){ 116 116 for(i=0;i<femmodel->elements->Size();i++){ … … 122 122 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 123 123 J=J_sum; 124 124 125 125 timepassedflag = true; 126 126 return J; … … 139 139 IssmDouble vx,vy,vxobs,vyobs,weight; 140 140 IssmDouble* xyz_list = NULL; 141 141 142 142 /*Get basal element*/ 143 143 if(!element->IsOnSurface()) return 0.; … … 160 160 /* Get node coordinates*/ 161 161 topelement->GetVerticesCoordinates(&xyz_list); 162 162 163 163 /*Get model values*/ 164 164 Input* vx_input =topelement->GetInput(VxEnum); _assert_(vx_input); … … 174 174 if(tempinput->ObjectEnum()!=DatasetInputEnum) _error_("don't know what to do"); 175 175 datasetinput = (DatasetInput*)tempinput; 176 177 176 178 177 /* Start looping on the number of gaussian points: */ … … 222 221 return Jelem; 223 222 }/*}}}*/ 224 -
issm/trunk/src/c/classes/Cfsurfacesquare.cpp
r22758 r23189 23 23 #include "../classes/gauss/Gauss.h" 24 24 /*}}}*/ 25 25 26 26 /*Cfsurfacesquare constructors, destructors :*/ 27 27 Cfsurfacesquare::Cfsurfacesquare(){/*{{{*/ … … 43 43 44 44 this->definitionenum=in_definitionenum; 45 45 46 46 this->name = xNew<char>(strlen(in_name)+1); 47 47 xMemCpy<char>(this->name,in_name,strlen(in_name)+1); … … 52 52 this->datatime=in_datatime; 53 53 this->timepassedflag=in_timepassedflag; 54 54 55 55 this->misfit=0; 56 56 this->lock=0; … … 111 111 /*diverse: */ 112 112 IssmDouble time; 113 113 114 114 /*recover time parameters: */ 115 115 femmodel->parameters->FindParam(&time,TimeEnum); … … 130 130 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 131 131 J=J_sum; 132 132 133 133 timepassedflag = true; 134 134 return J; … … 172 172 /*Get input if it already exists*/ 173 173 Input* tempinput = topelement->GetInput(definitionenum); 174 174 175 175 /*Cast it to a Datasetinput*/ 176 176 if(tempinput->ObjectEnum()!=DatasetInputEnum) _error_("don't know what to do"); … … 214 214 return Jelem; 215 215 }/*}}}*/ 216 -
issm/trunk/src/c/classes/Constraints/SpcStatic.cpp
r22758 r23189 37 37 /*Object virtual functions definitions:*/ 38 38 Object* SpcStatic::copy() {/*{{{*/ 39 39 40 40 SpcStatic* spcstat = new SpcStatic(*this); 41 41 -
issm/trunk/src/c/classes/Dakota/IssmParallelDirectApplicInterface.cpp
r22758 r23189 20 20 int world_rank; 21 21 ISSM_MPI_Comm_rank(ISSM_MPI_COMM_WORLD,&world_rank); 22 22 23 23 /*Build an femmodel if you are a slave, using the corresponding communicator:*/ 24 24 if(world_rank!=0){ … … 33 33 int world_rank; 34 34 ISSM_MPI_Comm_rank(ISSM_MPI_COMM_WORLD,&world_rank); 35 35 36 36 if(world_rank!=0){ 37 37 -
issm/trunk/src/c/classes/Elements/Element.cpp
r22822 r23189 100 100 dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]); 101 101 } 102 103 102 /*Build strain rate tensor*/ 104 103 eps[0][0] = dvx[0]; eps[0][1] = .5*(dvx[1]+dvy[0]); eps[0][2] = .5*(dvx[2]+dvz[0]); … … 117 116 /*Add Stress tensor components into inputs*/ 118 117 this->AddInput(LambdaSEnum,lambdas,P1Enum); 119 118 120 119 /*Clean up and return*/ 121 120 delete gauss; … … 172 171 B_input=this->GetInput(MaterialsRheologyBEnum); _assert_(B_input); 173 172 } 174 173 175 174 /* Start looping on the number of nodes: */ 176 175 Gauss* gauss=this->NewGauss(); … … 196 195 197 196 /* Compute threshold strain rate from threshold stress */ 198 eps_0=pow(sigma_0/B,n); 197 eps_0=pow(sigma_0/B,n); 199 198 200 199 if(eps_eff>eps_0){ … … 262 261 if(dim==2){ 263 262 /* epsilon=[exx,eyy,exy];*/ 264 eps_xx[iv]=epsilon[0]; 263 eps_xx[iv]=epsilon[0]; 265 264 eps_yy[iv]=epsilon[1]; 266 265 eps_xy[iv]=epsilon[2]; … … 270 269 else{ 271 270 /*epsilon=[exx eyy ezz exy exz eyz]*/ 272 eps_xx[iv]=epsilon[0]; 271 eps_xx[iv]=epsilon[0]; 273 272 eps_yy[iv]=epsilon[1]; 274 273 eps_zz[iv]=epsilon[2]; 275 eps_xy[iv]=epsilon[3]; 274 eps_xy[iv]=epsilon[3]; 276 275 eps_xz[iv]=epsilon[4]; 277 276 eps_yz[iv]=epsilon[5]; … … 535 534 IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices); 536 535 IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices); 536 IssmDouble* TemperaturesReconstructed=xNew<IssmDouble>(12*numvertices); 537 IssmDouble* PrecipitationsReconstructed=xNew<IssmDouble>(12*numvertices); 537 538 IssmDouble* tmp=xNew<IssmDouble>(numvertices); 538 539 IssmDouble Delta18oTime; 539 540 IssmDouble dpermil,f; 540 IssmDouble time,yts,time_yr,month,time_clim ;541 IssmDouble time,yts,time_yr,month,time_clim,time_climt,time_climp,del_clim; 541 542 bool isTemperatureScaled=true; 543 bool isPrecipScaled=true; 542 544 this->parameters->FindParam(&time,TimeEnum); 543 545 this->parameters->FindParam(&yts,ConstantsYtsEnum); 544 546 this->parameters->FindParam(&f,SmbFEnum); 545 547 time_yr=floor(time/yts)*yts; 546 time_clim=time_yr; 548 time_clim=ceil(time/yts + 1e-10)*yts; 549 time_climt=ceil(time/yts + 1e-10)*yts; 550 time_climp=ceil(time/yts + 1e-10)*yts; 547 551 548 552 /*Get some pdd parameters*/ 549 553 dpermil=this->matpar->GetMaterialParameter(SmbDpermilEnum); 554 555 this->parameters->FindParam(&isTemperatureScaled,SmbIstemperaturescaledEnum); 556 this->parameters->FindParam(&isPrecipScaled,SmbIsprecipscaledEnum); 550 557 551 558 /*Recover present day temperature and precipitation*/ 552 559 Input* input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum); _assert_(input); 553 560 Input* input2=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input2); 561 Input* input3=NULL; 562 Input* input4=NULL; 554 563 int offset; 555 564 556 offset=dynamic_cast<TransientInput*>(input)->GetTimeInputOffset(time_yr); 557 if (fmod(offset,12.)!=1){ 558 time_clim=floor(dynamic_cast<TransientInput*>(input)->GetTimeByOffset(offset-fmod(offset,12.)+1)/yts)*yts; 565 offset=dynamic_cast<TransientInput*>(input)->GetTimeInputOffset(time_clim); 566 time_clim=dynamic_cast<TransientInput*>(input)->GetTimeByOffset(offset-11-fmod(offset-11,12.)); 567 568 if(!isTemperatureScaled){ 569 input3=this->inputs->GetInput(SmbTemperaturesReconstructedEnum); _assert_(input3); 570 offset=dynamic_cast<TransientInput*>(input3)->GetTimeInputOffset(time_climt); 571 time_climt=dynamic_cast<TransientInput*>(input3)->GetTimeByOffset(offset-11-fmod(offset-11,12.)); 572 } 573 if(!isPrecipScaled){ 574 input4=this->inputs->GetInput(SmbPrecipitationsReconstructedEnum); _assert_(input4); 575 offset=dynamic_cast<TransientInput*>(input4)->GetTimeInputOffset(time_climp); 576 time_climp=dynamic_cast<TransientInput*>(input4)->GetTimeByOffset(offset-11-fmod(offset-11,12.)); 559 577 } 560 578 … … 566 584 input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,time_clim+month/12.*yts); 567 585 input2->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,time_clim+month/12.*yts); 568 569 586 PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts; 587 588 if(!isTemperatureScaled){ 589 input3->GetInputValue(&TemperaturesReconstructed[iv*12+month],gauss,time_climt+month/12.*yts); 590 } 591 if(!isPrecipScaled){ 592 input4->GetInputValue(&PrecipitationsReconstructed[iv*12+month],gauss,time_climp+month/12.*yts); 593 PrecipitationsReconstructed[iv*12+month]=PrecipitationsReconstructed[iv*12+month]*yts; 594 } 595 570 596 } 571 597 } … … 573 599 /*Recover interpolation parameters at time t*/ 574 600 this->parameters->FindParam(&Delta18oTime,SmbDelta18oEnum,time); 575 this->parameters->FindParam(&isTemperatureScaled,SmbIstemperaturescaledEnum);576 601 577 602 /*Compute the temperature and precipitation*/ 578 603 for(int iv=0;iv<numvertices;iv++){ 579 ComputeD18OTemperaturePrecipitationFromPD(Delta18oTime,dpermil,isTemperatureScaled,f, 580 &PrecipitationsPresentday[iv*12], &TemperaturesPresentday[iv*12], 604 ComputeD18OTemperaturePrecipitationFromPD(Delta18oTime,dpermil,isTemperatureScaled,isPrecipScaled, 605 f,&PrecipitationsPresentday[iv*12], &TemperaturesPresentday[iv*12], 606 &PrecipitationsReconstructed[iv*12], &TemperaturesReconstructed[iv*12], 581 607 &monthlytemperatures[iv*12], &monthlyprec[iv*12]); 582 608 } … … 623 649 xDelete<IssmDouble>(TemperaturesPresentday); 624 650 xDelete<IssmDouble>(PrecipitationsPresentday); 651 xDelete<IssmDouble>(TemperaturesReconstructed); 652 xDelete<IssmDouble>(PrecipitationsReconstructed); 625 653 xDelete<IssmDouble>(tmp); 626 654 627 655 } 628 656 /*}}}*/ … … 821 849 int numnodes = this->GetNumberOfNodes(); 822 850 for(int i=0;i<numnodes;i++) { 823 _printf_("nodes[" << i << "] = " << nodes[i]); 851 _printf_("nodes[" << i << "] = " << nodes[i]); 824 852 nodes[i]->Echo(); 825 853 } … … 1027 1055 } 1028 1056 /*}}}*/ 1057 void Element::GetInputListOnVerticesAtTime(IssmDouble* pvalue, int enumtype, IssmDouble time){/*{{{*/ 1058 1059 /*Recover input*/ 1060 Input* input=this->GetInput(enumtype); 1061 if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element"); 1062 1063 /*Fetch number vertices for this element*/ 1064 int numvertices = this->GetNumberOfVertices(); 1065 1066 /*Checks in debugging mode*/ 1067 _assert_(pvalue); 1068 1069 /* Start looping on the number of vertices: */ 1070 Gauss*gauss=this->NewGauss(); 1071 for(int iv=0;iv<numvertices;iv++){ 1072 gauss->GaussVertex(iv); 1073 input->GetInputValue(&pvalue[iv],gauss,time); 1074 } 1075 1076 /*clean-up*/ 1077 delete gauss; 1078 } 1079 /*}}}*/ 1029 1080 void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/ 1030 1081 … … 1054 1105 void Element::GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug){/*{{{*/ 1055 1106 1056 1057 1107 /*Get number of nodes for this element*/ 1058 1108 int numnodes = this->GetNumberOfNodes(); … … 1070 1120 if(ug[nodes[i]->GetDof(0,GsetEnum)] > input_max) input_max = ug[nodes[i]->GetDof(0,GsetEnum)]; 1071 1121 } 1072 1073 1122 1074 1123 /*Second loop to reassign min and max with local extrema*/ … … 1195 1244 epsilon_eff=1/sqrt(2.)*sqrt(epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]); 1196 1245 1197 /*Phi = Tr(sigma * eps) 1246 /*Phi = Tr(sigma * eps) 1198 1247 * = Tr(sigma'* eps) 1199 1248 * = 2 * eps_eff * sigma'_eff … … 1310 1359 } 1311 1360 /*}}}*/ 1361 void Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum,int type, IssmDouble time){/*{{{*/ 1362 1363 /*Fetch number vertices for this element and allocate arrays*/ 1364 int numvertices = this->GetNumberOfVertices(); 1365 int numnodes = this->GetNumberOfNodes(); 1366 int* doflist = NULL; 1367 IssmDouble* values = NULL; 1368 1369 switch(type){ 1370 case VertexPIdEnum: 1371 doflist = xNew<int>(numvertices); 1372 values = xNew<IssmDouble>(numvertices); 1373 /*Fill in values*/ 1374 this->GetVertexPidList(doflist); 1375 this->GetInputListOnVerticesAtTime(values,input_enum,time); 1376 vector->SetValues(numvertices,doflist,values,INS_VAL); 1377 break; 1378 case VertexSIdEnum: 1379 doflist = xNew<int>(numvertices); 1380 values = xNew<IssmDouble>(numvertices); 1381 /*Fill in values*/ 1382 this->GetVerticesSidList(doflist); 1383 this->GetInputListOnVerticesAtTime(values,input_enum,time); 1384 vector->SetValues(numvertices,doflist,values,INS_VAL); 1385 break; 1386 default: 1387 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet"); 1388 } 1389 1390 /*Clean up*/ 1391 xDelete<int>(doflist); 1392 xDelete<IssmDouble>(values); 1393 1394 } 1395 /*}}}*/ 1312 1396 void Element::GetVertexPidList(int* pidlist){/*{{{*/ 1313 1397 … … 1383 1467 return z; 1384 1468 }/*}}}*/ 1385 void Element::GradientIndexing(int* indexing,int control_index ,bool onsid){/*{{{*/1469 void Element::GradientIndexing(int* indexing,int control_index){/*{{{*/ 1386 1470 1387 1471 /*Get number of controls*/ … … 1390 1474 parameters->FindParam(&num_controls,InversionNumControlParametersEnum); 1391 1475 parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum); 1392 1393 1476 1394 1477 /*Get number of vertices*/ … … 1415 1498 int M; 1416 1499 parameters->FindParam(&M,ControlInputSizeMEnum); 1417 /*get gradient indices*/ 1418 if(onsid){ 1419 for(int i=0;i<numvertices;i++){ 1420 indexing[i]=this->vertices[i]->Sid() + (control_index)*M; 1421 } 1422 } 1423 else{ 1424 for(int i=0;i<numvertices;i++){ 1425 indexing[i]=this->vertices[i]->Pid() + (control_index)*M; 1426 } 1500 /*get gradient indices*/ 1501 for(int i=0;i<numvertices;i++){ 1502 indexing[i]=this->vertices[i]->Sid() + (control_index)*M; 1427 1503 } 1428 1504 } … … 1510 1586 /*}}}*/ 1511 1587 void Element::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/ 1512 1588 1513 1589 /*Intermediaries*/ 1514 1590 int i,t; 1515 1591 1516 1592 /*Branch on type of vector: nodal or elementary: */ 1517 1593 if(vector_type==1){ //nodal vector 1518 1594 1519 1595 int numvertices = this->GetNumberOfVertices(); 1520 1596 int *vertexids = xNew<int>(numvertices); 1521 1597 IssmDouble *values = xNew<IssmDouble>(numvertices); 1522 1598 1523 1599 /*Recover vertices ids needed to initialize inputs*/ 1524 1600 _assert_(iomodel->elements); … … 1526 1602 vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab 1527 1603 } 1528 1604 1529 1605 /*Are we in transient or static? */ 1530 1606 if(M==1){ … … 1570 1646 _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long"); 1571 1647 } 1572 1648 1573 1649 xDelete<IssmDouble>(values); 1574 1650 xDelete<int>(vertexids); 1575 1651 } 1576 1652 else if(vector_type==2){ //element vector 1577 1653 1578 1654 IssmDouble value; 1579 1655 1580 1656 /*Are we in transient or static? */ 1581 1657 if(M==iomodel->numberofelements){ … … 1612 1688 } 1613 1689 else if(vector_type==3){ //element vector 1614 1690 1615 1691 /*For right now we are static */ 1616 1692 if(M==iomodel->numberofelements){ … … 1637 1713 1638 1714 /*Some sanity checks*/ 1639 _assert_(vector); 1640 _assert_(min_vector); 1641 _assert_(max_vector); 1715 _assert_(vector); 1716 _assert_(min_vector); 1717 _assert_(max_vector); 1642 1718 1643 1719 /*For now we only support nodal vectors*/ … … 1658 1734 values_max[i] = max_vector[vertexids[i]-1]; 1659 1735 } 1660 this->AddControlInput(input_enum,values, min_vector,max_vector,P1Enum,id);1736 this->AddControlInput(input_enum,values,values_min,values_max,P1Enum,id); 1661 1737 } 1662 1738 … … 1671 1747 TransientInput* grad_input = new TransientInput(ControlInputGradEnum); 1672 1748 for(int t=0;t<N;t++){ 1673 for(int i=0;i<numvertices;i++){ 1749 for(int i=0;i<numvertices;i++){ 1674 1750 values[i]=vector[N*(vertexids[i]-1)+t]; 1675 1751 values_min[i] = min_vector[N*(vertexids[i]-1)+t]; … … 1678 1754 switch(this->ObjectEnum()){ 1679 1755 case TriaEnum: 1680 values_input->AddTimeInput(new TriaInput(input_enum,values,P1Enum)); 1681 mins_input->AddTimeInput(new TriaInput(ControlInputMinsEnum,values_min,P1Enum)); 1756 values_input->AddTimeInput(new TriaInput(input_enum,values,P1Enum)); 1757 mins_input->AddTimeInput(new TriaInput(ControlInputMinsEnum,values_min,P1Enum)); 1682 1758 maxs_input->AddTimeInput(new TriaInput(ControlInputMaxsEnum,values_max,P1Enum)); 1683 1759 break; 1684 1760 case PentaEnum: 1685 values_input->AddTimeInput(new PentaInput(input_enum,values,P1Enum)); 1686 mins_input->AddTimeInput(new PentaInput(ControlInputMinsEnum,values_min,P1Enum)); 1687 maxs_input->AddTimeInput(new PentaInput(ControlInputMaxsEnum,values_max,P1Enum)); 1761 values_input->AddTimeInput(new PentaInput(input_enum,values,P1Enum)); 1762 mins_input->AddTimeInput(new PentaInput(ControlInputMinsEnum,values_min,P1Enum)); 1763 maxs_input->AddTimeInput(new PentaInput(ControlInputMaxsEnum,values_max,P1Enum)); 1688 1764 break; 1689 1765 case TetraEnum: 1690 values_input->AddTimeInput(new TetraInput(input_enum,values,P1Enum)); 1691 mins_input->AddTimeInput(new TetraInput(ControlInputMinsEnum,values_min,P1Enum)); 1692 maxs_input->AddTimeInput(new TetraInput(ControlInputMaxsEnum,values_max,P1Enum)); 1766 values_input->AddTimeInput(new TetraInput(input_enum,values,P1Enum)); 1767 mins_input->AddTimeInput(new TetraInput(ControlInputMinsEnum,values_min,P1Enum)); 1768 maxs_input->AddTimeInput(new TetraInput(ControlInputMaxsEnum,values_max,P1Enum)); 1693 1769 break; 1694 1770 default: _error_("Not implemented yet"); … … 1712 1788 * code: what type of data is in the vector (booleans, ints, doubles) 1713 1789 */ 1714 1790 1715 1791 /*Intermediaries*/ 1716 1792 int i,t; … … 1729 1805 } 1730 1806 1731 1732 1807 /*Branch on type of vector: nodal or elementary: */ 1733 1808 if(vector_type==1){ //nodal vector 1734 1809 1735 1810 int numvertices = this->GetNumberOfVertices(); 1736 1811 int *vertexids = xNew<int>(numvertices); 1737 1812 IssmDouble *values = xNew<IssmDouble>(numvertices); 1738 1813 1739 1814 /*Recover vertices ids needed to initialize inputs*/ 1740 1815 _assert_(iomodel->elements); … … 1742 1817 vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab 1743 1818 } 1744 1819 1745 1820 /*Are we in transient or static? */ 1746 1821 if(M==1){ … … 1751 1826 case TetraEnum: datasetinput->AddInput(new TetraInput(vector_enum,values,P0Enum),input_enum); break; 1752 1827 default: _error_("Not implemented yet"); 1753 } 1828 } 1754 1829 } 1755 1830 else if(M==iomodel->numberofvertices){ … … 1799 1874 case TetraEnum: datasetinput->AddInput(new TetraInput(vector_enum,values,P0Enum),input_enum); break; 1800 1875 default: _error_("Not implemented yet"); 1801 } 1876 } 1802 1877 } 1803 1878 else if(N==this->GetNumberOfNodes(P1xP2Enum)){ … … 1823 1898 _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long"); 1824 1899 } 1825 1900 1826 1901 xDelete<IssmDouble>(values); 1827 1902 xDelete<int>(vertexids); 1828 1903 } 1829 1904 else if(vector_type==2){ //element vector 1830 1905 1831 1906 IssmDouble value; 1832 1907 1833 1908 /*Are we in transient or static? */ 1834 1909 if(M==iomodel->numberofelements){ … … 1865 1940 } 1866 1941 else if(vector_type==3){ //element vector 1867 1942 1868 1943 /*For right now we are static */ 1869 1944 if(M==iomodel->numberofelements){ … … 1882 1957 void Element::InputDuplicate(int original_enum,int new_enum){/*{{{*/ 1883 1958 1884 if(!IsInput (original_enum)) _error_("Enum "<<EnumToStringx(original_enum)<<" is not in IsInput");1959 if(!IsInputEnum(original_enum)) _error_("Enum "<<EnumToStringx(original_enum)<<" is not in IsInput"); 1885 1960 1886 1961 /*Call inputs method*/ … … 1892 1967 1893 1968 /*Check that name is an element input*/ 1894 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");1969 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 1895 1970 1896 1971 /*update input*/ … … 1901 1976 1902 1977 /*Check that name is an element input*/ 1903 if(!IsInput (name)) return;1978 if(!IsInputEnum(name)) return; 1904 1979 1905 1980 /*update input*/ … … 1910 1985 1911 1986 /*Check that name is an element input*/ 1912 if(!IsInput (name)) return;1987 if(!IsInputEnum(name)) return; 1913 1988 1914 1989 /*update input*/ … … 1922 1997 parameters->FindParam(&migration_style,GroundinglineMigrationEnum); 1923 1998 1924 if(migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){ //Floating if all nodes are floating1999 if(migration_style==SubelementMigrationEnum){ //Floating if all nodes are floating 1925 2000 if(this->inputs->Max(MaskGroundediceLevelsetEnum) <= 0.) shelf=true; 1926 2001 else shelf=false; 1927 2002 } 1928 2003 else if(migration_style==ContactEnum){ 1929 if(this->inputs->M ax(MaskGroundediceLevelsetEnum) > 0.) shelf=false;1930 else shelf= true;2004 if(this->inputs->Min(MaskGroundediceLevelsetEnum) < 0.) shelf=true; 2005 else shelf=false; 1931 2006 } 1932 2007 else if(migration_style==NoneEnum || migration_style==AggressiveMigrationEnum || migration_style==SoftMigrationEnum || migration_style==GroundingOnlyEnum){ //Floating if all nodes are floating … … 1940 2015 bool Element::IsIceInElement(){/*{{{*/ 1941 2016 return (this->inputs->Min(MaskIceLevelsetEnum)<0.); 1942 }1943 /*}}}*/1944 bool Element::IsInput(int name){/*{{{*/1945 if (1946 name==ThicknessEnum ||1947 name==SurfaceEnum ||1948 name==BaseEnum ||1949 name==BedEnum ||1950 name==BalancethicknessThickeningRateEnum ||1951 name==BalancethicknessOmegaEnum ||1952 name==SigmaNNEnum ||1953 name==SurfaceSlopeXEnum ||1954 name==SurfaceSlopeYEnum ||1955 name==SmbMassBalanceEnum ||1956 name==SmbAccumulationEnum ||1957 name==SmbRunoffEnum ||1958 name==SmbMeltEnum ||1959 name==SmbRefreezeEnum ||1960 name==SmbEvaporationEnum ||1961 name==SmbCEnum ||1962 name==SmbTaEnum ||1963 name==SmbVEnum ||1964 name==SmbDswrfEnum ||1965 name==SmbDlwrfEnum ||1966 name==SmbPEnum ||1967 name==SmbEAirEnum ||1968 name==SmbPAirEnum ||1969 name==SmbVzEnum ||1970 name==SmbTzEnum ||1971 name==SmbTmeanEnum ||1972 name==SmbIsInitializedEnum ||1973 name==BasalforcingsGroundediceMeltingRateEnum ||1974 name==BasalforcingsFloatingiceMeltingRateEnum ||1975 name==BasalforcingsGeothermalfluxEnum ||1976 name==BalancethicknessSpcthicknessEnum ||1977 name==SurfaceAreaEnum||1978 name==DamageDEnum ||1979 name==DamageDbarEnum ||1980 name==PressureEnum ||1981 name==VxEnum ||1982 name==VyEnum ||1983 name==VzEnum ||1984 name==VxMeshEnum ||1985 name==VyMeshEnum ||1986 name==VzMeshEnum ||1987 name==InversionVxObsEnum ||1988 name==InversionVyObsEnum ||1989 name==InversionVzObsEnum ||1990 name==TemperatureEnum ||1991 name==TemperaturePDDEnum ||1992 name==EnthalpyEnum ||1993 name==EnthalpyPicardEnum ||1994 name==WaterfractionEnum||1995 name==WatercolumnEnum ||1996 name==FrictionCoefficientEnum ||1997 name==FrictionAsEnum ||1998 name==FrictionEffectivePressureEnum ||1999 name==MaskGroundediceLevelsetEnum ||2000 name==MaskIceLevelsetEnum ||2001 name==IceMaskNodeActivationEnum ||2002 name==LevelsetfunctionSlopeXEnum ||2003 name==LevelsetfunctionSlopeYEnum ||2004 name==LevelsetfunctionPicardEnum ||2005 name==CalvingCalvingrateEnum ||2006 name==CalvingMeltingrateEnum ||2007 name==GradientEnum ||2008 name==OldGradientEnum ||2009 name==ConvergedEnum ||2010 name==MaterialsRheologyEEnum ||2011 name==MaterialsRheologyEbarEnum ||2012 name==MaterialsRheologyBEnum ||2013 name==MaterialsRheologyBbarEnum ||2014 name==MaterialsRheologyNEnum ||2015 name==MaterialsRheologyEcEnum ||2016 name==MaterialsRheologyEcbarEnum ||2017 name==MaterialsRheologyEsEnum ||2018 name==MaterialsRheologyEsbarEnum ||2019 name==SealevelEnum ||2020 name==SealevelUmotionEnum ||2021 name==SealevelNmotionEnum ||2022 name==SealevelEmotionEnum ||2023 name==SealevelAbsoluteEnum ||2024 name==SealevelEustaticEnum ||2025 name==SealevelriseDeltathicknessEnum ||2026 name==EsaUmotionEnum ||2027 name==EsaNmotionEnum ||2028 name==EsaEmotionEnum ||2029 name==EsaXmotionEnum ||2030 name==EsaYmotionEnum ||2031 name==EsaStrainratexxEnum ||2032 name==EsaStrainratexyEnum ||2033 name==EsaStrainrateyyEnum ||2034 name==EsaRotationrateEnum ||2035 name==EsaDeltathicknessEnum ||2036 name==GiaWEnum ||2037 name==GiadWdtEnum ||2038 name==SedimentHeadEnum ||2039 name==EplHeadEnum ||2040 name==SedimentHeadOldEnum ||2041 name==EplHeadOldEnum ||2042 name==StressIntensityFactorEnum ||2043 name==StrainRateparallelEnum ||2044 name==StrainRateperpendicularEnum ||2045 name==HydrologydcEplThicknessOldEnum ||2046 name==HydrologydcEplInitialThicknessEnum ||2047 name==HydrologydcEplThicknessEnum ||2048 name==HydrologydcMaskEplactiveNodeEnum ||2049 name==HydrologyHeadEnum ||2050 name==HydrologyHeadOldEnum ||2051 name==StressbalanceConvergenceNumStepsEnum ||2052 name==MeshVertexonbaseEnum ||2053 name==FrictionPEnum ||2054 name==FrictionQEnum ||2055 name==FrictionCoefficientcoulombEnum ||2056 name==LoadingforceXEnum ||2057 name==LoadingforceYEnum ||2058 name==VelEnum ||2059 name==DeviatoricStressxxEnum ||2060 name==DeviatoricStressyyEnum ||2061 name==DeviatoricStressxyEnum ||2062 name==DeviatoricStressxzEnum ||2063 name==DeviatoricStressyzEnum ||2064 name==DeviatoricStresszzEnum ||2065 name==DeviatoricStresseffectiveEnum ||2066 name==VxAverageEnum ||2067 name==VyAverageEnum2068 ) {2069 return true;2070 }2071 else return false;2072 2017 } 2073 2018 /*}}}*/ … … 2102 2047 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum); 2103 2048 xDelete<IssmDouble>(base); 2049 xDelete<IssmDouble>(values); 2050 2051 }/*}}}*/ 2052 void Element::SpatialLinearFloatingiceMeltingRate(){/*{{{*/ 2053 2054 int numvertices = this->GetNumberOfVertices(); 2055 IssmDouble* deepwatermelt = xNew<IssmDouble>(numvertices); 2056 IssmDouble* deepwaterel = xNew<IssmDouble>(numvertices); 2057 IssmDouble* upperwaterel = xNew<IssmDouble>(numvertices); 2058 IssmDouble* base = xNew<IssmDouble>(numvertices); 2059 IssmDouble* values = xNew<IssmDouble>(numvertices); 2060 2061 this->GetInputListOnVertices(base,BaseEnum); 2062 this->GetInputListOnVertices(deepwatermelt,BasalforcingsDeepwaterMeltingRateEnum); 2063 this->GetInputListOnVertices(deepwaterel,BasalforcingsDeepwaterElevationEnum); 2064 this->GetInputListOnVertices(upperwaterel,BasalforcingsUpperwaterElevationEnum); 2065 2066 for(int i=0;i<numvertices;i++){ 2067 if(base[i]>upperwaterel[i]) values[i]=0; 2068 else if (base[i]<deepwaterel[i]) values[i]=deepwatermelt[i]; 2069 else values[i]=deepwatermelt[i]*(base[i]-upperwaterel[i])/(deepwaterel[i]-upperwaterel[i]); 2070 } 2071 2072 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum); 2073 xDelete<IssmDouble>(base); 2074 xDelete<IssmDouble>(deepwaterel); 2075 xDelete<IssmDouble>(deepwatermelt); 2076 xDelete<IssmDouble>(upperwaterel); 2104 2077 xDelete<IssmDouble>(values); 2105 2078 … … 2153 2126 }/*}}}*/ 2154 2127 void Element::MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses){/*{{{*/ 2155 2128 2156 2129 _assert_(this); 2157 2130 if(marshall_direction==MARSHALLING_BACKWARD){ … … 2161 2134 2162 2135 MARSHALLING_ENUM(ElementEnum); 2163 2136 2164 2137 MARSHALLING(id); 2165 2138 MARSHALLING(sid); … … 2200 2173 for(i=0;i<numvertices;i++){ 2201 2174 /* Contact FS*/ 2202 if(migration_style == ContactEnum && phi_ungrounding[vertices[i]->Pid()]<10){2203 phi[i]=phi_ungrounding[vertices[i]->Pid()]; 2175 if(migration_style == ContactEnum){ 2176 phi[i]=phi_ungrounding[vertices[i]->Pid()]; 2204 2177 if(phi[i]>=0.) b[i]=r[i]; 2205 2178 } … … 2207 2180 /*Ice shelf: if bed below bathymetry, impose it at the bathymetry and update surface, elso do nothing */ 2208 2181 else if(phi[i]<=0.){ 2209 if(b[i]<=r[i]){ 2182 if(b[i]<=r[i]){ 2210 2183 b[i] = r[i]; 2211 2184 s[i] = b[i]+h[i]; … … 2218 2191 if (bed_hydro>r[i]){ 2219 2192 /*Unground only if the element is connected to the ice shelf*/ 2220 if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){2193 if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum){ 2221 2194 s[i] = (1-density)*h[i]+sl[i]; 2222 2195 b[i] = -density*h[i]+sl[i]; … … 2467 2440 } 2468 2441 2469 /*Recover pdd factors at time t. 2470 * This parameter is set, if the user wants to define the 2442 /*Recover pdd factors at time t. 2443 * This parameter is set, if the user wants to define the 2471 2444 * pdd factors regionally, if issetpddfac==1 in the d18opdd method */ 2472 2445 if (issetpddfac==1){ … … 2514 2487 2515 2488 switch(this->ObjectEnum()){ 2516 case TriaEnum: 2489 case TriaEnum: 2517 2490 // this->inputs->AddInput(new TriaInput(TemperatureEnum,&yearlytemperatures[0],P1Enum)); 2518 2491 this->inputs->AddInput(new TriaInput(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum)); … … 2549 2522 this->InputExtrude(SmbMassBalanceEnum,-1); 2550 2523 break; 2551 case TetraEnum: 2524 case TetraEnum: 2552 2525 if(IsOnSurface()){ 2553 2526 GetInputListOnVertices(&s[0],TemperatureEnum); … … 2597 2570 case ViscousHeatingEnum: this->ViscousHeatingCreateInput(); break; 2598 2571 case StressMaxPrincipalEnum: this->StressMaxPrincipalCreateInput(); break; 2599 case StressTensorxxEnum: 2600 case StressTensorxyEnum: 2601 case StressTensorxzEnum: 2602 case StressTensoryyEnum: 2603 case StressTensoryzEnum: 2572 case StressTensorxxEnum: 2573 case StressTensorxyEnum: 2574 case StressTensorxzEnum: 2575 case StressTensoryyEnum: 2576 case StressTensoryzEnum: 2604 2577 case StressTensorzzEnum: this->ComputeStressTensor(); break; 2605 2578 case StrainRatexxEnum: … … 2610 2583 case StrainRatezzEnum: 2611 2584 case StrainRateeffectiveEnum: this->ComputeStrainRate(); break; 2612 case DeviatoricStressxxEnum: 2613 case DeviatoricStressxyEnum: 2614 case DeviatoricStressxzEnum: 2615 case DeviatoricStressyyEnum: 2616 case DeviatoricStressyzEnum: 2617 case DeviatoricStresszzEnum: 2585 case DeviatoricStressxxEnum: 2586 case DeviatoricStressxyEnum: 2587 case DeviatoricStressxzEnum: 2588 case DeviatoricStressyyEnum: 2589 case DeviatoricStressyzEnum: 2590 case DeviatoricStresszzEnum: 2618 2591 case DeviatoricStresseffectiveEnum: this->ComputeDeviatoricStressTensor(); break; 2619 2592 case EsaStrainratexxEnum: 2620 case EsaStrainratexyEnum: 2621 case EsaStrainrateyyEnum: 2593 case EsaStrainratexyEnum: 2594 case EsaStrainrateyyEnum: 2622 2595 case EsaRotationrateEnum: this->ComputeEsaStrainAndVorticity(); break; 2623 2596 case SigmaNNEnum: this->ComputeSigmaNN(); break; … … 2893 2866 if (!IsOnSurface()) return; 2894 2867 2895 2896 2868 /*Retrieve material properties and parameters:{{{ */ 2897 2869 rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum); … … 2924 2896 /*}}}*/ 2925 2897 /*Retrieve inputs: {{{*/ 2926 Input* zTop_input=this->GetInput(SmbZTopEnum); _assert_(zTop_input); 2927 Input* dzTop_input=this->GetInput(SmbDzTopEnum); _assert_(dzTop_input); 2928 Input* dzMin_input=this->GetInput(SmbDzMinEnum); _assert_(dzMin_input); 2929 Input* zMax_input=this->GetInput(SmbZMaxEnum); _assert_(zMax_input); 2930 Input* zMin_input=this->GetInput(SmbZMinEnum); _assert_(zMin_input); 2931 Input* zY_input=this->GetInput(SmbZYEnum); _assert_(zY_input); 2898 Input* zTop_input=this->GetInput(SmbZTopEnum); _assert_(zTop_input); 2899 Input* dzTop_input=this->GetInput(SmbDzTopEnum); _assert_(dzTop_input); 2900 Input* dzMin_input=this->GetInput(SmbDzMinEnum); _assert_(dzMin_input); 2901 Input* zMax_input=this->GetInput(SmbZMaxEnum); _assert_(zMax_input); 2902 Input* zMin_input=this->GetInput(SmbZMinEnum); _assert_(zMin_input); 2903 Input* zY_input=this->GetInput(SmbZYEnum); _assert_(zY_input); 2932 2904 Input* Tmean_input=this->GetInput(SmbTmeanEnum); _assert_(Tmean_input); 2933 2905 Input* C_input=this->GetInput(SmbCEnum); _assert_(C_input); … … 2950 2922 dzTop_input->GetInputValue(&dzTop,gauss); 2951 2923 dzMin_input->GetInputValue(&dzMin,gauss); 2952 zMax_input->GetInputValue(&zMax,gauss); 2953 zMin_input->GetInputValue(&zMin,gauss); 2924 zMax_input->GetInputValue(&zMax,gauss); 2925 zMin_input->GetInputValue(&zMin,gauss); 2954 2926 zY_input->GetInputValue(&zY,gauss); 2955 2927 Tmean_input->GetInputValue(&Tmean,gauss); … … 3005 2977 a = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)a[i]=aini[0]; //set albedo equal to fresh snow [fraction] 3006 2978 T = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)T[i]=Tmean; //set initial grid cell temperature to the annual mean temperature [K] 3007 /*/!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties) 2979 /*/!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties) 3008 2980 * because don't know Tmean yet when set default values. 3009 2981 * Default value of 0C given in SMBgemb.m is overwritten here with value of Tmean*/ … … 3066 3038 sumdz_add=0; 3067 3039 3068 //before starting loop, realize that the transient core runs this smb_core at time = time +deltaT. 3069 //go back to time - deltaT: 3040 //before starting loop, realize that the transient core runs this smb_core at time = time +deltaT. 3041 //go back to time - deltaT: 3070 3042 time-=dt; 3071 3043 … … 3095 3067 if(isalbedo)albedo(&a,aIdx,re,d,cldFrac,aIce,aSnow,aValue,adThresh,T,W,P,EC,t0wet,t0dry,K,smb_dt,rho_ice,m,this->Sid()); 3096 3068 3097 3098 3069 /*Distribution of absorbed short wave radation with depth:*/ 3099 3070 if(isshortwave)shortwave(&swf, swIdx, aIdx, dsw, a[0], d, dz, re,rho_ice,m,this->Sid()); … … 3105 3076 if(isthermal)thermo(&EC, &T, dz, d, swf, dlw, Ta, V, eAir, pAir, teValue, W[0], smb_dt, m, Vz, Tz, thermo_scaling,rho_ice,this->Sid()); 3106 3077 3107 /*Change in thickness of top cell due to evaporation/condensation assuming same density as top cell. 3078 /*Change in thickness of top cell due to evaporation/condensation assuming same density as top cell. 3108 3079 * need to fix this in case all or more of cell evaporates */ 3109 3080 dz[0] = dz[0] + EC / d[0]; … … 3119 3090 if(isdensification)densification(&d,&dz, T, re, denIdx, C, smb_dt, Tmean,rho_ice,m,this->Sid()); 3120 3091 3121 /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every 3092 /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every 3122 3093 * sub-time step in thermo equations*/ 3123 3094 ulw = 5.67E-8 * pow(T[0],4.0) * teValue; … … 3130 3101 3131 3102 /*Verbose some results in debug mode: {{{*/ 3132 if(VerboseSmb() && 0){ 3133 _printf_("smb log: count[" << count << "] m[" << m << "] " 3134 << setprecision(16) << "T[" << cellsum(T,m) << "] " 3103 if(VerboseSmb() && 0){ 3104 _printf_("smb log: count[" << count << "] m[" << m << "] " 3105 << setprecision(16) << "T[" << cellsum(T,m) << "] " 3135 3106 << "d[" << cellsum(d,m) << "] " 3136 3107 << "dz[" << cellsum(dz,m) << "] " … … 3155 3126 3156 3127 /*Calculate total system mass:*/ 3157 sumMass=0; 3128 sumMass=0; 3158 3129 fac=0; 3159 3130 for(int i=0;i<m;i++){ … … 3234 3205 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss); 3235 3206 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss); 3236 epsilon[0] = dvx[0]; // normal strain rate x-direction 3237 epsilon[1] = dvy[1]; // normal strain rate y-direction 3238 epsilon[2] = 0.5*(dvx[1] + dvy[0]); // shear strain rate 3239 epsilon[3] = 0.5*(dvx[1] - dvy[0]); // rotation rate 3207 epsilon[0] = dvx[0]; // normal strain rate x-direction 3208 epsilon[1] = dvy[1]; // normal strain rate y-direction 3209 epsilon[2] = 0.5*(dvx[1] + dvy[0]); // shear strain rate 3210 epsilon[3] = 0.5*(dvx[1] - dvy[0]); // rotation rate 3240 3211 3241 3212 }/*}}}*/ -
issm/trunk/src/c/classes/Elements/Element.h
r22758 r23189 90 90 void GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype); 91 91 void GetInputListOnVertices(IssmDouble* pvalue,int enumtype); 92 void GetInputListOnVerticesAtTime(IssmDouble* pvalue,int enumtype,IssmDouble time); 92 93 void GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue); 93 94 void GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug); … … 104 105 void GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int solutionenum); 105 106 void GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type); 107 void GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type,IssmDouble time); 106 108 void GetVertexPidList(int* pidlist); 107 109 void GetVerticesConnectivityList(int* connectivitylist); … … 111 113 IssmDouble GetYcoord(IssmDouble* xyz_list,Gauss* gauss); 112 114 IssmDouble GetZcoord(IssmDouble* xyz_list,Gauss* gauss); 113 void GradientIndexing(int* indexing,int control_index ,bool onsid=false);115 void GradientIndexing(int* indexing,int control_index); 114 116 IssmDouble GroundedArea(IssmDouble* mask, bool scaled); 115 117 bool HasNodeOnBase(); … … 130 132 bool IsFloating(); 131 133 bool IsIceInElement(); 132 bool IsInput(int name);133 134 bool IsLandInElement(); 134 135 bool IsWaterInElement(); 135 136 void LinearFloatingiceMeltingRate(); 137 void SpatialLinearFloatingiceMeltingRate(); 136 138 void MantlePlumeGeothermalFlux(); 137 139 void MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses); … … 205 207 virtual void ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index)=0; 206 208 virtual void ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum)=0; 207 virtual void CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){_error_("not implemented yet");};209 virtual void CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum){_error_("not implemented yet");}; 208 210 virtual void ElementResponse(IssmDouble* presponse,int response_enum)=0; 209 211 virtual void ElementSizes(IssmDouble* phx,IssmDouble* phy,IssmDouble* phz)=0; 210 212 virtual int FiniteElement(void)=0; 211 213 virtual IssmDouble FloatingArea(bool scaled)=0; 212 virtual void FSContactMigration(Vector<IssmDouble>* vertex grounded,Vector<IssmDouble>* vertexfloating)=0;214 virtual void FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure)=0; 213 215 virtual Element* GetBasalElement(void)=0; 214 216 virtual int GetElementType(void)=0; … … 225 227 virtual int GetNumberOfNodes(int enum_type)=0; 226 228 virtual int GetNumberOfVertices(void)=0; 227 virtual void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset , bool onsid)=0;228 virtual void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data , bool onsid)=0;229 virtual void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset)=0; 230 virtual void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data)=0; 229 231 virtual void GetVerticesCoordinatesBase(IssmDouble** xyz_list)=0; 230 232 virtual void GetVerticesCoordinatesTop(IssmDouble** xyz_list)=0; … … 281 283 virtual void PicoUpdateBoxid(int* pmax_boxid_basin)=0; 282 284 virtual void PicoUpdateBox(int loopboxid)=0; 285 virtual void PicoComputeBasalMelt(void)=0; 283 286 virtual void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding)=0; 284 287 virtual int PressureInterpolation()=0; … … 286 289 virtual void ResetFSBasalBoundaryCondition()=0; 287 290 virtual void ResetHooks()=0; 288 virtual void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};289 291 virtual void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset,int N,int M)=0; 290 292 virtual void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0; … … 315 317 virtual void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0; 316 318 virtual void WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue){_error_("not implemented yet");}; 317 virtual void WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};318 virtual void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;319 319 320 320 #ifdef _HAVE_GIAIVINS_ … … 333 333 virtual void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0; 334 334 virtual void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea)=0; 335 virtual void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea )=0;335 virtual void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz)=0; 336 336 #endif 337 337 -
issm/trunk/src/c/classes/Elements/ElementHook.cpp
r22758 r23189 104 104 105 105 if(marshall_direction==MARSHALLING_BACKWARD){ 106 106 107 107 if (!hnodes_null)this->hnodes = new Hook*[numanalyses]; 108 108 else this->hnodes=NULL; … … 140 140 _printf_(" ElementHook DeepEcho:\n"); 141 141 _printf_(" numanalyses : "<< this->numanalyses <<"\n"); 142 142 143 143 _printf_(" hnodes:\n"); 144 144 if(hnodes){ … … 149 149 } 150 150 else _printf_(" hnodes = NULL\n"); 151 151 152 152 _printf_(" hvertices:\n"); 153 153 if(hvertices) hvertices->DeepEcho(); 154 154 else _printf_(" hvertices = NULL\n"); 155 155 156 156 _printf_(" hmaterial:\n"); 157 157 if(hmaterial) hmaterial->DeepEcho(); … … 170 170 /*}}}*/ 171 171 void ElementHook::Echo(){/*{{{*/ 172 172 173 173 _printf_(" ElementHook Echo:\n"); 174 174 _printf_(" numanalyses : "<< this->numanalyses <<"\n"); 175 175 176 176 _printf_(" hnodes:\n"); 177 177 if(hnodes){ … … 181 181 } 182 182 else _printf_(" hnodes = NULL\n"); 183 183 184 184 _printf_(" hvertices:\n"); 185 185 if(hvertices) hvertices->Echo(); 186 186 else _printf_(" hvertices = NULL\n"); 187 187 188 188 _printf_(" hmaterial:\n"); 189 189 if(hmaterial) hmaterial->Echo(); -
issm/trunk/src/c/classes/Elements/Penta.cpp
r22758 r23189 286 286 IssmDouble calvingratey[NUMVERTICES]; 287 287 IssmDouble calvingrate[NUMVERTICES]; 288 289 288 290 289 /* Get node coordinates and dof list: */ … … 741 740 } 742 741 /*}}}*/ 743 void Penta::FSContactMigration(Vector<IssmDouble>* vertex grounded,Vector<IssmDouble>* vertexfloating){/*{{{*/742 void Penta::FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure){/*{{{*/ 744 743 745 744 if(!IsOnBase()) return; … … 747 746 int approximation; 748 747 inputs->GetInputValue(&approximation,ApproximationEnum); 749 if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum){ 750 for(int i=0;i<NUMVERTICES;i++){ 751 vertexgrounded->SetValue(vertices[i]->Pid(),+9999.,INS_VAL); 752 vertexfloating->SetValue(vertices[i]->Pid(),+9999.,INS_VAL); 748 if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum || approximation==HOFSApproximationEnum){ 749 _error_("Cannot compute contact condition for non FS elements"); 750 } 751 752 /*Intermediaries*/ 753 IssmDouble* xyz_list = NULL; 754 IssmDouble bed_normal[3],base[NUMVERTICES],bed[NUMVERTICES],surface[NUMVERTICES],phi[NUMVERTICES]; 755 IssmDouble water_pressure[NUMVERTICES],pressureice[NUMVERTICES],pressure[NUMVERTICES]; 756 IssmDouble sigmaxx[NUMVERTICES],sigmayy[NUMVERTICES],sigmazz[NUMVERTICES],sigmaxy[NUMVERTICES]; 757 IssmDouble sigmayz[NUMVERTICES],sigmaxz[NUMVERTICES],sigma_nn[NUMVERTICES]; 758 IssmDouble viscosity,epsilon[NUMVERTICES]; 759 GetInputListOnVertices(&base[0],BaseEnum); 760 GetInputListOnVertices(&bed[0],BedEnum); 761 GetInputListOnVertices(&surface[0],SurfaceEnum); 762 GetInputListOnVertices(&pressure[0],PressureEnum); 763 GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum); 764 IssmDouble rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum); 765 IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum); 766 IssmDouble gravity = matpar->GetMaterialParameter(ConstantsGEnum); 767 768 /* Get node coordinates and dof list: */ 769 GetVerticesCoordinates(&xyz_list); 770 771 /*Retrieve all inputs we will be needing: */ 772 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input); 773 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input); 774 Input* vz_input = inputs->GetInput(VzEnum); _assert_(vz_input); 775 776 /*1. Recover stresses at the base*/ 777 GaussPenta* gauss=new GaussPenta(); 778 for (int iv=0;iv<NUMVERTICES;iv++){ 779 gauss->GaussVertex(iv); 780 781 /*Compute strain rate viscosity and pressure: */ 782 this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input); 783 this->material->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input); 784 /*FIXME: this is for Hongju only*/ 785 //pressureice[iv]=gravity*rho_ice*(surface[iv]-base[iv]); 786 //if (pressure[iv]/pressureice[iv]>1) pressure[iv]=pressureice[iv]; 787 788 /*Compute Stress*/ 789 sigmaxx[iv]=2*viscosity*epsilon[0]-pressure[iv]; // sigma = nu eps - pressure 790 sigmayy[iv]=2*viscosity*epsilon[1]-pressure[iv]; 791 sigmazz[iv]=2*viscosity*epsilon[2]-pressure[iv]; 792 sigmaxy[iv]=2*viscosity*epsilon[3]; 793 sigmaxz[iv]=2*viscosity*epsilon[4]; 794 sigmayz[iv]=2*viscosity*epsilon[5]; 795 } 796 797 /*2. compute contact condition*/ 798 for(int i=0;i<NUMVERTICES;i++){ 799 800 /*If was grounded*/ 801 if (phi[i]>=0.){ 802 NormalBase(&bed_normal[0],xyz_list); 803 sigma_nn[i]=-1*(sigmaxx[i]*bed_normal[0]*bed_normal[0] + sigmayy[i]*bed_normal[1]*bed_normal[1] + sigmazz[i]*bed_normal[2]*bed_normal[2]+2*sigmaxy[i]*bed_normal[0]*bed_normal[1]+2*sigmaxz[i]*bed_normal[0]*bed_normal[2]+2*sigmayz[i]*bed_normal[1]*bed_normal[2]); 804 water_pressure[i]=-gravity*rho_water*base[i]; 805 vertex_sigmann->SetValue(vertices[i]->Pid(),sigma_nn[i],ADD_VAL); 806 vertex_waterpressure->SetValue(vertices[i]->Pid(),water_pressure[i],ADD_VAL); 753 807 } 754 } 755 else { 756 /*Intermediaries*/ 757 IssmDouble* xyz_list = NULL; 758 IssmDouble pressure,water_pressure,sigma_nn,viscosity,bed,base; 759 IssmDouble bed_normal[3]; 760 IssmDouble epsilon[6]; /* epsilon=[exx eyy ezz exy exz eyz];*/ 761 IssmDouble surface=0,value=0; 762 bool grounded; 763 764 /* Get node coordinates and dof list: */ 765 GetVerticesCoordinates(&xyz_list); 766 767 /*Retrieve all inputs we will be needing: */ 768 Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input); 769 Input* base_input = inputs->GetInput(BaseEnum); _assert_(base_input); 770 Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input); 771 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input); 772 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input); 773 Input* vz_input = inputs->GetInput(VzEnum); _assert_(vz_input); 774 775 /*Create gauss point in the middle of the basal edge*/ 776 Gauss* gauss=NewGaussBase(1); 777 gauss->GaussPoint(0); 778 779 if(!IsFloating()){ 780 /*Check for basal force only if grounded and touching GL*/ 781 this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input); 782 this->material->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input); 783 pressure_input->GetInputValue(&pressure, gauss); 784 base_input->GetInputValue(&base, gauss); _assert_(base<0.); 785 786 /*Compute Stress*/ 787 IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure; 788 IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure; 789 IssmDouble sigma_zz=2.*viscosity*epsilon[2]-pressure; 790 IssmDouble sigma_xy=2.*viscosity*epsilon[3]; 791 IssmDouble sigma_xz=2.*viscosity*epsilon[4]; 792 IssmDouble sigma_yz=2.*viscosity*epsilon[5]; 793 794 /*Get normal vector to the bed */ 795 NormalBase(&bed_normal[0],xyz_list); 796 797 /*basalforce*/ 798 sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + sigma_zz*bed_normal[2]*bed_normal[2] 799 + 2.*sigma_xy*bed_normal[0]*bed_normal[1] + 2.*sigma_xz*bed_normal[0]*bed_normal[2] + 2.*sigma_yz*bed_normal[1]*bed_normal[2]; 800 801 /*Compute water pressure*/ 802 IssmDouble rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum); 803 IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum); 804 IssmDouble gravity = matpar->GetMaterialParameter(ConstantsGEnum); 805 water_pressure=gravity*rho_water*base; 806 807 /*Compare basal stress to water pressure and determine whether it should ground*/ 808 if (sigma_nn<water_pressure) grounded=true; 809 else grounded=false; 808 809 /*If was floating*/ 810 else{ 811 /*Tricky part: 812 * 1. if base is now touching, we put 1 for sigma_nn and leave water pressure at 0 so that the rest of the module will reground this vertex 813 * 2. if base is still above bed, water pressure is set as 1, sigma_nn is left as 0, so the GL module will keep it afloat*/ 814 if(base[i]<bed[i]) vertex_sigmann->SetValue(vertices[i]->Pid(),+1.,ADD_VAL); 815 else vertex_waterpressure->SetValue(vertices[i]->Pid(),+1.,ADD_VAL); 810 816 } 811 else{ 812 /*Check for basal elevation if floating*/ 813 base_input->GetInputValue(&base, gauss); 814 bed_input->GetInputValue(&bed, gauss); 815 if(base<bed) grounded=true; 816 else grounded=false; 817 } 818 for(int i=0;i<NUMVERTICES;i++){ 819 if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL); 820 else vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL); 821 } 822 823 /*clean up*/ 824 delete gauss; 825 xDelete<IssmDouble>(xyz_list); 826 } 817 } 818 819 /*clean up*/ 820 delete gauss; 821 xDelete<IssmDouble>(xyz_list); 827 822 } 828 823 /*}}}*/ … … 1052 1047 /*}}}*/ 1053 1048 void Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 1054 1049 1055 1050 /* Intermediaries */ 1056 1051 const int dim=3; … … 1153 1148 } 1154 1149 /*}}}*/ 1155 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data ,bool onsid){/*{{{*/1150 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/ 1156 1151 1157 1152 int vertexidlist[NUMVERTICES]; 1158 1153 1159 1154 /*Get out if this is not an element input*/ 1160 if(!IsInput (control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");1155 if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput"); 1161 1156 1162 1157 /*Prepare index list*/ 1163 GradientIndexing(&vertexidlist[0],control_index ,onsid);1158 GradientIndexing(&vertexidlist[0],control_index); 1164 1159 1165 1160 /*Get input (either in element or material)*/ … … 1176 1171 } 1177 1172 /*}}}*/ 1178 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset ,bool onsid){/*{{{*/1173 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset){/*{{{*/ 1179 1174 1180 1175 int* idlist = NULL; … … 1183 1178 1184 1179 /*Get out if this is not an element input*/ 1185 if(!IsInput (control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");1180 if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput"); 1186 1181 Input* input=(Input*)this->inputs->GetInput(control_enum); _assert_(input); 1187 1188 1182 1189 1183 /*Cast to Controlinput*/ … … 1217 1211 idlist = xNew<int>(NUMVERTICES); 1218 1212 values = xNew<IssmDouble>(NUMVERTICES); 1219 GradientIndexing(&idlist[0],control_index ,true);1213 GradientIndexing(&idlist[0],control_index); 1220 1214 for(int i=0;i<NUMVERTICES;i++){ 1221 1215 values[i] = pentainput->values[i]; … … 1611 1605 1612 1606 /*Add input to the element: */ 1613 this->inputs->AddInput(new PentaInput(enum_type,values, P1Enum));1607 this->inputs->AddInput(new PentaInput(enum_type,values,this->element_type)); 1614 1608 1615 1609 /*Free ressources:*/ … … 1665 1659 1666 1660 /*Check that name is an element input*/ 1667 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");1661 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 1668 1662 1669 1663 switch(type){ … … 2288 2282 } 2289 2283 /*}}}*/ 2290 void Penta::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/2291 2292 /*Intermediaries*/2293 IssmDouble d,xn,yn;2294 2295 /*Get current levelset and vertex coordinates*/2296 IssmDouble ls[NUMVERTICES];2297 IssmDouble xyz_list[NUMVERTICES][3];2298 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);2299 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);2300 2301 /*Get distance from list of segments and reset ls*/2302 for(int j=0;j<NUMVERTICES;j++){2303 IssmDouble dmin = 1.e+50;2304 for(int i=0;i<numsegments;i++){2305 IssmDouble x = xyz_list[j][0];2306 IssmDouble y = xyz_list[j][1];2307 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);2308 2309 /*Segment has a length of 0*/2310 if(l2==0.){2311 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);2312 if(d<dmin) dmin = d;2313 continue;2314 }2315 2316 /*Consider the line extending the segment, parameterized as v + t (w - v).2317 *We find projection of point p onto the line.2318 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/2319 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;2320 if(t < 0.0){2321 // Beyond the 'v' end of the segment2322 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);2323 }2324 else if (t > 1.0){2325 // Beyond the 'w' end of the segment2326 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);2327 }2328 else{2329 // Projection falls on the segment2330 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);2331 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);2332 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);2333 }2334 2335 if(d<dmin) dmin = d;2336 }2337 2338 /*Update signed distance*/2339 dmin = sqrt(dmin);2340 if(dmin>10000) dmin=10000;2341 if(ls[j]>0){2342 ls[j] = dmin;2343 }2344 else{2345 ls[j] = - dmin;2346 }2347 }2348 2349 /*Update Levelset*/2350 this->inputs->AddInput(new PentaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));2351 }2352 /*}}}*/2353 2284 void Penta::SetClone(int* minranks){/*{{{*/ 2354 2285 … … 2374 2305 2375 2306 /*Get out if this is not an element input*/ 2376 if(!IsInput (control_enum)) return;2307 if(!IsInputEnum(control_enum)) return; 2377 2308 2378 2309 /*Prepare index list*/ … … 2416 2347 2417 2348 /*Get out if this is not an element input*/ 2418 if(!IsInput (control_enum)) return;2349 if(!IsInputEnum(control_enum)) return; 2419 2350 2420 2351 /*Prepare index list*/ … … 2662 2593 Penta* penta=this; 2663 2594 for(;;){ 2664 2595 2665 2596 IssmDouble xyz_list[NUMVERTICES][3]; 2666 2597 /* Get node coordinates and dof list: */ … … 2671 2602 Jdet[1]=(xyz_list[4][2]-xyz_list[1][2])*0.5; 2672 2603 Jdet[2]=(xyz_list[5][2]-xyz_list[2][2])*0.5; 2673 2604 2674 2605 /*Retrieve all inputs we will need*/ 2675 2606 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); … … 2682 2613 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input); 2683 2614 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input); 2684 2615 2685 2616 /* Start looping on the number of 2D vertices: */ 2686 2617 for(int ig=0;ig<3;ig++){ … … 2711 2642 delete gauss; 2712 2643 } 2713 2644 2714 2645 /*Stop if we have reached the surface/base*/ 2715 2646 if(penta->IsOnSurface()) break; 2716 2647 2717 2648 /*get upper Penta*/ 2718 2649 penta=penta->GetUpperPenta(); … … 3470 3401 } 3471 3402 /*}}}*/ 3472 void Penta::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/3473 /*Compute portion of the element that is grounded*/3474 3475 int normal_orientation=0;3476 IssmDouble s1,s2;3477 IssmDouble levelset[NUMVERTICES];3478 IssmDouble* xyz_zero = xNew<IssmDouble>(4*3);3479 3480 /*Recover parameters and values*/3481 GetInputListOnVertices(&levelset[0],levelsetenum);3482 3483 if(levelset[0]*levelset[1]>0.){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-23484 /*Portion of the segments*/3485 s1=levelset[2]/(levelset[2]-levelset[1]);3486 s2=levelset[2]/(levelset[2]-levelset[0]);3487 3488 if(levelset[2]<0.) normal_orientation=1; //orientation of quadrangle at base and top, depending on distribution of levelsetfunction3489 /*New point 1*/3490 xyz_zero[3*normal_orientation+0]=xyz_list[2*3+0]+s1*(xyz_list[1*3+0]-xyz_list[2*3+0]);3491 xyz_zero[3*normal_orientation+1]=xyz_list[2*3+1]+s1*(xyz_list[1*3+1]-xyz_list[2*3+1]);3492 xyz_zero[3*normal_orientation+2]=xyz_list[2*3+2]+s1*(xyz_list[1*3+2]-xyz_list[2*3+2]);3493 3494 /*New point 0*/3495 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2*3+0]+s2*(xyz_list[0*3+0]-xyz_list[2*3+0]);3496 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2*3+1]+s2*(xyz_list[0*3+1]-xyz_list[2*3+1]);3497 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2*3+2]+s2*(xyz_list[0*3+2]-xyz_list[2*3+2]);3498 3499 /*New point 3*/3500 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[5*3+0]+s1*(xyz_list[4*3+0]-xyz_list[5*3+0]);3501 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[5*3+1]+s1*(xyz_list[4*3+1]-xyz_list[5*3+1]);3502 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[5*3+2]+s1*(xyz_list[4*3+2]-xyz_list[5*3+2]);3503 3504 /*New point 4*/3505 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[5*3+0]+s2*(xyz_list[3*3+0]-xyz_list[5*3+0]);3506 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[5*3+1]+s2*(xyz_list[3*3+1]-xyz_list[5*3+1]);3507 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[5*3+2]+s2*(xyz_list[3*3+2]-xyz_list[5*3+2]);3508 }3509 else if(levelset[1]*levelset[2]>0.){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-23510 /*Portion of the segments*/3511 s1=levelset[0]/(levelset[0]-levelset[2]);3512 s2=levelset[0]/(levelset[0]-levelset[1]);3513 3514 if(levelset[0]<0.) normal_orientation=1;3515 /*New point 1*/3516 xyz_zero[3*normal_orientation+0]=xyz_list[0*3+0]+s1*(xyz_list[2*3+0]-xyz_list[0*3+0]);3517 xyz_zero[3*normal_orientation+1]=xyz_list[0*3+1]+s1*(xyz_list[2*3+1]-xyz_list[0*3+1]);3518 xyz_zero[3*normal_orientation+2]=xyz_list[0*3+2]+s1*(xyz_list[2*3+2]-xyz_list[0*3+2]);3519 3520 /*New point 2*/3521 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0*3+0]+s2*(xyz_list[1*3+0]-xyz_list[0*3+0]);3522 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0*3+1]+s2*(xyz_list[1*3+1]-xyz_list[0*3+1]);3523 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0*3+2]+s2*(xyz_list[1*3+2]-xyz_list[0*3+2]);3524 3525 /*New point 3*/3526 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[3*3+0]+s1*(xyz_list[5*3+0]-xyz_list[3*3+0]);3527 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[3*3+1]+s1*(xyz_list[5*3+1]-xyz_list[3*3+1]);3528 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[3*3+2]+s1*(xyz_list[5*3+2]-xyz_list[3*3+2]);3529 3530 /*New point 4*/3531 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[3*3+0]+s2*(xyz_list[4*3+0]-xyz_list[3*3+0]);3532 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[3*3+1]+s2*(xyz_list[4*3+1]-xyz_list[3*3+1]);3533 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[3*3+2]+s2*(xyz_list[4*3+2]-xyz_list[3*3+2]);3534 }3535 else if(levelset[0]*levelset[2]>0.){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-23536 /*Portion of the segments*/3537 s1=levelset[1]/(levelset[1]-levelset[0]);3538 s2=levelset[1]/(levelset[1]-levelset[2]);3539 3540 if(levelset[1]<0.) normal_orientation=1;3541 /*New point 0*/3542 xyz_zero[3*normal_orientation+0]=xyz_list[1*3+0]+s1*(xyz_list[0*3+0]-xyz_list[1*3+0]);3543 xyz_zero[3*normal_orientation+1]=xyz_list[1*3+1]+s1*(xyz_list[0*3+1]-xyz_list[1*3+1]);3544 xyz_zero[3*normal_orientation+2]=xyz_list[1*3+2]+s1*(xyz_list[0*3+2]-xyz_list[1*3+2]);3545 3546 /*New point 2*/3547 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1*3+0]+s2*(xyz_list[2*3+0]-xyz_list[1*3+0]);3548 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1*3+1]+s2*(xyz_list[2*3+1]-xyz_list[1*3+1]);3549 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1*3+2]+s2*(xyz_list[2*3+2]-xyz_list[1*3+2]);3550 3551 /*New point 3*/3552 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[4*3+0]+s1*(xyz_list[3*3+0]-xyz_list[4*3+0]);3553 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[4*3+1]+s1*(xyz_list[3*3+1]-xyz_list[4*3+1]);3554 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[4*3+2]+s1*(xyz_list[3*3+2]-xyz_list[4*3+2]);3555 3556 /*New point 4*/3557 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[4*3+0]+s2*(xyz_list[5*3+0]-xyz_list[4*3+0]);3558 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[4*3+1]+s2*(xyz_list[5*3+1]-xyz_list[4*3+1]);3559 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[4*3+2]+s2*(xyz_list[5*3+2]-xyz_list[4*3+2]);3560 }3561 else if(levelset[0]==0. && levelset[1]==0.){ //front is on point 0 and 13562 xyz_zero[3*0+0]=xyz_list[0*3+0];3563 xyz_zero[3*0+1]=xyz_list[0*3+1];3564 xyz_zero[3*0+2]=xyz_list[0*3+2];3565 3566 /*New point 2*/3567 xyz_zero[3*1+0]=xyz_list[1*3+0];3568 xyz_zero[3*1+1]=xyz_list[1*3+1];3569 xyz_zero[3*1+2]=xyz_list[1*3+2];3570 3571 /*New point 3*/3572 xyz_zero[3*2+0]=xyz_list[4*3+0];3573 xyz_zero[3*2+1]=xyz_list[4*3+1];3574 xyz_zero[3*2+2]=xyz_list[4*3+2];3575 3576 /*New point 4*/3577 xyz_zero[3*3+0]=xyz_list[3*3+0];3578 xyz_zero[3*3+1]=xyz_list[3*3+1];3579 xyz_zero[3*3+2]=xyz_list[3*3+2];3580 }3581 else if(levelset[0]==0. && levelset[2]==0.){ //front is on point 0 and 13582 xyz_zero[3*0+0]=xyz_list[2*3+0];3583 xyz_zero[3*0+1]=xyz_list[2*3+1];3584 xyz_zero[3*0+2]=xyz_list[2*3+2];3585 3586 /*New point 2*/3587 xyz_zero[3*1+0]=xyz_list[0*3+0];3588 xyz_zero[3*1+1]=xyz_list[0*3+1];3589 xyz_zero[3*1+2]=xyz_list[0*3+2];3590 3591 /*New point 3*/3592 xyz_zero[3*2+0]=xyz_list[3*3+0];3593 xyz_zero[3*2+1]=xyz_list[3*3+1];3594 xyz_zero[3*2+2]=xyz_list[3*3+2];3595 3596 /*New point 4*/3597 xyz_zero[3*3+0]=xyz_list[5*3+0];3598 xyz_zero[3*3+1]=xyz_list[5*3+1];3599 xyz_zero[3*3+2]=xyz_list[5*3+2];3600 }3601 else if(levelset[1]==0. && levelset[2]==0.){ //front is on point 0 and 13602 xyz_zero[3*0+0]=xyz_list[1*3+0];3603 xyz_zero[3*0+1]=xyz_list[1*3+1];3604 xyz_zero[3*0+2]=xyz_list[1*3+2];3605 3606 /*New point 2*/3607 xyz_zero[3*1+0]=xyz_list[2*3+0];3608 xyz_zero[3*1+1]=xyz_list[2*3+1];3609 xyz_zero[3*1+2]=xyz_list[2*3+2];3610 3611 /*New point 3*/3612 xyz_zero[3*2+0]=xyz_list[5*3+0];3613 xyz_zero[3*2+1]=xyz_list[5*3+1];3614 xyz_zero[3*2+2]=xyz_list[5*3+2];3615 3616 /*New point 4*/3617 xyz_zero[3*3+0]=xyz_list[4*3+0];3618 xyz_zero[3*3+1]=xyz_list[4*3+1];3619 xyz_zero[3*3+2]=xyz_list[4*3+2];3620 }3621 else _error_("Case not covered");3622 3623 /*Assign output pointer*/3624 *pxyz_zero= xyz_zero;3625 }3626 /*}}}*/3627 3403 3628 3404 #ifdef _HAVE_GIAIVINS_ … … 3642 3418 3643 3419 /*Check that name is an element input*/ 3644 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");3420 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 3645 3421 3646 3422 switch(type){ … … 3677 3453 3678 3454 /*Check that name is an element input*/ 3679 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");3455 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 3680 3456 3681 3457 switch(type){ -
issm/trunk/src/c/classes/Elements/Penta.h
r22758 r23189 66 66 int FiniteElement(void); 67 67 IssmDouble FloatingArea(bool scaled); 68 void FSContactMigration(Vector<IssmDouble>* vertex grounded,Vector<IssmDouble>* vertexfloating);68 void FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure); 69 69 IssmDouble GetArea3D(void){_error_("not implemented yet!");}; 70 70 IssmDouble GetAreaSpherical(void){_error_("not implemented yet!");}; … … 86 86 Penta* GetLowerPenta(void); 87 87 Penta* GetUpperPenta(void); 88 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data ,bool onsid);89 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset ,bool onsid);88 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data); 89 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset); 90 90 void GetVerticesCoordinatesBase(IssmDouble** pxyz_list); 91 91 void GetVerticesCoordinatesTop(IssmDouble** pxyz_list); … … 143 143 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");}; 144 144 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");}; 145 void PicoComputeBasalMelt(void){_error_("not implemented yet");}; 145 146 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding); 146 147 int PressureInterpolation(); … … 148 149 void ResetFSBasalBoundaryCondition(void); 149 150 void ResetHooks(); 150 void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);151 151 void SetClone(int* minranks); 152 152 void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M); … … 178 178 void VerticalSegmentIndicesBase(int** pindices,int* pnumseg); 179 179 void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input); 180 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);181 180 182 181 #ifdef _HAVE_DAKOTA_ … … 198 197 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 199 198 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 200 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};199 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 201 200 #endif 202 201 -
issm/trunk/src/c/classes/Elements/Seg.cpp
r22758 r23189 104 104 return seg; 105 105 106 107 106 } 108 107 /*}}}*/ … … 141 140 /*}}}*/ 142 141 void Seg::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 143 142 144 143 /* Intermediaries */ 145 144 int nrfrontnodes,index; -
issm/trunk/src/c/classes/Elements/Seg.h
r22758 r23189 73 73 int GetNumberOfNodes(int enum_type){_error_("not implemented yet");}; 74 74 int GetNumberOfVertices(void); 75 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset ,bool onsid){_error_("not implemented yet");};76 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data ,bool onsid){_error_("not implemented yet");};75 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset){_error_("not implemented yet");}; 76 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");}; 77 77 void GetVerticesCoordinates(IssmDouble** pxyz_list); 78 78 void GetVerticesCoordinatesBase(IssmDouble** pxyz_list){_error_("not implemented yet");}; … … 132 132 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");}; 133 133 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");}; 134 void PicoComputeBasalMelt(void){_error_("not implemented yet");}; 134 135 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");}; 135 136 int PressureInterpolation(void){_error_("not implemented yet");}; … … 164 165 void VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");}; 165 166 void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");}; 166 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};167 167 IssmDouble GetArea3D(void){_error_("not implemented yet!");}; 168 168 IssmDouble GetAreaSpherical(void){_error_("not implemented yet!");}; … … 179 179 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 180 180 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 181 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};181 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 182 182 IssmDouble OceanArea(void){_error_("not implemented yet!");}; 183 183 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");}; -
issm/trunk/src/c/classes/Elements/Tetra.cpp
r22758 r23189 501 501 502 502 /*Add input to the element: */ 503 this->inputs->AddInput(new TetraInput(enum_type,values, P1Enum));503 this->inputs->AddInput(new TetraInput(enum_type,values,this->element_type)); 504 504 505 505 /*Free ressources:*/ … … 1029 1029 } 1030 1030 /*}}}*/ 1031 void Tetra::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/1032 /*Compute portion of the element that is grounded*/1033 1034 IssmDouble levelset[NUMVERTICES];1035 IssmDouble* xyz_zero = xNew<IssmDouble>(3*3);1036 1037 /*Recover parameters and values*/1038 GetInputListOnVertices(&levelset[0],levelsetenum);1039 1040 if(levelset[0]==0. && levelset[1]==0. && levelset[2]==0.){1041 xyz_zero[3*0+0]=xyz_list[0*3+0];1042 xyz_zero[3*0+1]=xyz_list[0*3+1];1043 xyz_zero[3*0+2]=xyz_list[0*3+2];1044 1045 /*New point 2*/1046 xyz_zero[3*1+0]=xyz_list[1*3+0];1047 xyz_zero[3*1+1]=xyz_list[1*3+1];1048 xyz_zero[3*1+2]=xyz_list[1*3+2];1049 1050 /*New point 3*/1051 xyz_zero[3*2+0]=xyz_list[2*3+0];1052 xyz_zero[3*2+1]=xyz_list[2*3+1];1053 xyz_zero[3*2+2]=xyz_list[2*3+2];1054 }1055 else if(levelset[0]==0. && levelset[1]==0. && levelset[3]==0.){1056 xyz_zero[3*0+0]=xyz_list[0*3+0];1057 xyz_zero[3*0+1]=xyz_list[0*3+1];1058 xyz_zero[3*0+2]=xyz_list[0*3+2];1059 1060 /*New point 2*/1061 xyz_zero[3*1+0]=xyz_list[1*3+0];1062 xyz_zero[3*1+1]=xyz_list[1*3+1];1063 xyz_zero[3*1+2]=xyz_list[1*3+2];1064 1065 /*New point 3*/1066 xyz_zero[3*2+0]=xyz_list[3*3+0];1067 xyz_zero[3*2+1]=xyz_list[3*3+1];1068 xyz_zero[3*2+2]=xyz_list[3*3+2];1069 }1070 else if(levelset[1]==0. && levelset[2]==0. && levelset[3]==0.){1071 xyz_zero[3*0+0]=xyz_list[1*3+0];1072 xyz_zero[3*0+1]=xyz_list[1*3+1];1073 xyz_zero[3*0+2]=xyz_list[1*3+2];1074 1075 /*New point 2*/1076 xyz_zero[3*1+0]=xyz_list[2*3+0];1077 xyz_zero[3*1+1]=xyz_list[2*3+1];1078 xyz_zero[3*1+2]=xyz_list[2*3+2];1079 1080 /*New point 3*/1081 xyz_zero[3*2+0]=xyz_list[3*3+0];1082 xyz_zero[3*2+1]=xyz_list[3*3+1];1083 xyz_zero[3*2+2]=xyz_list[3*3+2];1084 }1085 else if(levelset[2]==0. && levelset[0]==0. && levelset[3]==0.){1086 xyz_zero[3*0+0]=xyz_list[2*3+0];1087 xyz_zero[3*0+1]=xyz_list[2*3+1];1088 xyz_zero[3*0+2]=xyz_list[2*3+2];1089 1090 /*New point 2*/1091 xyz_zero[3*1+0]=xyz_list[0*3+0];1092 xyz_zero[3*1+1]=xyz_list[0*3+1];1093 xyz_zero[3*1+2]=xyz_list[0*3+2];1094 1095 /*New point 3*/1096 xyz_zero[3*2+0]=xyz_list[3*3+0];1097 xyz_zero[3*2+1]=xyz_list[3*3+1];1098 xyz_zero[3*2+2]=xyz_list[3*3+2];1099 }1100 else _error_("Case not covered");1101 1102 /*Assign output pointer*/1103 *pxyz_zero= xyz_zero;1104 }1105 /*}}}*/ -
issm/trunk/src/c/classes/Elements/Tetra.h
r22758 r23189 79 79 int GetNumberOfNodes(int enum_type){_error_("not implemented yet");}; 80 80 int GetNumberOfVertices(void); 81 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset ,bool onsid){_error_("not implemented yet");};82 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data ,bool onsid){_error_("not implemented yet");};81 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset){_error_("not implemented yet");}; 82 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");}; 83 83 void GetVerticesCoordinatesBase(IssmDouble** pxyz_list); 84 84 void GetVerticesCoordinatesTop(IssmDouble** pxyz_list); … … 140 140 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");}; 141 141 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");}; 142 void PicoComputeBasalMelt(void){_error_("not implemented yet");}; 142 143 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");}; 143 144 int PressureInterpolation(void); … … 173 174 void VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");}; 174 175 void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input); 175 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);176 176 177 177 #ifdef _HAVE_GIAIVINS_ … … 186 186 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 187 187 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 188 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};188 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 189 189 IssmDouble OceanArea(void){_error_("not implemented yet!");}; 190 190 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");}; -
issm/trunk/src/c/classes/Elements/Tria.cpp
r22822 r23189 106 106 } 107 107 else tria->nodes = NULL; 108 108 109 109 tria->vertices = (Vertex**)this->hvertices->deliverp(); 110 110 tria->material = (Material*)this->hmaterial->delivers(); … … 115 115 /*}}}*/ 116 116 void Tria::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 117 117 118 118 MARSHALLING_ENUM(TriaEnum); 119 119 120 120 /*Call parent classes: */ 121 121 ElementHook::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); … … 135 135 /*Call inputs method*/ 136 136 _assert_(this->inputs); 137 137 138 138 int domaintype; 139 139 parameters->FindParam(&domaintype,DomainTypeEnum); … … 185 185 186 186 int tria_vertex_ids[3]; 187 187 188 188 for(int k=0;k<3;k++){ 189 189 tria_vertex_ids[k]=reCast<int>(iomodel->elements[3*this->Sid()+k]); //ids for vertices are in the elements array from Matlab … … 328 328 /*}}}*/ 329 329 void Tria::CalvingCrevasseDepth(){/*{{{*/ 330 330 331 331 IssmDouble xyz_list[NUMVERTICES][3]; 332 332 IssmDouble calvingrate[NUMVERTICES]; … … 340 340 /* Get node coordinates and dof list: */ 341 341 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 342 342 343 343 /*Get the critical fraction of thickness surface and basal crevasses penetrate for calving onset*/ 344 344 this->parameters->FindParam(&critical_fraction,CalvingCrevasseDepthEnum); 345 345 346 346 IssmDouble rho_ice = this->GetMaterialParameter(MaterialsRhoIceEnum); 347 347 IssmDouble rho_seawater = this->GetMaterialParameter(MaterialsRhoSeawaterEnum); … … 361 361 Input* s_xy_input = inputs->GetInput(DeviatoricStressxyEnum); _assert_(s_xy_input); 362 362 Input* s_yy_input = inputs->GetInput(DeviatoricStressyyEnum); _assert_(s_yy_input); 363 363 364 364 /*Loop over all elements of this partition*/ 365 365 GaussTria* gauss=new GaussTria(); 366 366 for (int iv=0;iv<NUMVERTICES;iv++){ 367 367 gauss->GaussVertex(iv); 368 368 369 369 H_input->GetInputValue(&thickness,gauss); 370 370 bed_input->GetInputValue(&bed,gauss); … … 378 378 s_xy_input->GetInputValue(&s_xy,gauss); 379 379 s_yy_input->GetInputValue(&s_yy,gauss); 380 380 381 381 vel=sqrt(vx*vx+vy*vy)+1.e-14; 382 382 … … 384 384 s2=(s_xx+s_yy)/2.-sqrt(pow((s_xx-s_yy)/2.,2)+pow(s_xy,2)); 385 385 if(fabs(s2)>fabs(s1)){stmp=s2; s2=s1; s1=stmp;} 386 386 387 387 Ho = thickness - (rho_seawater/rho_ice) * (-bed); 388 388 if(Ho<0.) Ho=0.; … … 399 399 // water_height = surface_crevasse[iv]; 400 400 //} 401 401 402 402 /*basal crevasse*/ 403 403 //basal_crevasse[iv] = (rho_ice/(rho_seawater-rho_ice)) * (rheology_B * strainparallel * pow(straineffective,((1/rheology_n)-1)) / (rho_ice*constant_g) - Ho); … … 405 405 if (basal_crevasse[iv]<0.) basal_crevasse[iv]=0.; 406 406 if (bed>0.) basal_crevasse[iv] = 0.; 407 407 408 408 H_surf = surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height - critical_fraction*float_depth; 409 409 H_surfbasal = (surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height + basal_crevasse[iv])-(critical_fraction*thickness); 410 410 411 411 crevasse_depth[iv] = max(H_surf,H_surfbasal); 412 412 } 413 413 414 414 this->inputs->AddInput(new TriaInput(SurfaceCrevasseEnum,&surface_crevasse[0],P1Enum)); 415 415 this->inputs->AddInput(new TriaInput(BasalCrevasseEnum,&basal_crevasse[0],P1Enum)); … … 461 461 else 462 462 calvingrate[iv]=0.; 463 463 464 464 calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14); 465 465 calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14); … … 562 562 IssmDouble vorticity_xy[NUMVERTICES]; 563 563 GaussTria* gauss=NULL; 564 564 565 565 /* Get node coordinates and dof list: */ 566 566 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); … … 569 569 Input* vx_input=this->GetInput(EsaXmotionEnum); _assert_(vx_input); 570 570 Input* vy_input=this->GetInput(EsaYmotionEnum); _assert_(vy_input); 571 571 572 572 /* Start looping on the number of vertices: */ 573 573 gauss=new GaussTria(); … … 753 753 if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput"); 754 754 755 GradientIndexing(&gradidlist[0],control_index ,true);755 GradientIndexing(&gradidlist[0],control_index); 756 756 757 757 for(int n=0;n<N;n++){ … … 773 773 } 774 774 775 776 775 }/*}}}*/ 777 776 void Tria::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/ … … 823 822 824 823 }/*}}}*/ 825 void Tria::CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){/*{{{*/ 826 827 /*Intermediaries*/ 828 IssmDouble d,xn,yn; 824 void Tria::CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum){/*{{{*/ 829 825 830 826 /*Get current field and vertex coordinates*/ 831 IssmDouble ls[NUMVERTICES]; 832 IssmDouble xyz_list[NUMVERTICES][3]; 833 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 827 IssmDouble ls[NUMVERTICES],distance; 834 828 GetInputListOnVertices(&ls[0],distanceenum); 835 829 836 830 /*Get distance from list of segments and reset ls*/ 837 831 for(int j=0;j<NUMVERTICES;j++){ 838 IssmDouble dmin = 1.e+50; 839 for(int i=0;i<numsegments;i++){ 840 IssmDouble x = xyz_list[j][0]; 841 IssmDouble y = xyz_list[j][1]; 842 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]); 843 844 /*Segment has a length of 0*/ 845 if(l2==0.){ 846 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 847 if(d<dmin) dmin = d; 848 continue; 849 } 850 851 /*Consider the line extending the segment, parameterized as v + t (w - v). 852 *We find projection of point p onto the line. 853 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/ 854 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2; 855 if(t < 0.0){ 856 // Beyond the 'v' end of the segment 857 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 858 } 859 else if (t > 1.0){ 860 // Beyond the 'w' end of the segment 861 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]); 862 } 863 else{ 864 // Projection falls on the segment 865 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]); 866 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]); 867 d = (x-xn)*(x-xn)+(y-yn)*(y-yn); 868 } 869 870 if(d<dmin) dmin = d; 871 } 872 873 /*Update signed distance*/ 874 dmin = sqrt(dmin); 875 // if(dmin>10000) dmin=10000; 832 distance=distances[this->vertices[j]->Lid()]; 833 if(xIsNan<IssmDouble>(distance)) _error_("NaN found in vector"); 834 if(xIsInf<IssmDouble>(distance)) _error_("Inf found in vector"); 835 836 /*FIXME: do we really need this?*/ 837 if(distanceenum==MaskIceLevelsetEnum) if(distance>10000) distance=10000; 876 838 if(ls[j]>0){ 877 ls[j] = d min;839 ls[j] = distance; 878 840 } 879 841 else{ 880 ls[j] = - d min;842 ls[j] = - distance; 881 843 } 882 844 } … … 1041 1003 } 1042 1004 /*}}}*/ 1043 void Tria::FSContactMigration(Vector<IssmDouble>* vertex grounded,Vector<IssmDouble>* vertexfloating){/*{{{*/1005 void Tria::FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure){/*{{{*/ 1044 1006 1045 1007 if(!IsOnBase()) return; … … 1049 1011 1050 1012 if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum){ 1051 for(int i=0;i<NUMVERTICES;i++){ 1052 vertexgrounded->SetValue(vertices[i]->Pid(),+9999.,INS_VAL); 1053 vertexfloating->SetValue(vertices[i]->Pid(),+9999.,INS_VAL); 1054 } 1055 } 1056 else{ 1057 /*Intermediaries*/ 1058 IssmDouble* xyz_list = NULL; 1059 IssmDouble* xyz_list_base = NULL; 1060 IssmDouble pressure,water_pressure,sigma_nn,viscosity,bed,base; 1061 IssmDouble bed_normal[2]; 1062 IssmDouble epsilon[3]; /* epsilon=[exx,eyy,exy];*/ 1063 IssmDouble surface=0,value=0; 1064 bool grounded; 1065 1066 /* Get node coordinates and dof list: */ 1067 GetVerticesCoordinates(&xyz_list); 1068 GetVerticesCoordinatesBase(&xyz_list_base); 1069 1070 /*Retrieve all inputs we will be needing: */ 1071 Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input); 1072 Input* base_input = inputs->GetInput(BaseEnum); _assert_(base_input); 1073 Input* bed_input = inputs->GetInput(BedEnum); _assert_(bed_input); 1074 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input); 1075 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input); 1076 1077 /*Create gauss point in the middle of the basal edge*/ 1078 Gauss* gauss=NewGaussBase(1); 1079 gauss->GaussPoint(0); 1080 1081 if(!IsFloating()){ 1082 /*Check for basal force only if grounded and touching GL*/ 1083 // if(this->inputs->Min(MaskGroundediceLevelsetEnum)==0.){ 1084 this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input); 1085 this->material->ViscosityFS(&viscosity,2,xyz_list,gauss,vx_input,vy_input,NULL); 1086 pressure_input->GetInputValue(&pressure, gauss); 1087 base_input->GetInputValue(&base, gauss); 1088 1089 /*Compute Stress*/ 1090 IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure; 1091 IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure; 1092 IssmDouble sigma_xy=2.*viscosity*epsilon[2]; 1093 1094 /*Get normal vector to the bed */ 1095 NormalBase(&bed_normal[0],xyz_list_base); 1096 1097 /*basalforce*/ 1098 sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + 2.*sigma_xy*bed_normal[0]*bed_normal[1]; 1099 1100 /*Compute water pressure*/ 1101 IssmDouble rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum); 1102 IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum); 1103 IssmDouble gravity = matpar->GetMaterialParameter(ConstantsGEnum); 1104 water_pressure=gravity*rho_water*base; 1105 1106 /*Compare basal stress to water pressure and determine whether it should ground*/ 1107 if (sigma_nn<water_pressure) grounded=true; 1108 else grounded=false; 1109 } 1110 else{ 1111 /*Check for basal elevation if floating*/ 1112 base_input->GetInputValue(&base, gauss); 1113 bed_input->GetInputValue(&bed, gauss); 1114 if(base<bed) grounded=true; 1115 else grounded=false; 1116 } 1117 for(int i=0;i<NUMVERTICES;i++){ 1118 if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL); 1119 else vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL); 1120 } 1121 1122 /*clean up*/ 1123 delete gauss; 1124 xDelete<IssmDouble>(xyz_list); 1125 xDelete<IssmDouble>(xyz_list_base); 1126 } 1013 _error_(" contact contiditon only works for FS elements"); 1014 } 1015 /*Intermediaries*/ 1016 IssmDouble* xyz_list = NULL; 1017 IssmDouble bed_normal[2],base[NUMVERTICES],bed[NUMVERTICES],surface[NUMVERTICES],phi[NUMVERTICES]; 1018 IssmDouble water_pressure[NUMVERTICES],pressureice[NUMVERTICES],pressure[NUMVERTICES]; 1019 IssmDouble sigmaxx[NUMVERTICES],sigmayy[NUMVERTICES],sigmaxy[NUMVERTICES],sigma_nn[NUMVERTICES]; 1020 IssmDouble viscosity,epsilon[NUMVERTICES]; 1021 GetInputListOnVertices(&base[0],BaseEnum); 1022 GetInputListOnVertices(&bed[0],BedEnum); 1023 GetInputListOnVertices(&surface[0],SurfaceEnum); 1024 GetInputListOnVertices(&pressure[0],PressureEnum); 1025 GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum); 1026 IssmDouble rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum); 1027 IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum); 1028 IssmDouble gravity = matpar->GetMaterialParameter(ConstantsGEnum); 1029 1030 /* Get node coordinates and dof list: */ 1031 GetVerticesCoordinates(&xyz_list); 1032 /*Retrieve all inputs we will be needing: */ 1033 Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input); 1034 Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input); 1035 1036 /*1. Recover stresses at the base*/ 1037 GaussTria* gauss=new GaussTria(); 1038 for (int iv=0;iv<NUMVERTICES;iv++){ 1039 gauss->GaussVertex(iv); 1040 1041 /*Compute strain rate viscosity and pressure: */ 1042 this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input); 1043 this->material->ViscosityFS(&viscosity,2,xyz_list,gauss,vx_input,vy_input,NULL); 1044 /*FIXME: this is for Hongju only*/ 1045 // pressureice[iv]=gravity*rho_ice*(surface[iv]-base[iv]); 1046 // if (pressure[iv]/pressureice[iv]>1) pressure[iv]=pressureice[iv]; 1047 1048 /*Compute Stress*/ 1049 sigmaxx[iv]=2*viscosity*epsilon[0]-pressure[iv]; 1050 sigmayy[iv]=2*viscosity*epsilon[1]-pressure[iv]; 1051 sigmaxy[iv]=2*viscosity*epsilon[2]; 1052 } 1053 1054 /*2. compute contact condition*/ 1055 for(int i=0;i<NUMVERTICES;i++){ 1056 /*If was grounded*/ 1057 if (phi[i]>=0.){ 1058 NormalBase(&bed_normal[0],xyz_list); 1059 sigma_nn[i]=-1*(sigmaxx[i]*bed_normal[0]*bed_normal[0] + sigmayy[i]*bed_normal[1]*bed_normal[1]+2*sigmaxy[i]*bed_normal[0]*bed_normal[1]); 1060 water_pressure[i]=-gravity*rho_water*base[i]; 1061 vertex_sigmann->SetValue(vertices[i]->Pid(),sigma_nn[i],ADD_VAL); 1062 vertex_waterpressure->SetValue(vertices[i]->Pid(),water_pressure[i],ADD_VAL); 1063 } 1064 /*If was floating*/ 1065 else{ 1066 /*Tricky part: 1067 * 1. if base is now touching, we put 1 for sigma_nn and leave water pressure at 0 so that the rest of the module will reground this vertex 1068 * 2. if base is still above bed, water pressure is set as 1, sigma_nn is left as 0, so the GL module will keep it afloat*/ 1069 if(base[i]<bed[i]) vertex_sigmann->SetValue(vertices[i]->Pid(),+1.,ADD_VAL); 1070 vertex_waterpressure->SetValue(vertices[i]->Pid(),+1.,ADD_VAL); 1071 } 1072 } 1073 1074 /*clean up*/ 1075 delete gauss; 1076 xDelete<IssmDouble>(xyz_list); 1127 1077 } 1128 1078 /*}}}*/ … … 1354 1304 1355 1305 } 1356 else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum ){1306 else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum || domaintype==Domain3DsurfaceEnum){ 1357 1307 /*Check that not all nodes are grounded or floating*/ 1358 1308 if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded … … 1429 1379 1430 1380 /*Compute fraction of grounded element*/ 1431 GetJacobianDeterminant(&area_init, xyz_list,NULL); 1432 GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL); 1381 if(domaintype==Domain3DsurfaceEnum){ //hack, need to be implemented in a Tria 3D 1382 GetJacobianDeterminant3D(&area_init, xyz_list,NULL); 1383 GetJacobianDeterminant3D(&area_grounded, &xyz_bis[0][0],NULL); 1384 } 1385 else{ 1386 GetJacobianDeterminant(&area_init, xyz_list,NULL); 1387 GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL); 1388 } 1433 1389 if(mainlyfloating==true) area_grounded=area_init-area_grounded; 1434 1390 phi=area_grounded/area_init; … … 1443 1399 /*}}}*/ 1444 1400 void Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 1445 1401 1446 1402 /* Intermediaries */ 1447 1403 int i, dir,nrfrontnodes; … … 1532 1488 }/*}}}*/ 1533 1489 void Tria::GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/ 1534 1490 1535 1491 /* GetLevelsetIntersection computes: 1536 1492 * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion, … … 1608 1564 /*}}}*/ 1609 1565 void Tria::GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* gl){/*{{{*/ 1610 1566 1611 1567 /*Computeportion of the element that has a positive levelset*/ 1612 1568 … … 1689 1645 } 1690 1646 /*}}}*/ 1691 void Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data ,bool onsid){/*{{{*/1647 void Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/ 1692 1648 1693 1649 int vertexidlist[NUMVERTICES]; … … 1695 1651 1696 1652 /*Get out if this is not an element input*/ 1697 if(!IsInput (control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");1653 if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput"); 1698 1654 1699 1655 /*Prepare index list*/ 1700 GradientIndexing(&vertexidlist[0],control_index ,onsid);1656 GradientIndexing(&vertexidlist[0],control_index); 1701 1657 1702 1658 /*Get input (either in element or material)*/ … … 1711 1667 } 1712 1668 /*}}}*/ 1713 void Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset , bool onsid){/*{{{*/1669 void Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset){/*{{{*/ 1714 1670 1715 1671 int* idlist = NULL; … … 1718 1674 1719 1675 /*Get out if this is not an element input*/ 1720 if(!IsInput (control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");1676 if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput"); 1721 1677 Input* input=(Input*)this->inputs->GetInput(control_enum); _assert_(input); 1722 1678 1723 1679 parameters->FindParam(&M,NULL,ControlInputSizeMEnum); 1724 1680 1725 1681 /*Cast to Controlinput*/ 1726 1682 if(input->ObjectEnum()!=ControlInputEnum) _error_("input " << EnumToStringx(control_enum) << " is not a ControlInput"); 1727 1683 ControlInput* controlinput = xDynamicCast<ControlInput*>(input); 1728 1684 1729 1685 if(strcmp(data,"value")==0){ 1730 1686 input = controlinput->values; … … 1743 1699 } 1744 1700 /*Check what input we are dealing with*/ 1745 1701 1746 1702 switch(input->ObjectEnum()){ 1747 1703 case TriaInputEnum: … … 1753 1709 idlist = xNew<int>(NUMVERTICES); 1754 1710 values = xNew<IssmDouble>(NUMVERTICES); 1755 GradientIndexing(&idlist[0],control_index ,true);1711 GradientIndexing(&idlist[0],control_index); 1756 1712 for(int i=0;i<NUMVERTICES;i++){ 1757 1713 values[i] = triainput->values[i]; … … 1760 1716 break; 1761 1717 } 1762 1718 1763 1719 case TransientInputEnum: 1764 1720 { … … 1905 1861 1906 1862 if(!IsIceInElement())return 0.; 1863 //if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)) return 0; 1907 1864 1908 1865 int domaintype; … … 2024 1981 base_input->GetInputAverage(&bed); 2025 1982 bed_input->GetInputAverage(&bathymetry); 2026 1983 2027 1984 /*Return: */ 2028 1985 return base*(surface-bed+min(rho_water/rho_ice*bathymetry,0.)); … … 2068 2025 if(control_analysis && ad_analysis) iomodel->FindConstant(&num_control_type,"md.autodiff.num_independent_objects"); 2069 2026 if(control_analysis && ad_analysis) iomodel->FindConstant(&num_responses,"md.autodiff.num_dependent_objects"); 2070 2071 2072 2027 2073 2028 /*Recover vertices ids needed to initialize inputs*/ … … 2221 2176 2222 2177 /*Add input to the element: */ 2223 this->inputs->AddInput(new TriaInput(enum_type,values, P1Enum));2178 this->inputs->AddInput(new TriaInput(enum_type,values,this->element_type)); 2224 2179 2225 2180 /*Free ressources:*/ … … 2231 2186 2232 2187 /*Check that name is an element input*/ 2233 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");2188 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 2234 2189 2235 2190 int numnodes; … … 2238 2193 2239 2194 switch(type){ 2240 case VertexPIdEnum: 2241 values = xNew<IssmDouble>(NUMVERTICES); 2242 for(int i=0;i<NUMVERTICES;i++){ 2243 values[i]=vector[this->vertices[i]->Pid()]; 2244 } 2245 /*update input*/ 2246 this->inputs->AddInput(new TriaInput(name,values,P1Enum)); 2247 break; 2248 2249 case VertexSIdEnum: 2250 values = xNew<IssmDouble>(NUMVERTICES); 2251 for(int i=0;i<NUMVERTICES;i++){ 2252 values[i]=vector[this->vertices[i]->Sid()]; 2253 } 2254 /*update input*/ 2255 this->inputs->AddInput(new TriaInput(name,values,P1Enum)); 2256 break; 2257 2258 case NodesEnum: 2259 /*Get number of nodes and dof list: */ 2260 numnodes = this->NumberofNodes(this->element_type); 2261 values = xNew<IssmDouble>(numnodes); 2262 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 2263 2264 for(int i=0;i<numnodes;i++){ 2265 values[i]=vector[doflist[i]]; 2266 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2267 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2268 } 2269 this->inputs->AddInput(new TriaInput(name,values,this->element_type)); 2270 break; 2271 2272 case NodeSIdEnum: 2273 /*Get number of nodes and dof list: */ 2274 numnodes = this->NumberofNodes(this->element_type); 2275 values = xNew<IssmDouble>(numnodes); 2276 2277 for(int i=0;i<numnodes;i++){ 2278 values[i]=vector[nodes[i]->Sid()]; 2279 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2280 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2281 } 2282 this->inputs->AddInput(new TriaInput(name,values,this->element_type)); 2283 break; 2284 2285 default: 2286 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet"); 2195 case VertexLIdEnum: 2196 values = xNew<IssmDouble>(NUMVERTICES); 2197 for(int i=0;i<NUMVERTICES;i++){ 2198 values[i]=vector[this->vertices[i]->Lid()]; 2199 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2200 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2201 } 2202 /*update input*/ 2203 this->inputs->AddInput(new TriaInput(name,values,P1Enum)); 2204 break; 2205 2206 case VertexPIdEnum: 2207 values = xNew<IssmDouble>(NUMVERTICES); 2208 for(int i=0;i<NUMVERTICES;i++){ 2209 values[i]=vector[this->vertices[i]->Pid()]; 2210 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2211 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2212 } 2213 /*update input*/ 2214 this->inputs->AddInput(new TriaInput(name,values,P1Enum)); 2215 break; 2216 2217 case VertexSIdEnum: 2218 values = xNew<IssmDouble>(NUMVERTICES); 2219 for(int i=0;i<NUMVERTICES;i++){ 2220 values[i]=vector[this->vertices[i]->Sid()]; 2221 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2222 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2223 } 2224 /*update input*/ 2225 this->inputs->AddInput(new TriaInput(name,values,P1Enum)); 2226 break; 2227 2228 case NodesEnum: 2229 /*Get number of nodes and dof list: */ 2230 numnodes = this->NumberofNodes(this->element_type); 2231 values = xNew<IssmDouble>(numnodes); 2232 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 2233 2234 for(int i=0;i<numnodes;i++){ 2235 values[i]=vector[doflist[i]]; 2236 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2237 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2238 } 2239 this->inputs->AddInput(new TriaInput(name,values,this->element_type)); 2240 break; 2241 2242 case NodeSIdEnum: 2243 /*Get number of nodes and dof list: */ 2244 numnodes = this->NumberofNodes(this->element_type); 2245 values = xNew<IssmDouble>(numnodes); 2246 2247 for(int i=0;i<numnodes;i++){ 2248 values[i]=vector[nodes[i]->Sid()]; 2249 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector"); 2250 if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector"); 2251 } 2252 this->inputs->AddInput(new TriaInput(name,values,this->element_type)); 2253 break; 2254 2255 default: 2256 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet"); 2287 2257 } 2288 2258 … … 2420 2390 /*}}}*/ 2421 2391 IssmDouble Tria::Masscon(IssmDouble* levelset){ /*{{{*/ 2422 2423 2392 2424 2393 /*intermediary: */ … … 2434 2403 IssmDouble fraction1,fraction2; 2435 2404 bool mainlynegative=true; 2436 2405 2437 2406 /*Output:*/ 2438 2407 volume=0; … … 2443 2412 /*Retrieve inputs required:*/ 2444 2413 thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input); 2445 2414 2446 2415 /*Retrieve material parameters: */ 2447 2416 rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum); … … 2452 2421 values[i]=levelset[this->vertices[i]->Sid()]; 2453 2422 } 2454 2423 2455 2424 /*Ok, use the level set values to figure out where we put our gaussian points:*/ 2456 2425 this->GetLevelsetPositivePart(&point1,&fraction1,&fraction2,&mainlynegative,values); … … 2904 2873 dist_cf_input->GetInputValue(&dist_cf,gauss); 2905 2874 delete gauss; 2906 2875 2907 2876 /*Ensure values are positive for floating ice*/ 2908 2877 dist_gl = fabs(dist_gl); … … 2922 2891 } 2923 2892 } 2924 if(boxid==-1) {_error_("No boxid found for element " << this->Sid() << "!");}2893 if(boxid==-1) _error_("No boxid found for element " << this->Sid() << "!"); 2925 2894 2926 2895 this->inputs->AddInput(new IntInput(BasalforcingsPicoBoxIdEnum, boxid)); … … 2937 2906 IssmDouble gamma_T, overturning_coeff, thickness; 2938 2907 IssmDouble pressure, T_star,p_coeff, q_coeff; 2908 bool isplume; 2939 2909 2940 2910 /*Get variables*/ … … 2959 2929 this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum); 2960 2930 this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 2931 this->parameters->FindParam(&isplume, BasalforcingsPicoIsplumeEnum); 2961 2932 Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input); 2962 2933 _assert_(basinid<=num_basins); 2963 2934 2964 IssmDouble* boxareas = xNew<IssmDouble>(num_basins*maxbox);2935 IssmDouble* boxareas = NULL; 2965 2936 this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum); 2937 _assert_(M==num_basins*maxbox); 2966 2938 2967 2939 IssmDouble area_boxi = boxareas[basinid*maxbox+boxid]; … … 2994 2966 2995 2967 /* To avoid negatives under the square root */ 2996 if((0.25*pow(p_coeff,2)-q_coeff)<0){ 2997 q_coeff = 0.25*p_coeff*p_coeff; 2998 } 2968 if((0.25*pow(p_coeff,2)-q_coeff)<0) q_coeff = 0.25*p_coeff*p_coeff; 2999 2969 3000 2970 Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff)); 3001 2971 Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]); 3002 2972 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure; 3003 basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);2973 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]); 3004 2974 overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i])); 3005 2975 } 3006 2976 3007 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);2977 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 3008 2978 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum); 3009 2979 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum); … … 3038 3008 Socs[i] = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda)); 3039 3009 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure; 3040 basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);3041 } 3042 3043 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);3010 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]); 3011 } 3012 3013 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 3044 3014 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum); 3045 3015 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum); … … 3056 3026 } 3057 3027 /*}}}*/ 3028 void Tria::PicoComputeBasalMelt(void){/*{{{*/ 3029 3030 if(!this->IsIceInElement() || !this->IsFloating()) return; 3031 3032 IssmDouble E0, Cd, CdT, YT, lam1, lam2, lam3, M0, CdTS0, y1, y2, x0; 3033 IssmDouble Tf_gl, YTS, CdTS, G1, G2, G3, g_alpha, M, l, X_hat, M_hat; 3034 IssmDouble alpha, zgl, Toc, Soc, z_base, yts, slopex, slopey; 3035 3036 /*Get variables*/ 3037 E0 = 3.6e-2; //Entrainment coefficient 3038 Cd = 2.5e-3; //Drag coefficient 3039 CdT = 1.1e-3; //Turbulent heat exchange coefficient 3040 YT = CdT/sqrt(Cd); //Heat exchange coefficient 3041 lam1 = -5.73e-2; //Freezing point-salinity coefficient (degrees C) 3042 lam2 = 8.32e-2; //Freezing point offset (degrees C) 3043 lam3 = 7.61e-4; //Freezing point-depth coefficient (K m-1) 3044 M0 = 10.; //Melt-rate parameter (m yr-1 C-2) 3045 CdTS0 = 6e-4; //Heat exchange parameter 3046 y1 = 0.545; //Heat exchange parameter 3047 y2 = 3.5e-5; //Heat exchange parameter 3048 x0 = 0.56; //Dimentionless scaling factor 3049 3050 /*Define arrays*/ 3051 IssmDouble basalmeltrates_shelf[NUMVERTICES]; //Basal melt-rate 3052 //IssmDouble slope[NUMVERTICES]; //Basal slope 3053 3054 /*Polynomial coefficients*/ 3055 IssmDouble p[12]; 3056 p[0] = 0.1371330075095435; 3057 p[1] = 5.527656234709359E1; 3058 p[2] = -8.951812433987858E2; 3059 p[3] = 8.927093637594877E3; 3060 p[4] = -5.563863123811898E4; 3061 p[5] = 2.218596970948727E5; 3062 p[6] = -5.820015295669482E5; 3063 p[7] = 1.015475347943186E6; 3064 p[8] = -1.166290429178556E6; 3065 p[9] = 8.466870335320488E5; 3066 p[10] = -3.520598035764990E5; 3067 p[11] = 6.387953795485420E4; 3068 3069 /*Get inputs*/ 3070 Input* zgl_input = this->GetInput(GroundinglineHeightEnum); _assert_(zgl_input); 3071 Input* toc_input = this->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(toc_input); 3072 Input* soc_input = this->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(soc_input); 3073 Input* base_input = this->GetInput(BaseEnum); _assert_(base_input); 3074 Input* baseslopex_input = this->GetInput(BaseSlopeXEnum); _assert_(baseslopex_input); 3075 Input* baseslopey_input = this->GetInput(BaseSlopeYEnum); _assert_(baseslopey_input); 3076 this->FindParam(&yts, ConstantsYtsEnum); 3077 3078 /*Loop over the number of vertices in this element*/ 3079 Gauss* gauss=this->NewGauss(); 3080 for(int i=0;i<NUMVERTICES;i++){ 3081 gauss->GaussVertex(i); 3082 3083 /*Get inputs*/ 3084 zgl_input->GetInputValue(&zgl,gauss); 3085 toc_input->GetInputValue(&Toc,gauss); //(K) 3086 soc_input->GetInputValue(&Soc,gauss); 3087 base_input->GetInputValue(&z_base,gauss); 3088 baseslopex_input->GetInputValue(&slopex,gauss); 3089 baseslopey_input->GetInputValue(&slopey,gauss); 3090 3091 /*Compute ice shelf base slope*/ 3092 alpha = sqrt(slopex*slopex + slopey*slopey); 3093 3094 /*Make necessary conversions*/ 3095 Toc = Toc-273.15; 3096 alpha = atan(alpha); 3097 if(zgl>z_base) zgl=z_base-10; 3098 3099 /*Low bound for Toc to ensure X_hat is between 0 and 1*/ 3100 if(Toc<lam1*Soc+lam2) Toc=lam1*Soc+lam2; 3101 3102 /*Compute parameters needed for melt-rate calculation*/ 3103 Tf_gl = lam1*Soc+lam2+lam3*zgl; //Characteristic freezing point 3104 YTS = YT*(y1+y2*(((Toc-Tf_gl)*E0*sin(alpha))/(lam3*(CdTS0+E0*sin(alpha))))); //Effective heat exchange coefficient 3105 CdTS = sqrt(Cd)*YTS; //Heat exchange coefficient 3106 G1 = sqrt(sin(alpha)/(Cd+E0*sin(alpha))); //Geometric factor 3107 G2 = sqrt(CdTS/(CdTS+E0*sin(alpha))); //Geometric factor 3108 G3 = (E0*sin(alpha))/(CdTS+E0*sin(alpha)); //Geometric factor 3109 g_alpha = G1*G2*G3; //Melt scaling factor 3110 M = M0*g_alpha*pow((Toc-Tf_gl),2); //Melt-rate scale 3111 l = ((Toc-Tf_gl)*(x0*CdTS+E0*sin(alpha)))/(lam3*x0*(CdTS+E0*sin(alpha))); //Length scale 3112 X_hat = (z_base-zgl)/l; //Dimentionless coordinate system 3113 3114 /*Compute polynomial fit*/ 3115 M_hat = 0.; //Reset summation variable for each node 3116 for(int ii=0;ii<12;ii++) { 3117 M_hat += p[ii]*pow(X_hat,ii); //Polynomial fit 3118 } 3119 3120 /*Compute melt-rate*/ 3121 basalmeltrates_shelf[i] = (M*M_hat)/yts; //Basal melt-rate (m/s) 3122 } 3123 /*Save computed melt-rate*/ 3124 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 3125 3126 /*Cleanup and return*/ 3127 delete gauss; 3128 }/*}}}*/ 3058 3129 void Tria::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/ 3059 3130 … … 3122 3193 } 3123 3194 3124 3125 3195 } 3126 3196 /*}}}*/ … … 3193 3263 } 3194 3264 /*}}}*/ 3195 void Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/3196 3197 /*Intermediaries*/3198 IssmDouble d,xn,yn;3199 3200 /*Get current levelset and vertex coordinates*/3201 IssmDouble ls[NUMVERTICES];3202 IssmDouble xyz_list[NUMVERTICES][3];3203 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3204 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);3205 3206 /*Get distance from list of segments and reset ls*/3207 for(int j=0;j<NUMVERTICES;j++){3208 IssmDouble dmin = 1.e+50;3209 for(int i=0;i<numsegments;i++){3210 IssmDouble x = xyz_list[j][0];3211 IssmDouble y = xyz_list[j][1];3212 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);3213 3214 /*Segment has a length of 0*/3215 if(l2==0.){3216 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);3217 if(d<dmin) dmin = d;3218 continue;3219 }3220 3221 /*Consider the line extending the segment, parameterized as v + t (w - v).3222 *We find projection of point p onto the line.3223 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/3224 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;3225 if(t < 0.0){3226 // Beyond the 'v' end of the segment3227 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);3228 }3229 else if (t > 1.0){3230 // Beyond the 'w' end of the segment3231 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);3232 }3233 else{3234 // Projection falls on the segment3235 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);3236 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);3237 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);3238 }3239 3240 if(d<dmin) dmin = d;3241 }3242 3243 /*Update signed distance*/3244 dmin = sqrt(dmin);3245 if(dmin>10000) dmin=10000;3246 if(ls[j]>0){3247 ls[j] = dmin;3248 }3249 else{3250 ls[j] = - dmin;3251 }3252 }3253 3254 /*Update Levelset*/3255 this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));3256 }3257 /*}}}*/3258 3265 void Tria::SetClone(int* minranks){/*{{{*/ 3259 3266 … … 3265 3272 IssmDouble values[NUMVERTICES]; 3266 3273 int idlist[NUMVERTICES],control_init; 3267 3268 3274 3269 3275 /*Get Domain type*/ … … 3285 3291 3286 3292 /*Get out if this is not an element input*/ 3287 if(!IsInput (control_enum)) return;3288 3293 if(!IsInputEnum(control_enum)) return; 3294 3289 3295 Input* input = (Input*)this->inputs->GetInput(control_enum); _assert_(input); 3290 3296 if(input->ObjectEnum()!=ControlInputEnum){ … … 3318 3324 IssmDouble values[NUMVERTICES]; 3319 3325 int vertexpidlist[NUMVERTICES],control_init; 3320 3321 3326 3322 3327 /*Get Domain type*/ … … 3338 3343 3339 3344 /*Get out if this is not an element input*/ 3340 if(!IsInput (control_enum)) return;3345 if(!IsInputEnum(control_enum)) return; 3341 3346 3342 3347 /*hrepare index list*/ … … 3954 3959 _assert_(fieldvalue==0.); //field value != 0 not implemented yet 3955 3960 3956 /*1. check that we do cross fieldvalue in this element*/ 3957 Input* input = inputs->GetInput(fieldenum); 3958 if(!input) _error_("Cannot calculate distance to "<<EnumToStringx(fieldenum)<<", input not found"); 3959 IssmDouble minvalue = input->Min(); 3960 IssmDouble maxvalue = input->Max(); 3961 if(minvalue>fieldvalue || maxvalue<fieldvalue) return; 3962 3963 /* check #2: If only one vertex is on fieldvalue, there is no segment here */ 3961 /*Get field on vertices (we do not allow for higher order elements!!)*/ 3964 3962 IssmDouble lsf[NUMVERTICES]; 3965 3963 this->GetInputListOnVertices(&lsf[0],fieldenum); 3966 int nrice=0; 3967 for(int i=0;i<NUMVERTICES;i++) if(lsf[i]==fieldvalue) nrice++; 3968 if(nrice==1) return; 3969 3970 /*2. Write segments*/ 3971 IssmDouble* xyz_list_zero = NULL; 3964 3965 /*1. check that we do cross fieldvalue in this element*/ 3966 IssmDouble minvalue = lsf[0]; 3967 IssmDouble maxvalue = lsf[0]; 3968 for(int i=1;i<NUMVERTICES;i++){ 3969 if(lsf[i]>maxvalue) maxvalue = lsf[i]; 3970 if(lsf[i]<minvalue) minvalue = lsf[i]; 3971 } 3972 if(minvalue>fieldvalue) return; 3973 if(maxvalue<fieldvalue) return; 3974 3975 /*2. Find coordinates of where levelset crosses 0*/ 3976 int numiceverts; 3977 IssmDouble s[2],x[2],y[2]; 3978 int *indices = NULL; 3979 this->GetLevelsetIntersection(&indices, &numiceverts,&s[0],fieldenum,fieldvalue); 3980 _assert_(numiceverts); 3981 3982 /*3 Write coordinates*/ 3972 3983 IssmDouble xyz_list[NUMVERTICES][3]; 3973 3984 ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); 3974 this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0],fieldenum); 3975 if(xyz_list_zero){ 3976 IssmDouble x[2],y[2]; 3977 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0]; 3978 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1]; 3979 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false)); 3980 } 3981 xDelete<IssmDouble>(xyz_list_zero); 3982 } 3983 /*}}}*/ 3984 void Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/ 3985 3986 if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return; 3987 3988 IssmDouble* xyz_list_zero = NULL; 3989 IssmDouble xyz_list[NUMVERTICES][3]; 3990 ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); 3991 this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum); 3992 if(xyz_list_zero){ 3993 IssmDouble x[2]; 3994 IssmDouble y[2]; 3995 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0]; 3996 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1]; 3997 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false)); 3998 } 3999 xDelete<IssmDouble>(xyz_list_zero); 4000 4001 // IssmDouble ls[NUMVERTICES]; 4002 // IssmDouble xyz_list[NUMVERTICES][3]; 4003 // 4004 // if(IsIceInElement()){ 4005 // 4006 // /*Retrieve all inputs and parameters*/ 4007 // GetInputListOnVertices(&ls[0],levelset_enum); 4008 // 4009 // /*If the level set is awlays <0, there is no ice front here*/ 4010 // bool iszerols= false; 4011 // if(IsIceInElement()){ 4012 // if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){ 4013 // iszerols = true; 4014 // } 4015 // } 4016 // 4017 // if(iszerols){ 4018 // /*OK we have one segment!*/ 4019 // ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 4020 // int count = 0; 4021 // IssmDouble x[2]; 4022 // IssmDouble y[2]; 4023 // 4024 // for(int i=0;i<NUMVERTICES,i++){ 4025 // int index1 = i; 4026 // int index1 = (i+1)%3; 4027 // if(ls[index1]<=0 && ls[index2]>=0){ 4028 // 4029 // } 4030 // 4031 // } 4032 // Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false); 4033 // } 4034 // 4035 // } 4036 // 4037 // _error_("STOP"); 4038 } 4039 /*}}}*/ 4040 void Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 4041 /* Return coordinates where levelset intersects element edges. 4042 * Attention: In case that no intersection exists, NULL pointer is returned.*/ 4043 4044 /*Intermediaries*/ 4045 const int dim=3; 4046 int numiceverts; 4047 int i, n, e, counter; 4048 IssmDouble s[2]; 4049 int* indices=NULL; 4050 IssmDouble* xyz_zero=NULL; 4051 4052 this->GetLevelsetIntersection(&indices, &numiceverts, s,levelsetenum,0.); 4053 4054 //TODO: check if for 2 iceverts front segment is oriented in CCW way 4055 4056 if(numiceverts>0) xyz_zero=xNew<IssmDouble>(2*dim); 4057 if((numiceverts>0)&&(numiceverts<NUMVERTICES)){ 4058 counter=0; 4059 for(i=0;i<numiceverts;i++){ // iterate over ice vertices 4060 for(n=numiceverts;n<NUMVERTICES;n++){ // iterate over no-ice vertices 4061 for(e=0;e<dim;e++){ // spatial direction 4062 int ind_ice =dim*indices[i]+e; 4063 int ind_noice =dim*indices[n]+e; 4064 int ind =dim*counter+e; 4065 xyz_zero[ind]=xyz_list[ind_ice]+s[counter]*(xyz_list[ind_noice]-xyz_list[ind_ice]); 4066 } 3985 int counter = 0; 3986 if((numiceverts>0) && (numiceverts<NUMVERTICES)){ 3987 for(int i=0;i<numiceverts;i++){ 3988 for(int n=numiceverts;n<NUMVERTICES;n++){ // iterate over no-ice vertices 3989 x[counter] = xyz_list[indices[i]][0]+s[counter]*(xyz_list[indices[n]][0]-xyz_list[indices[i]][0]); 3990 y[counter] = xyz_list[indices[i]][1]+s[counter]*(xyz_list[indices[n]][1]-xyz_list[indices[i]][1]); 4067 3991 counter++; 4068 3992 } … … 4070 3994 } 4071 3995 else if(numiceverts==NUMVERTICES){ //NUMVERTICES ice vertices: calving front lies on element edge 4072 IssmDouble lsf[NUMVERTICES]; 4073 this->GetInputListOnVertices(&lsf[0],levelsetenum); 4074 counter=0; 4075 for(i=0;i<NUMVERTICES;i++){ 3996 3997 for(int i=0;i<NUMVERTICES;i++){ 4076 3998 if(lsf[indices[i]]==0.){ 4077 for(e=0;e<dim;e++) xyz_zero[dim*counter+e]=xyz_list[dim*indices[i]+e]; 3999 x[counter]=xyz_list[indices[i]][0]; 4000 y[counter]=xyz_list[indices[i]][1]; 4078 4001 counter++; 4079 4002 } 4080 4003 if(counter==2) break; 4081 4004 } 4082 } 4005 if(counter==1){ 4006 /*We actually have only 1 vertex on levelset, write a single point as a segment*/ 4007 x[counter]=x[0]; 4008 y[counter]=y[0]; 4009 counter++; 4010 } 4011 } 4012 else{ 4013 _error_("not sure what's going on here..."); 4014 } 4015 4016 /*4. Write segment*/ 4083 4017 _assert_(counter==2); 4084 4085 /*Cleanup & return*/ 4018 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false)); 4019 4020 /*Cleanup and return*/ 4086 4021 xDelete<int>(indices); 4087 *pxyz_zero=xyz_zero;4088 4022 } 4089 4023 /*}}}*/ … … 4231 4165 IssmDouble* H_elastic_precomputed = NULL; 4232 4166 int M, hemi; 4233 4167 4234 4168 /*computation of Green functions:*/ 4235 4169 IssmDouble* U_elastic= NULL; … … 4238 4172 IssmDouble* X_elastic= NULL; 4239 4173 IssmDouble* Y_elastic= NULL; 4240 4174 4241 4175 /*optimization:*/ 4242 4176 bool store_green_functions=false; … … 4246 4180 if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!"); 4247 4181 deltathickness_input->GetInputAverage(&I); 4248 4182 4249 4183 /*early return if we are not on the (ice) loading point: */ 4250 4184 if(I==0) return; … … 4259 4193 /*which hemisphere? for north-south, east-west components*/ 4260 4194 this->parameters->FindParam(&hemi,EsaHemisphereEnum); 4261 4195 4262 4196 /*compute area of element:*/ 4263 4197 area=GetArea(); … … 4318 4252 Y_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*Y_elastic[i]; 4319 4253 X_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*X_elastic[i]; 4320 4254 4321 4255 /*North-south, East-west components */ 4322 4256 if (hemi == -1) { … … 4341 4275 pX->SetValues(gsize,indices,X_values,ADD_VAL); 4342 4276 pY->SetValues(gsize,indices,Y_values,ADD_VAL); 4343 4277 4344 4278 /*free ressources:*/ 4345 4279 xDelete<int>(indices); … … 4371 4305 IssmDouble* H_elastic_precomputed = NULL; 4372 4306 int M; 4373 4307 4374 4308 /*computation of Green functions:*/ 4375 4309 IssmDouble* U_elastic= NULL; 4376 4310 IssmDouble* N_elastic= NULL; 4377 4311 IssmDouble* E_elastic= NULL; 4378 4312 4379 4313 /*optimization:*/ 4380 4314 bool store_green_functions=false; … … 4384 4318 if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!"); 4385 4319 deltathickness_input->GetInputAverage(&I); 4386 4320 4387 4321 /*early return if we are not on the (ice) loading point: */ 4388 4322 if(I==0) return; … … 4483 4417 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 4484 4418 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 4485 4419 4486 4420 /*Elastic component (from Eq 17 in Adhikari et al, GMD 2015): */ 4487 4421 int index=reCast<int,IssmDouble>(alpha/PI*(M-1)); … … 4498 4432 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 4499 4433 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 4500 4434 4501 4435 /*free ressources:*/ 4502 4436 xDelete<int>(indices); … … 4519 4453 4520 4454 if(IsWaterInElement()){ 4521 4455 4522 4456 IssmDouble area; 4523 4457 … … 4536 4470 /*}}}*/ 4537 4471 void Tria::SealevelriseMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,IssmDouble eartharea){/*{{{*/ 4538 4539 4472 /*early return if we are not on an ice cap OR ocean:*/ 4540 4473 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()){ … … 4593 4526 if(IsWaterInElement()){ 4594 4527 IssmDouble rho_water, S; 4595 4528 4596 4529 /*recover material parameters: */ 4597 4530 rho_water=matpar->GetMaterialParameter(MaterialsRhoFreshwaterEnum); 4598 4531 4599 4532 /*From Sg_old, recover water sea level rise:*/ 4600 4533 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg_old[this->vertices[i]->Sid()]/NUMVERTICES; 4601 4534 4602 4535 /* Perturbation terms for moment of inertia (moi_list): 4603 4536 * computed analytically (see Wu & Peltier, eqs 10 & 32) … … 4611 4544 else if(this->inputs->Max(MaskIceLevelsetEnum)<0){ 4612 4545 IssmDouble rho_ice, I; 4613 4546 4614 4547 /*recover material parameters: */ 4615 4548 rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum); 4616 4549 4617 4550 /*Compute ice thickness change: */ 4618 4551 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 4619 4552 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 4620 4553 deltathickness_input->GetInputAverage(&I); 4621 4554 4622 4555 dI_list[0] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*cos(longe))/eartharea; 4623 4556 dI_list[1] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*sin(longe))/eartharea; 4624 4557 dI_list[2] = +4*PI*(rho_ice*I*area)*pow(re,4)*(1-pow(sin(late),2))/eartharea; 4625 4558 } 4626 4559 4627 4560 return; 4628 4561 }/*}}}*/ … … 4638 4571 IssmDouble late,longe,re; 4639 4572 IssmDouble lati,longi,ri; 4573 bool notfullygrounded=false; 4640 4574 4641 4575 /*elastic green function:*/ … … 4645 4579 /*ice properties: */ 4646 4580 IssmDouble rho_ice,rho_water,rho_earth; 4581 4582 /*constants:*/ 4583 IssmDouble constant=0; 4647 4584 4648 4585 /*Initialize eustatic component: do not skip this step :):*/ … … 4653 4590 bool computeelastic= true; 4654 4591 bool scaleoceanarea= false; 4655 4592 4656 4593 /*early return if we are not on an ice cap:*/ 4657 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)){ 4594 if(!(this->inputs->Max(MaskIceLevelsetEnum)<=0)){ 4595 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4658 4596 *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage! 4659 4597 return; 4660 4598 } 4599 4600 /*early return if we are fully floating: */ 4601 if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0){ 4602 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4603 *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage! 4604 return; 4605 } 4606 4607 /*If we are here, we are on ice that is fully grounded or half-way to floating: */ 4608 if ((this->inputs->Min(MaskGroundediceLevelsetEnum))<0){ 4609 notfullygrounded=true; //used later on. 4610 } 4611 4612 /*Inform mask: */ 4613 constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4661 4614 4662 4615 /*recover material parameters: */ … … 4681 4634 4682 4635 /* Where is the centroid of this element?:{{{*/ 4683 4636 4684 4637 /*retrieve coordinates: */ 4685 4638 ::GetVerticesCoordinates(&llr_list[0][0],this->vertices,NUMVERTICES,spherical); 4686 4639 4687 4640 IssmDouble minlong=400; 4688 4641 IssmDouble maxlong=-20; … … 4698 4651 if (llr_list[2][1]==0)llr_list[2][1]=360; 4699 4652 } 4700 4653 4701 4654 // correction at the north pole 4702 4655 if(llr_list[0][0]==0)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0; 4703 4656 if(llr_list[1][0]==0)llr_list[1][1]=(llr_list[0][1]+llr_list[2][1])/2.0; 4704 4657 if(llr_list[2][0]==0)llr_list[2][1]=(llr_list[0][1]+llr_list[1][1])/2.0; 4705 4658 4706 4659 //correction at the south pole 4707 4660 if(llr_list[0][0]==180)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0; … … 4719 4672 /*}}}*/ 4720 4673 4721 /*Compute area of element :*/4674 /*Compute area of element. Scale it by grounded fraction if not fully grounded: */ 4722 4675 area=GetAreaSpherical(); 4676 if(notfullygrounded){ 4677 IssmDouble phi=0; 4678 IssmDouble xyz_list[NUMVERTICES][3]; 4679 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 4680 4681 phi=this->GetGroundedPortion(&xyz_list[0][0]); //watch out, this only works because of the Thales theorem! We are in 3D, but this routine is inherently for 2D trias 4682 area*=phi; 4683 } 4723 4684 4724 4685 /*Compute ice thickness change: */ 4725 4686 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 4726 4687 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 4727 deltathickness_input->GetInputAverage(&I); 4688 4689 /*If we are fully grounded, take the average over the element: */ 4690 if(!notfullygrounded)deltathickness_input->GetInputAverage(&I); 4691 else{ 4692 IssmDouble total_weight=0; 4693 bool mainlyfloating = true; 4694 int point1; 4695 IssmDouble fraction1,fraction2; 4696 4697 /*Recover portion of element that is grounded*/ 4698 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating); 4699 Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2); 4700 4701 /* Start looping on the number of gaussian points and average over these gaussian points: */ 4702 total_weight=0; 4703 I=0; 4704 for(int ig=gauss->begin();ig<gauss->end();ig++){ 4705 IssmDouble Ig=0; 4706 gauss->GaussPoint(ig); 4707 deltathickness_input->GetInputValue(&Ig,gauss); 4708 I+=Ig*gauss->weight; 4709 total_weight+=gauss->weight; 4710 } 4711 I=I/total_weight; 4712 delete gauss; 4713 } 4728 4714 4729 4715 /*Compute eustatic compoent:*/ … … 4762 4748 } 4763 4749 pSgi->SetValues(gsize,indices,values,ADD_VAL); 4764 4750 4765 4751 /*free ressources:*/ 4766 4752 xDelete<IssmDouble>(values); 4767 4753 xDelete<int>(indices); 4768 4754 } 4769 4755 4770 4756 /*Assign output pointer:*/ 4771 4757 _assert_(!xIsNan<IssmDouble>(eustatic)); … … 4787 4773 IssmDouble minlong=400; 4788 4774 IssmDouble maxlong=-20; 4775 IssmDouble constant=0; 4789 4776 4790 4777 /*precomputed elastic green functions:*/ 4791 4778 IssmDouble* G_elastic_precomputed = NULL; 4792 4779 int M; 4793 4780 4794 4781 /*computation of Green functions:*/ 4795 4782 IssmDouble* G_elastic= NULL; … … 4807 4794 4808 4795 /*early return if we are not on the ocean:*/ 4809 if (!IsWaterInElement())return; 4796 if (!IsWaterInElement()){ 4797 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum)); 4798 return; 4799 } 4800 constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum)); 4810 4801 4811 4802 /*recover computational flags: */ … … 4864 4855 longe=longe/180*PI; 4865 4856 /*}}}*/ 4866 4857 4867 4858 if(computeelastic){ 4868 4859 4869 4860 /*recover elastic green function:*/ 4870 4861 DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGElasticEnum)); _assert_(parameter); … … 4904 4895 } 4905 4896 } 4906 4897 4907 4898 pSgo->SetValues(gsize,indices,values,ADD_VAL); 4908 4899 … … 4918 4909 } 4919 4910 /*}}}*/ 4920 void Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){ /*{{{*/4911 void Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){ /*{{{*/ 4921 4912 4922 4913 /*diverse:*/ … … 4937 4928 IssmDouble* H_elastic_precomputed = NULL; 4938 4929 int M; 4939 4930 4940 4931 /*computation of Green functions:*/ 4941 4932 IssmDouble* U_elastic= NULL; 4942 4933 IssmDouble* N_elastic= NULL; 4943 4934 IssmDouble* E_elastic= NULL; 4935 DoubleVecParam* U_parameter = NULL; 4936 DoubleVecParam* H_parameter = NULL; 4937 IssmDouble* U_values=NULL; 4938 IssmDouble* N_values=NULL; 4939 IssmDouble* E_values=NULL; 4944 4940 4945 4941 /*optimization:*/ … … 4953 4949 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()) return; 4954 4950 4951 /*early return if we are fully floating: */ 4952 if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0)return; 4953 4955 4954 /*recover computational flags: */ 4956 4955 this->parameters->FindParam(&computerigid,SealevelriseRigidEnum); 4957 4956 this->parameters->FindParam(&computeelastic,SealevelriseElasticEnum); 4958 4957 4959 4958 /*early return if elastic not requested:*/ 4960 4959 if(!computeelastic) return; … … 5016 5015 5017 5016 /*recover elastic Green's functions for displacement:*/ 5018 DoubleVecParam* U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter); 5019 DoubleVecParam* H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter); 5017 U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter); 5020 5018 U_parameter->GetParameterValueByPointer(&U_elastic_precomputed,&M); 5021 H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M); 5019 if(horiz){ 5020 H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter); 5021 H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M); 5022 } 5022 5023 5023 5024 /*From Sg, recover water sea level rise:*/ 5024 5025 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg[this->vertices[i]->Sid()]/NUMVERTICES; 5025 5026 5026 5027 /*Compute ice thickness change: */ 5027 5028 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 5028 5029 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 5029 5030 deltathickness_input->GetInputAverage(&I); 5030 5031 5031 5032 /*initialize: */ 5032 5033 U_elastic=xNewZeroInit<IssmDouble>(gsize); 5033 N_elastic=xNewZeroInit<IssmDouble>(gsize); 5034 E_elastic=xNewZeroInit<IssmDouble>(gsize); 5034 if(horiz){ 5035 N_elastic=xNewZeroInit<IssmDouble>(gsize); 5036 E_elastic=xNewZeroInit<IssmDouble>(gsize); 5037 } 5035 5038 5036 5039 int* indices=xNew<int>(gsize); 5037 IssmDouble* U_values=xNewZeroInit<IssmDouble>(gsize); 5038 IssmDouble* N_values=xNewZeroInit<IssmDouble>(gsize); 5039 IssmDouble* E_values=xNewZeroInit<IssmDouble>(gsize); 5040 U_values=xNewZeroInit<IssmDouble>(gsize); 5041 if(horiz){ 5042 N_values=xNewZeroInit<IssmDouble>(gsize); 5043 E_values=xNewZeroInit<IssmDouble>(gsize); 5044 } 5040 5045 IssmDouble alpha; 5041 5046 IssmDouble delPhi,delLambda; … … 5062 5067 } 5063 5068 dx = x_element-x; dy = y_element-y; dz = z_element-z; 5064 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5065 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5066 5069 if(horiz){ 5070 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5071 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5072 } 5073 5067 5074 /*Elastic component (from Eq 17 in Adhikari et al, GMD 2015): */ 5068 5075 int index=reCast<int,IssmDouble>(alpha/PI*(M-1)); 5069 5076 U_elastic[i] += U_elastic_precomputed[index]; 5070 N_elastic[i] += H_elastic_precomputed[index]*N_azim; 5071 E_elastic[i] += H_elastic_precomputed[index]*E_azim; 5077 if(horiz){ 5078 N_elastic[i] += H_elastic_precomputed[index]*N_azim; 5079 E_elastic[i] += H_elastic_precomputed[index]*E_azim; 5080 } 5072 5081 5073 5082 /*Add all components to the pUp solution vectors:*/ 5074 5083 if(this->inputs->Max(MaskIceLevelsetEnum)<0){ 5075 5084 U_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*U_elastic[i]; 5076 N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i]; 5077 E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i]; 5085 if(horiz){ 5086 N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i]; 5087 E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i]; 5088 } 5078 5089 } 5079 5090 else if(IsWaterInElement()) { 5080 5091 U_values[i]+=3*rho_water/rho_earth*area/eartharea*S*U_elastic[i]; 5081 N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i]; 5082 E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i]; 5092 if(horiz){ 5093 N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i]; 5094 E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i]; 5095 } 5083 5096 } 5084 5097 } 5085 5098 pUp->SetValues(gsize,indices,U_values,ADD_VAL); 5086 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 5087 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 5099 if(horiz){ 5100 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 5101 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 5102 } 5088 5103 5089 5104 /*free ressources:*/ 5090 5105 xDelete<int>(indices); 5091 xDelete<IssmDouble>(U_values); xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values); 5092 xDelete<IssmDouble>(U_elastic); xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic); 5106 xDelete<IssmDouble>(U_values); 5107 xDelete<IssmDouble>(U_elastic); 5108 if(horiz){ 5109 xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values); 5110 xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic); 5111 } 5093 5112 5094 5113 return; … … 5106 5125 5107 5126 /*Check that name is an element input*/ 5108 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");5127 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 5109 5128 5110 5129 switch(type){ … … 5141 5160 5142 5161 /*Check that name is an element input*/ 5143 if(!IsInput (name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");5162 if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput"); 5144 5163 5145 5164 switch(type){ -
issm/trunk/src/c/classes/Elements/Tria.h
r22758 r23189 66 66 void ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index); 67 67 void ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum); 68 void CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum);68 void CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum); 69 69 int EdgeOnBaseIndex(); 70 70 void EdgeOnBaseIndices(int* pindex1,int* pindex); … … 75 75 int FiniteElement(void); 76 76 IssmDouble FloatingArea(bool scaled); 77 void FSContactMigration(Vector<IssmDouble>* vertex grounded,Vector<IssmDouble>* vertexfloating);77 void FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure); 78 78 Element* GetBasalElement(void){_error_("not implemented yet");}; 79 79 void GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* levelsetvalues); … … 86 86 int GetNumberOfNodes(int enum_type); 87 87 int GetNumberOfVertices(void); 88 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset ,bool onsid);89 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data ,bool onsid);88 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset); 89 void GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data); 90 90 void GetVerticesCoordinatesBase(IssmDouble** pxyz_list); 91 91 void GetVerticesCoordinatesTop(IssmDouble** pxyz_list); … … 114 114 void PicoUpdateBoxid(int* pmax_boxid_basin); 115 115 void PicoUpdateBox(int loopboxid); 116 void PicoComputeBasalMelt(void); 116 117 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding); 117 118 int PressureInterpolation(); … … 143 144 void VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");}; 144 145 void WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue); 145 void WriteLevelsetSegment(DataSet* segments);146 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);147 146 148 147 #ifdef _HAVE_GIAIVINS_ … … 159 158 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea); 160 159 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea); 161 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea );160 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz); 162 161 #endif 163 162 /*}}}*/ -
issm/trunk/src/c/classes/Elements/TriaRef.cpp
r21341 r23189 116 116 Matrix2x2Determinant(Jdet,&J[0][0]); 117 117 if(*Jdet<0) _error_("negative jacobian determinant!"); 118 119 } 120 /*}}}*/ 121 void TriaRef::GetJacobianDeterminant3D(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 122 /*The Jacobian determinant is constant over the element, discard the gaussian points. 123 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ 124 IssmDouble J[2][2]; 125 126 /*Get Jacobian*/ 127 GetJacobian(&J[0][0],xyz_list,gauss); 128 129 /*Get Determinant*/ 130 Matrix2x2Determinant(Jdet,&J[0][0]); 118 131 119 132 } -
issm/trunk/src/c/classes/Elements/TriaRef.h
r21341 r23189 20 20 void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss); 21 21 void GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss); 22 void GetJacobianDeterminant3D(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss); 22 23 void GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,Gauss* gauss); 23 24 void GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement); -
issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h
r22822 r23189 623 623 /*Specific instantiations for IssmDouble*: */ 624 624 #if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_) //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 625 template <> inline GenericExternalResult<IssmDouble*>::~GenericExternalResult(){ /*{{{*/ 626 xDelete<char>(result_name); 627 xDelete<IssmDouble>(value); 628 } /*}}}*/ 625 629 template <> inline void GenericExternalResult<IssmDouble*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/ 626 630 … … 743 747 } 744 748 /*}}}*/ 749 template <> inline GenericExternalResult<Vector<IssmDouble>*>::~GenericExternalResult(){ /*{{{*/ 750 xDelete<char>(this->result_name); 751 delete value; 752 } /*}}}*/ 745 753 #endif 746 754 template <> inline int GenericExternalResult<Vector<IssmPDouble>*>::ObjectEnum(void){ /*{{{*/ -
issm/trunk/src/c/classes/FemModel.cpp
r22758 r23189 83 83 /*AMR stuff*/ 84 84 this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum); 85 this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum); 85 86 #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_) 86 87 this->amr = NULL; … … 90 91 #endif 91 92 #if !defined(_HAVE_ADOLC_) 92 if(amr_frequency ){93 if(amr_frequency && solution_type==TransientSolutionEnum){ 93 94 /*Verifications. AMR supports SSA, P1 and horizontal 2D domain*/ 94 95 bool isSSA; … … 136 137 bool traceon=true; 137 138 this->profiler=NULL; /*avoid leak, as we are not using the profiler ever in ad control run. */ 138 139 /*Store the communicator, but do not set it as a global variable, as this has already 139 140 /*Store the communicator, but do not set it as a global variable, as this has already 140 141 * been done by the FemModel that called this copy constructor: */ 141 142 IssmComm::SetComm(incomm); … … 152 153 this->amrbamg = NULL; 153 154 #endif 154 155 155 156 /*Save communicator in the parameters dataset: */ 156 157 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 182 183 if(parameters)delete parameters; 183 184 if(results)delete results; 184 185 185 186 #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_) 186 187 if(amr)delete amr; … … 206 207 /*First, recover the name of the restart file: */ 207 208 parameters->FindParam(&restartfilename,RestartFileNameEnum); 208 209 209 210 /*Open file for writing: */ 210 211 restartfid=pfopen(restartfilename,"wb"); … … 215 216 /*Create buffer to hold marshalled femmodel: */ 216 217 this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE); 217 femmodel_buffer=xNew<char>(femmodel_size); 218 femmodel_buffer=xNew<char>(femmodel_size); 218 219 /*Keep track of initial position of femmodel_buffer: */ 219 220 femmodel_buffer_ini=femmodel_buffer; 220 221 221 222 /*Marshall:*/ 222 223 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD); … … 242 243 char *lockfilename = NULL; 243 244 bool waitonlock = false; 244 245 245 246 246 /*Write lock file if requested: */ … … 376 376 }/*}}}*/ 377 377 void FemModel::InitFromFids(char* rootpath, FILE* IOMODEL, FILE* toolkitsoptionsfid, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/ 378 378 379 379 /*Initialize internal data: */ 380 380 this->solution_type = in_solution_type; 381 381 this->analysis_counter = nummodels-1; //point to last analysis_type carried out. 382 382 this->results = new Results(); //not initialized by CreateDataSets 383 383 384 384 /*create IoModel */ 385 385 IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X); … … 399 399 if(VerboseMProcessor()) _printf0_(" configuring element and loads\n"); 400 400 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters); 401 401 402 402 if(i==0){ 403 403 if(VerboseMProcessor()) _printf0_(" creating vertex PIDs\n"); 404 VerticesDofx(vertices,parameters); 404 VerticesDofx(vertices,parameters); 405 405 406 406 if(VerboseMProcessor()) _printf0_(" detecting active vertices\n"); 407 GetMaskOfIceVerticesLSMx (this);407 GetMaskOfIceVerticesLSMx0(this); 408 408 } 409 409 410 410 if(VerboseMProcessor()) _printf0_(" resolving node constraints\n"); 411 SpcNodesx(nodes,constraints,parameters,analysis_type_list[i]); 411 SpcNodesx(nodes,constraints,parameters,analysis_type_list[i]); 412 412 413 413 if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n"); … … 487 487 FILE* restartfid=NULL; 488 488 char* restartfilename = NULL; 489 int femmodel_size=0; 490 int fread_return=0; 489 int femmodel_size=0; 490 int fread_return=0; 491 491 char* femmodel_buffer=NULL; 492 492 char* femmodel_buffer_ini=NULL; … … 513 513 514 514 /*Figure out size of buffer to be read: */ 515 fseek(restartfid, 0L, SEEK_END); 515 fseek(restartfid, 0L, SEEK_END); 516 516 femmodel_size = ftell(restartfid); 517 517 fseek(restartfid, 0L, SEEK_SET); 518 518 519 519 /*Allocate buffer: */ 520 femmodel_buffer=xNew<char>(femmodel_size); 520 femmodel_buffer=xNew<char>(femmodel_size); 521 521 522 522 /*Read buffer from file: */ … … 539 539 void FemModel::SetCurrentConfiguration(int configuration_type,int analysis_type){/*{{{*/ 540 540 541 /*Use configuration_type to setup the analysis counter, the configurations of objects etc ... but use 542 * analysis_type to drive the element numerics. This allows for use of 1 configuration_type for several 543 * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the 541 /*Use configuration_type to setup the analysis counter, the configurations of objects etc ... but use 542 * analysis_type to drive the element numerics. This allows for use of 1 configuration_type for several 543 * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the 544 544 * Slope configuration.*/ 545 545 int found=-1; … … 660 660 analyses_temp[numanalyses++]=MasstransportAnalysisEnum; 661 661 analyses_temp[numanalyses++]=ExtrudeFromBaseAnalysisEnum; 662 662 663 break; 663 664 … … 700 701 analyses_temp[numanalyses++]=EsaAnalysisEnum; 701 702 break; 702 703 703 704 case SealevelriseSolutionEnum: 704 705 analyses_temp[numanalyses++]=SealevelriseAnalysisEnum; … … 753 754 if(ismasstransport || isgroundingline){ 754 755 analyses_temp[numanalyses++]=MasstransportAnalysisEnum; 756 int basalforcing_model; 757 iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model"); 758 if(basalforcing_model==BasalforcingsPicoEnum){ 759 bool isplume; 760 iomodel->FindConstant(&isplume,"md.basalforcings.isplume"); 761 if(isplume){ 762 analyses_temp[numanalyses++]=GLheightadvectionAnalysisEnum; 763 } 764 } 755 765 } 756 766 if(issmb) analyses_temp[numanalyses++]=SmbAnalysisEnum; … … 761 771 if(ishydrology){ 762 772 analyses_temp[numanalyses++]=HydrologyShreveAnalysisEnum; 763 analyses_temp[numanalyses++]=HydrologySommersAnalysisEnum; 773 analyses_temp[numanalyses++]=HydrologyShaktiAnalysisEnum; 774 analyses_temp[numanalyses++]=HydrologyPismAnalysisEnum; 764 775 analyses_temp[numanalyses++]=HydrologyDCInefficientAnalysisEnum; 765 776 analyses_temp[numanalyses++]=HydrologyDCEfficientAnalysisEnum; … … 825 836 826 837 /*run solution core: */ 827 profiler->Start(CORE); 828 solutioncore(this); 838 profiler->Start(CORE); 839 solutioncore(this); 829 840 profiler->Stop(CORE); 830 841 831 842 /*run AD core if needed: */ 832 profiler->Start(ADCORE); 833 ad_core(this); 843 profiler->Start(ADCORE); 844 ad_core(this); 834 845 profiler->Stop(ADCORE); 835 846 … … 1033 1044 segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1]; 1034 1045 } 1046 1035 1047 ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1036 1048 delete segments; … … 1039 1051 1040 1052 /*3: Add distance input to all elements*/ 1041 for(int i=0;i<elements->Size();i++){ 1042 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 1043 if(!element->IsOnBase()) continue; 1044 element->CreateDistanceInputFromSegmentlist(allsegmentlist,numseg,distanceenum); 1045 } 1046 1047 1048 /*Extrude if necessary*/ 1049 int elementtype; 1050 this->parameters->FindParam(&elementtype,MeshElementtypeEnum); 1051 if(elementtype==PentaEnum){ 1052 InputExtrudex(this,distanceenum,-1); 1053 } 1054 else if(elementtype==TriaEnum){ 1055 /*no need to extrude*/ 1056 } 1057 else{ 1058 _error_("not implemented yet"); 1059 } 1053 IssmDouble* distances = xNew<IssmDouble>(vertices->Size()); 1054 IssmDouble d,xn,yn,dmin; 1055 int last = -1; 1056 for(int v=0;v<vertices->Size();v++){ 1057 1058 Vertex* vertex=dynamic_cast<Vertex*>(this->vertices->GetObjectByOffset(v)); 1059 IssmDouble x = vertex->x; 1060 IssmDouble y = vertex->y; 1061 1062 /*Most of the time the last checked segment is the closest so start with that one*/ 1063 if(last>0){ 1064 dmin = pow(allsegmentlist[4*last+0] - x,2) + pow(y-allsegmentlist[4*last+1],2); 1065 } 1066 else{ 1067 dmin = 1.e+50; 1068 } 1069 1070 for(int i=0;i<numseg;i++){ 1071 1072 /*Skip if tip is more than 10xdmin away*/ 1073 if(pow(allsegmentlist[4*i+0] - x,2)>10*dmin) continue; 1074 if(pow(allsegmentlist[4*i+1] - y,2)>10*dmin) continue; 1075 1076 IssmDouble l2 = (allsegmentlist[4*i+2]-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (allsegmentlist[4*i+3]-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]); 1077 1078 /*Segment has a length of 0*/ 1079 if(l2==0.){ 1080 d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]); 1081 if(d<dmin){ 1082 dmin = d; 1083 last = i; 1084 } 1085 continue; 1086 } 1087 1088 /*Consider the line extending the segment, parameterized as v + t (w - v). 1089 *We find projection of point p onto the line. 1090 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/ 1091 IssmDouble t = ((x-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (y-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]))/l2; 1092 if(t < 0.0){ 1093 // Beyond the 'v' end of the segment 1094 d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]); 1095 } 1096 else if (t > 1.0){ 1097 // Beyond the 'w' end of the segment 1098 d = (x-allsegmentlist[4*i+2])*(x-allsegmentlist[4*i+2])+(y-allsegmentlist[4*i+3])*(y-allsegmentlist[4*i+3]); 1099 } 1100 else{ 1101 // Projection falls on the segment 1102 xn = allsegmentlist[4*i+0] + t * (allsegmentlist[4*i+2] - allsegmentlist[4*i+0]); 1103 yn = allsegmentlist[4*i+1] + t * (allsegmentlist[4*i+3] - allsegmentlist[4*i+1]); 1104 d = (x-xn)*(x-xn)+(y-yn)*(y-yn); 1105 } 1106 1107 if(d<dmin){ 1108 dmin = d; 1109 last = i; 1110 } 1111 } 1112 1113 /*Update signed distance*/ 1114 _assert_(vertex->lid<vertices->Size()); 1115 distances[vertex->lid] = sqrt(dmin); 1116 } 1117 1118 for(int i=0;i<this->elements->Size();i++){ 1119 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1120 element->CreateDistanceInputFromSegmentlist(distances,distanceenum); 1121 } 1122 //InputUpdateFromVectorx(this,distances,distanceenum,VertexLIdEnum); 1060 1123 1061 1124 /*Clean up and return*/ 1125 xDelete<IssmDouble>(distances); 1062 1126 xDelete<IssmDouble>(allsegmentlist); 1063 1127 }/*}}}*/ … … 1121 1185 /*Broadcast and plug into response: */ 1122 1186 ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm()); 1123 ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 1187 ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 1124 1188 1125 1189 /*Assign output pointers: */ … … 1268 1332 num_segments = mdims_array[counter-1]; 1269 1333 1270 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1334 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1271 1335 * When we find one, use the element to compute the mass flux on the segment: */ 1272 1336 for(i=0;i<num_segments;i++){ … … 1315 1379 /*Figure out maximum across the cluster: */ 1316 1380 ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1317 ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1381 ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1318 1382 maxabsvx=node_maxabsvx; 1319 1383 … … 1339 1403 /*Figure out maximum across the cluster: */ 1340 1404 ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1341 ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1405 ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1342 1406 maxabsvy=node_maxabsvy; 1343 1407 … … 1363 1427 /*Figure out maximum across the cluster: */ 1364 1428 ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1365 ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1429 ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1366 1430 maxabsvz=node_maxabsvz; 1367 1431 … … 1406 1470 /*Figure out maximum across the cluster: */ 1407 1471 ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1408 ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1472 ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1409 1473 maxvel=node_maxvel; 1410 1474 … … 1430 1494 /*Figure out maximum across the cluster: */ 1431 1495 ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1432 ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1496 ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1433 1497 maxvx=node_maxvx; 1434 1498 … … 1454 1518 /*Figure out maximum across the cluster: */ 1455 1519 ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1456 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1520 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1457 1521 maxvy=node_maxvy; 1458 1522 … … 1478 1542 /*Figure out maximum across the cluster: */ 1479 1543 ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1480 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1544 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1481 1545 maxvz=node_maxvz; 1482 1546 … … 1502 1566 /*Figure out minimum across the cluster: */ 1503 1567 ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1504 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1568 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1505 1569 minvel=node_minvel; 1506 1570 … … 1526 1590 /*Figure out minimum across the cluster: */ 1527 1591 ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1528 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1592 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1529 1593 minvx=node_minvx; 1530 1594 … … 1550 1614 /*Figure out minimum across the cluster: */ 1551 1615 ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1552 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1616 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1553 1617 minvy=node_minvy; 1554 1618 … … 1574 1638 /*Figure out minimum across the cluster: */ 1575 1639 ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1576 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1640 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1577 1641 minvz=node_minvz; 1578 1642 … … 1619 1683 omega_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 1620 1684 1621 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1685 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1622 1686 //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 1623 1687 J+=weight*1/2*pow(dp[0]*dp[0]+dp[1]*dp[1],2)*Jdet*gauss->weight; … … 1678 1742 omega0_input->GetInputValue(&p0,gauss); 1679 1743 1680 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1744 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1681 1745 //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 1682 1746 J+=weight*1/2*pow(p - p0,2)*Jdet*gauss->weight; … … 1902 1966 ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1903 1967 ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1904 1968 1905 1969 if(results_on_nodes){ 1906 1970 … … 1934 1998 1935 1999 } 1936 if 2000 if(!isarray){ 1937 2001 Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size); 1938 2002 … … 1955 2019 IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols); 1956 2020 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols); 1957 2021 1958 2022 /*Fill-in matrix*/ 1959 2023 for(int j=0;j<elements->Size();j++){ … … 1964 2028 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1965 2029 xDelete<IssmDouble>(values); 1966 2030 1967 2031 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time)); 1968 2032 xDelete<IssmDouble>(allvalues); … … 2005 2069 void FemModel::ResetLevelset(void){/*{{{*/ 2006 2070 2007 /*recover my_rank:*/ 2008 int my_rank = IssmComm::GetRank(); 2009 int num_procs = IssmComm::GetSize(); 2010 2011 /*Get domain type (2d or 3d)*/ 2012 int domaintype; 2013 this->parameters->FindParam(&domaintype,DomainTypeEnum); 2014 2015 /*1: go throug all elements of this partition and figure out how many 2016 * segments we have (corresopnding to levelset = 0)*/ 2017 DataSet* segments=new DataSet(); 2018 for(int i=0;i<elements->Size();i++){ 2019 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2020 if(!element->IsOnBase()) continue; 2021 Element* basalelement = element->SpawnBasalElement(); 2022 basalelement->WriteLevelsetSegment(segments); 2023 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 2024 } 2025 2026 /*2: now get the segments from all partitions*/ 2027 int segcount=segments->Size(); 2028 int* allsegcount=xNew<int>(num_procs); 2029 ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2030 ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm()); 2031 2032 /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/ 2033 int numseg_offset=0; 2034 int numseg=0; 2035 for(int i=0;i<my_rank; i++) numseg_offset+=allsegcount[i]; 2036 for(int i=0;i<num_procs;i++) numseg+=allsegcount[i]; 2037 IssmDouble* segmentlist = xNewZeroInit<IssmDouble>(4*numseg); 2038 IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg); 2039 for(int i=0;i<segments->Size();i++){ 2040 Contour<IssmDouble>* segment=(Contour<IssmDouble>*)segments->GetObjectByOffset(i); 2041 _assert_(segment->nods == 2); 2042 segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0]; 2043 segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0]; 2044 segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1]; 2045 segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1]; 2046 } 2047 ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 2048 delete segments; 2049 xDelete<IssmDouble>(segmentlist); 2050 xDelete<int>(allsegcount); 2051 2052 /*3: update levelset for all elements*/ 2053 for(int i=0;i<elements->Size();i++){ 2054 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2055 if(!element->IsOnBase()) continue; 2056 element->ResetLevelsetFromSegmentlist(allsegmentlist,numseg); 2057 } 2058 2059 2060 /*Extrude if necessary*/ 2061 int elementtype; 2062 this->parameters->FindParam(&elementtype,MeshElementtypeEnum); 2063 if(elementtype==PentaEnum){ 2064 InputExtrudex(this,MaskIceLevelsetEnum,-1); 2065 } 2066 else if(elementtype==TriaEnum){ 2067 /*no need to extrude*/ 2068 } 2069 else{ 2070 _error_("not implemented yet"); 2071 } 2072 2073 /*Clean up and return*/ 2074 xDelete<IssmDouble>(allsegmentlist); 2071 this->DistanceToFieldValue(MaskIceLevelsetEnum,0.,MaskIceLevelsetEnum); 2075 2072 2076 2073 } … … 2132 2129 case VelEnum: this->ElementResponsex(responses,VelEnum); break; 2133 2130 case FrictionCoefficientEnum: NodalValuex(responses, FrictionCoefficientEnum,elements,nodes, vertices, loads, materials, parameters); break; 2134 default: 2131 default: 2135 2132 if(response_descriptor_enum>=Outputdefinition1Enum && response_descriptor_enum <=Outputdefinition100Enum){ 2136 2133 IssmDouble double_result = OutputDefinitionsResponsex(this,response_descriptor_enum); 2137 2134 *responses=double_result; 2138 2135 } 2139 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2140 break; 2136 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2137 break; 2141 2138 } 2142 2139 … … 2269 2266 thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 2270 2267 2271 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2268 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2272 2269 J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 2273 2270 } … … 2460 2457 analysis->UpdateConstraints(this); 2461 2458 delete analysis; 2462 2459 2463 2460 /*Second, constraints might be time dependent: */ 2464 SpcNodesx(nodes,constraints,parameters,analysis_type); 2461 SpcNodesx(nodes,constraints,parameters,analysis_type); 2465 2462 2466 2463 /*Now, update degrees of freedoms: */ … … 2473 2470 IssmDouble *surface = NULL; 2474 2471 IssmDouble *bed = NULL; 2475 2472 2476 2473 if(VerboseSolution()) _printf0_(" updating vertices positions\n"); 2477 2474 … … 2512 2509 2513 2510 /*AMR*/ 2514 #if !defined(_HAVE_ADOLC_) 2511 #if !defined(_HAVE_ADOLC_) 2515 2512 void FemModel::ReMesh(void){/*{{{*/ 2516 2513 … … 2522 2519 int newnumberofvertices = -1; 2523 2520 int newnumberofelements = -1; 2524 bool* my_elements = NULL; 2521 bool* my_elements = NULL; 2525 2522 int* my_vertices = NULL; 2526 2523 int elementswidth = this->GetElementsWidth();//just tria elements in this version … … 2528 2525 bool isgroundingline; 2529 2526 2530 /*Branch to specific amr depending on requested method*/ 2527 /*Branch to specific amr depending on requested method*/ 2531 2528 this->parameters->FindParam(&amrtype,AmrTypeEnum); 2532 2529 switch(amrtype){ … … 2541 2538 default: _error_("not implemented yet"); 2542 2539 } 2543 2540 2544 2541 /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/ 2545 2542 this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices); … … 2572 2569 2573 2570 /*As the domain is 2D, it is not necessary to create nodes for this analysis*/ 2574 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2571 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2575 2572 2576 2573 this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes); … … 2602 2599 //SetCurrentConfiguration(analysis_type); 2603 2600 2604 this->analysis_counter=i; 2601 this->analysis_counter=i; 2605 2602 /*Now, plug analysis_counter and analysis_type inside the parameters: */ 2606 2603 this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum); … … 2619 2616 2620 2617 ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters); 2621 if(i==0){ 2618 if(i==0){ 2622 2619 VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices 2623 2620 } … … 2636 2633 delete this->materials; this->materials = new_materials; 2637 2634 2638 GetMaskOfIceVerticesLSMx (this);2635 GetMaskOfIceVerticesLSMx0(this); 2639 2636 2640 2637 /*Insert MISMIP+ bed topography FIXME it could be stay in another place*/ … … 2663 2660 /*Insert bedrock from mismip+ setup*/ 2664 2661 /*This was used to Misomip project/simulations*/ 2665 2662 2666 2663 if(VerboseSolution())_printf0_(" call Mismip bedrock adjust module\n"); 2667 2664 … … 2680 2677 by = 500./(1.+exp((-2./4000.)*(y-80000./2.-24000.)))+500./(1.+exp((2./4000.)*(y-80000./2.+24000.))); 2681 2678 r[i] = max(bx+by,-720.); 2682 } 2679 } 2683 2680 /*insert new bedrock*/ 2684 2681 element->AddInput(BedEnum,&r[0],P1Enum); … … 2693 2690 2694 2691 if(VerboseSolution())_printf0_(" call adjust base and thickness module\n"); 2695 2692 2696 2693 int numvertices = this->GetElementsWidth(); 2697 2694 IssmDouble rho_water,rho_ice,density,base_float; … … 2705 2702 for(int el=0;el<this->elements->Size();el++){ 2706 2703 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el)); 2707 2704 2708 2705 element->GetInputListOnVertices(&s[0],SurfaceEnum); 2709 2706 element->GetInputListOnVertices(&r[0],BedEnum); … … 2717 2714 base_float = rho_ice*s[i]/(rho_ice-rho_water); 2718 2715 if(r[i]>base_float){ 2719 b[i] = r[i]; 2720 } 2716 b[i] = r[i]; 2717 } 2721 2718 else { 2722 b[i] = base_float; 2723 } 2719 b[i] = base_float; 2720 } 2724 2721 2725 2722 if(fabs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!"); 2726 2723 /*update thickness and mask grounded ice level set*/ 2727 2724 h[i] = s[i]-b[i]; 2728 phi[i] = h[i]+r[i]/density; 2725 phi[i] = h[i]+r[i]/density; 2729 2726 } 2730 2727 … … 2734 2731 element->AddInput(BaseEnum,&b[0],P1Enum); 2735 2732 } 2736 2733 2737 2734 /*Delete*/ 2738 2735 xDelete<IssmDouble>(phi); … … 2762 2759 Vector<IssmDouble>* input_interpolations = NULL; 2763 2760 IssmDouble* input_interpolations_serial = NULL; 2764 int* pos = NULL; 2761 int* pos = NULL; 2765 2762 IssmDouble value = 0; 2766 2763 … … 2782 2779 P0input_interp = xNew<int>(numP0inputs); 2783 2780 P1input_enums = xNew<int>(numP1inputs); 2784 P1input_interp = xNew<int>(numP1inputs); 2781 P1input_interp = xNew<int>(numP1inputs); 2785 2782 } 2786 2783 numP0inputs = 0; … … 2814 2811 } 2815 2812 } 2816 2817 /*Get P0 and P1 inputs over the elements*/ 2813 2814 /*Get P0 and P1 inputs over the elements*/ 2818 2815 pos = xNew<int>(elementswidth); 2819 2816 vP0inputs= new Vector<IssmDouble>(numberofelements*numP0inputs); … … 2821 2818 for(int i=0;i<this->elements->Size();i++){ 2822 2819 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2823 2820 2824 2821 /*Get P0 inputs*/ 2825 2822 for(int j=0;j<numP0inputs;j++){ 2826 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2823 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2827 2824 input->GetInputAverage(&value); 2828 2825 pos[0]=element->Sid()*numP0inputs+j; 2829 /*Insert input in the vector*/ 2826 /*Insert input in the vector*/ 2830 2827 vP0inputs->SetValues(1,pos,&value,INS_VAL); 2831 2828 } 2832 2829 2833 2830 /*Get P1 inputs*/ 2834 2831 for(int j=0;j<numP1inputs;j++){ … … 2837 2834 pos[1]=element->vertices[1]->Sid()*numP1inputs+j; 2838 2835 pos[2]=element->vertices[2]->Sid()*numP1inputs+j; 2839 /*Insert input in the vector*/ 2840 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2836 /*Insert input in the vector*/ 2837 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2841 2838 } 2842 2839 } … … 2847 2844 P0inputs=vP0inputs->ToMPISerial(); 2848 2845 P1inputs=vP1inputs->ToMPISerial(); 2849 2846 2850 2847 /*Assign pointers*/ 2851 *pnumP0inputs = numP0inputs; 2852 *pP0inputs = P0inputs; 2848 *pnumP0inputs = numP0inputs; 2849 *pP0inputs = P0inputs; 2853 2850 *pP0input_enums = P0input_enums; 2854 2851 *pP0input_interp = P0input_interp; 2855 *pnumP1inputs = numP1inputs; 2856 *pP1inputs = P1inputs; 2852 *pnumP1inputs = numP1inputs; 2853 *pP1inputs = P1inputs; 2857 2854 *pP1input_enums = P1input_enums; 2858 *pP1input_interp = P1input_interp; 2855 *pP1input_interp = P1input_interp; 2859 2856 2860 2857 /*Cleanup*/ … … 2867 2864 /*}}}*/ 2868 2865 void FemModel::InterpolateInputs(Vertices* newfemmodel_vertices,Elements* newfemmodel_elements){/*{{{*/ 2869 2866 2870 2867 int numberofelements = this->elements->NumberOfElements(); //global, entire old mesh 2871 2868 int newnumberofelements = newfemmodel_elements->Size(); //just on the new partition … … 2883 2880 int* P1input_enums = NULL; 2884 2881 int* P1input_interp = NULL; 2885 IssmDouble* values = NULL; 2882 IssmDouble* values = NULL; 2886 2883 IssmDouble* vector = NULL; 2887 2884 IssmDouble* x = NULL;//global, entire old mesh … … 2895 2892 IssmDouble* newyc = NULL;//just on the new partition 2896 2893 int* newelementslist = NULL;//just on the new partition 2897 int* sidtoindex = NULL;//global vertices sid to partition index 2894 int* sidtoindex = NULL;//global vertices sid to partition index 2898 2895 2899 2896 /*Get old P0 and P1 inputs (entire mesh)*/ … … 2928 2925 2929 2926 /*Insert P0 and P1 inputs into the new elements (just on the new partition)*/ 2930 values=xNew<IssmDouble>(elementswidth); 2927 values=xNew<IssmDouble>(elementswidth); 2931 2928 for(int i=0;i<newfemmodel_elements->Size();i++){//just on the new partition 2932 2929 Element* element=xDynamicCast<Element*>(newfemmodel_elements->GetObjectByOffset(i)); 2933 2930 /*newP0inputs is just on the new partition*/ 2934 2931 for(int j=0;j<numP0inputs;j++){ 2935 switch(P0input_interp[j]){ 2932 switch(P0input_interp[j]){ 2936 2933 case P0Enum: 2937 2934 case DoubleInputEnum: 2938 2935 element->AddInput(new DoubleInput(P0input_enums[j],newP0inputs[i*numP0inputs+j])); 2939 2936 break; 2940 case IntInputEnum: 2937 case IntInputEnum: 2941 2938 element->AddInput(new IntInput(P0input_enums[j],reCast<int>(newP0inputs[i*numP0inputs+j]))); 2942 2939 break; … … 2956 2953 } 2957 2954 } 2958 2955 2959 2956 /*Cleanup*/ 2960 2957 xDelete<IssmDouble>(P0inputs); … … 2995 2992 2996 2993 if(!this->elements || !this->vertices || !this->results || !this->parameters) return; 2997 2994 2998 2995 parameters->FindParam(&step,StepEnum); 2999 2996 parameters->FindParam(&time,TimeEnum); … … 3013 3010 this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum, 3014 3011 y,numberofvertices,1,step,time)); 3015 3012 3016 3013 /*Cleanup*/ 3017 3014 xDelete<IssmDouble>(x); … … 3074 3071 /*Assemble*/ 3075 3072 vmasklevelset->Assemble(); 3076 3073 3077 3074 /*Serialize and set output*/ 3078 3075 (*pmasklevelset)=vmasklevelset->ToMPISerial(); … … 3088 3085 3089 3086 /*newelementslist is in Matlab indexing*/ 3090 3087 3091 3088 /*Creating connectivity table*/ 3092 3089 int* connectivity=NULL; … … 3099 3096 connectivity[vertexid-1]+=1;//Matlab to C indexing 3100 3097 } 3101 } 3098 } 3102 3099 3103 3100 /*Create vertex and insert in vertices*/ 3104 3101 for(int i=0;i<newnumberofvertices;i++){ 3105 3102 if(my_vertices[i]){ 3106 Vertex *newvertex=new Vertex(); 3103 Vertex *newvertex=new Vertex(); 3107 3104 newvertex->id=i+1; 3108 3105 newvertex->sid=i; … … 3115 3112 newvertex->connectivity=connectivity[i]; 3116 3113 newvertex->clone=false;//itapopo check this 3117 vertices->AddObject(newvertex); 3118 } 3114 vertices->AddObject(newvertex); 3115 } 3119 3116 } 3120 3117 … … 3143 3140 } 3144 3141 else newtria->element_type_list=NULL; 3145 3142 3146 3143 /*Element hook*/ 3147 3144 int matpar_id=newnumberofelements+1; //retrieve material parameter id (last pointer in femodel->materials) … … 3149 3146 /*retrieve vertices ids*/ 3150 3147 int* vertex_ids=xNew<int>(elementswidth); 3151 for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 3148 for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 3152 3149 /*Setting the hooks*/ 3153 3150 newtria->numanalyses =this->nummodels; … … 3161 3158 /*Clean up*/ 3162 3159 xDelete<int>(vertex_ids); 3163 elements->AddObject(newtria); 3164 } 3160 elements->AddObject(newtria); 3161 } 3165 3162 } 3166 3163 … … 3172 3169 for(int i=0;i<newnumberofelements;i++){ 3173 3170 if(my_elements[i]){ 3174 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3175 } 3176 } 3177 3171 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3172 } 3173 } 3174 3178 3175 /*Add new constant material property to materials, at the end: */ 3179 3176 Matpar *newmatpar=static_cast<Matpar*>(this->materials->GetObjectByOffset(this->materials->Size()-1)->copy()); 3180 3177 newmatpar->SetMid(newnumberofelements+1); 3181 materials->AddObject(newmatpar);//put it at the end of the materials 3178 materials->AddObject(newmatpar);//put it at the end of the materials 3182 3179 } 3183 3180 /*}}}*/ … … 3186 3183 int lid=0; 3187 3184 for(int j=0;j<newnumberofvertices;j++){ 3188 if(my_vertices[j]){ 3189 3190 Node* newnode=new Node(); 3191 3185 if(my_vertices[j]){ 3186 3187 Node* newnode=new Node(); 3188 3192 3189 /*id: */ 3193 3190 newnode->id=nodecounter+j+1; … … 3195 3192 newnode->lid=lid++; 3196 3193 newnode->analysis_enum=analysis_enum; 3197 3194 3198 3195 /*Initialize coord_system: Identity matrix by default*/ 3199 3196 for(int k=0;k<3;k++) for(int l=0;l<3;l++) newnode->coord_system[k][l]=0.0; 3200 3197 for(int k=0;k<3;k++) newnode->coord_system[k][k]=1.0; 3201 3198 3202 3199 /*indexing:*/ 3203 3200 newnode->indexingupdate=true; 3204 3201 3205 3202 Analysis* analysis=EnumToAnalysis(analysis_enum); 3206 3203 int *doftypes=NULL; … … 3216 3213 /*Stressbalance Horiz*/ 3217 3214 if(analysis_enum==StressbalanceAnalysisEnum){ 3218 // itapopo this code is rarely used. 3215 // itapopo this code is rarely used. 3219 3216 /*Coordinate system provided, convert to coord_system matrix*/ 3220 3217 //XZvectorsToCoordinateSystem(&this->coord_system[0][0],&iomodel->Data(StressbalanceReferentialEnum)[j*6]); … … 3231 3228 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3232 3229 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3233 3230 3234 3231 int numberofvertices = femmodel_vertices->NumberOfVertices(); 3235 3232 int numberofelements = femmodel_elements->NumberOfElements(); … … 3237 3234 IssmDouble* x = NULL; 3238 3235 IssmDouble* y = NULL; 3239 IssmDouble* z = NULL; 3236 IssmDouble* z = NULL; 3240 3237 int* elementslist = NULL; 3241 3238 int* elem_vertices = NULL; … … 3246 3243 /*Get vertices coordinates*/ 3247 3244 VertexCoordinatesx(&x,&y,&z,femmodel_vertices,false) ; 3248 3245 3249 3246 /*Get element vertices*/ 3250 3247 elem_vertices = xNew<int>(elementswidth); … … 3261 3258 vid3->SetValue(element->sid,elem_vertices[2],INS_VAL); 3262 3259 } 3263 3260 3264 3261 /*Assemble*/ 3265 3262 vid1->Assemble(); … … 3271 3268 id2 = vid2->ToMPISerial(); 3272 3269 id3 = vid3->ToMPISerial(); 3273 3270 3274 3271 /*Construct elements list*/ 3275 3272 elementslist=xNew<int>(numberofelements*elementswidth); … … 3280 3277 elementslist[elementswidth*i+2] = reCast<int>(id3[i])+1; //InterpMesh wants Matlab indexing 3281 3278 } 3282 3279 3283 3280 /*Assign pointers*/ 3284 3281 *px = x; … … 3301 3298 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3302 3299 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3303 3300 3304 3301 int numberofvertices = femmodel_vertices->Size(); //number of vertices of this partition 3305 3302 int numbertotalofvertices = femmodel_vertices->NumberOfVertices(); //number total of vertices (entire mesh) … … 3308 3305 IssmDouble* x = NULL; 3309 3306 IssmDouble* y = NULL; 3310 IssmDouble* z = NULL; 3307 IssmDouble* z = NULL; 3311 3308 int* elementslist = NULL; 3312 3309 int* sidtoindex = NULL; 3313 3310 int* elem_vertices = NULL; 3314 3311 3315 3312 /*Get vertices coordinates of this partition*/ 3316 3313 sidtoindex = xNewZeroInit<int>(numbertotalofvertices);//entire mesh, all vertices … … 3318 3315 y = xNew<IssmDouble>(numberofvertices);//just this partitio; 3319 3316 z = xNew<IssmDouble>(numberofvertices);//just this partitio; 3320 3317 3321 3318 /*Go through in this partition (vertices)*/ 3322 3319 for(int i=0;i<numberofvertices;i++){//just this partition 3323 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3320 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3324 3321 /*Attention: no spherical coordinates*/ 3325 3322 x[i]=vertex->GetX(); … … 3334 3331 elementslist = xNew<int>(numberofelements*elementswidth); 3335 3332 if(numberofelements*elementswidth<0) _error_("numberofelements negative."); 3336 3333 3337 3334 for(int i=0;i<numberofelements;i++){//just this partition 3338 3335 Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i)); … … 3341 3338 elementslist[elementswidth*i+1] = sidtoindex[elem_vertices[1]]+1; //InterpMesh wants Matlab indexing 3342 3339 elementslist[elementswidth*i+2] = sidtoindex[elem_vertices[2]]+1; //InterpMesh wants Matlab indexing 3343 } 3344 3340 } 3341 3345 3342 /*Assign pointers*/ 3346 3343 *px = x; … … 3348 3345 *pz = z; 3349 3346 *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type. 3350 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3347 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3351 3348 3352 3349 /*Cleanup*/ … … 3359 3356 /*OTHERS CONSTRAINTS MUST BE IMPLEMENTED*/ 3360 3357 if(analysis_enum!=StressbalanceAnalysisEnum) return; 3361 3358 3362 3359 int numberofnodes_analysistype= this->nodes->NumberOfNodes(analysis_enum); 3363 int dofpernode = 2; //vx and vy 3360 int dofpernode = 2; //vx and vy 3364 3361 int numberofcols = dofpernode*2; //to keep dofs and flags in the vspc vector 3365 3362 int numberofvertices = this->vertices->NumberOfVertices(); //global, entire old mesh … … 3385 3382 newy=xNew<IssmDouble>(newnumberofvertices);//just the new partition 3386 3383 for(int i=0;i<newnumberofvertices;i++){//just the new partition 3387 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3384 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3388 3385 /*Attention: no spherical coordinates*/ 3389 3386 newx[i]=vertex->GetX(); … … 3393 3390 /*Get spcvx and spcvy of old mesh*/ 3394 3391 for(int i=0;i<this->constraints->Size();i++){ 3395 3392 3396 3393 Constraint* constraint=(Constraint*)constraints->GetObjectByOffset(i); 3397 3394 if(!constraint->InAnalysis(analysis_enum)) _error_("AMR create constraints for "<<EnumToStringx(analysis_enum)<<" not supported yet!\n"); … … 3400 3397 int dof = spcstatic->GetDof(); 3401 3398 int node = spcstatic->GetNodeId(); 3402 IssmDouble spcvalue = spcstatic->GetValue(); 3399 IssmDouble spcvalue = spcstatic->GetValue(); 3403 3400 int nodeindex = node-1; 3404 3401 3405 3402 /*vx and vx flag insertion*/ 3406 3403 if(dof==0) {//vx 3407 3404 vspc->SetValue(nodeindex*numberofcols,spcvalue,INS_VAL); //vx 3408 3405 vspc->SetValue(nodeindex*numberofcols+dofpernode,1,INS_VAL);//vxflag 3409 } 3406 } 3410 3407 /*vy and vy flag insertion*/ 3411 3408 if(dof==1){//vy … … 3423 3420 spc,numberofvertices,numberofcols, 3424 3421 newx,newy,newnumberofvertices,NULL); 3425 3422 3426 3423 /*Now, insert the interpolated constraints in the data set (constraints)*/ 3427 3424 count=0; … … 3440 3437 /*spcvy*/ 3441 3438 if(!xIsNan<IssmDouble>(newspc[i*numberofcols+1]) && newspc[i*numberofcols+dofpernode+1]>(1-eps) ){ 3442 newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 3439 newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 3443 3440 //add count'th spc, on node i+1, setting dof 1 to vx. 3444 3441 count++; … … 3497 3494 bool *my_elements = NULL; 3498 3495 int *my_vertices = NULL; 3499 3500 _assert_(newnumberofvertices>0); 3501 _assert_(newnumberofelements>0); 3496 3497 _assert_(newnumberofvertices>0); 3498 _assert_(newnumberofelements>0); 3502 3499 epart=xNew<int>(newnumberofelements); 3503 3500 npart=xNew<int>(newnumberofvertices); 3504 3501 index=xNew<int>(elementswidth*newnumberofelements); 3505 3502 3506 3503 for (int i=0;i<newnumberofelements;i++){ 3507 3504 for (int j=0;j<elementswidth;j++){ … … 3523 3520 for (int i=0;i<newnumberofvertices;i++) npart[i]=0; 3524 3521 } 3525 else _error_("At least one processor is required"); 3522 else _error_("At least one processor is required"); 3526 3523 3527 3524 my_vertices=xNew<int>(newnumberofvertices); … … 3533 3530 for(int i=0;i<newnumberofelements;i++){ 3534 3531 /*!All elements have been partitioned above, only deal with elements for this cpu: */ 3535 if(my_rank==epart[i]){ 3532 if(my_rank==epart[i]){ 3536 3533 my_elements[i]=true; 3537 /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 3538 *the element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 3539 into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 3534 /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 3535 *the element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 3536 into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 3540 3537 will hold which vertices belong to this partition*/ 3541 3538 for(int j=0;j<elementswidth;j++){ 3542 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3539 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3543 3540 my_vertices[newelementslist[elementswidth*i+j]-1]=1;//newelementslist is in Matlab indexing 3544 3541 } … … 3552 3549 /*Free ressources:*/ 3553 3550 xDelete<int>(epart); 3554 xDelete<int>(npart); 3551 xDelete<int>(npart); 3555 3552 xDelete<int>(index); 3556 3553 } 3557 3554 /*}}}*/ 3558 3555 void FemModel::SmoothedDeviatoricStressTensor(IssmDouble** ptauxx,IssmDouble** ptauyy,IssmDouble** ptauxy){/*{{{*/ 3559 3556 3560 3557 int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements 3561 3558 int numberofvertices = this->vertices->NumberOfVertices(); 3562 3559 IssmDouble weight = 0.; 3563 IssmDouble* tauxx = NULL; 3564 IssmDouble* tauyy = NULL; 3565 IssmDouble* tauxy = NULL; 3560 IssmDouble* tauxx = NULL; 3561 IssmDouble* tauyy = NULL; 3562 IssmDouble* tauxy = NULL; 3566 3563 IssmDouble* totalweight = NULL; 3567 3564 IssmDouble* deviatoricstressxx = xNew<IssmDouble>(elementswidth); … … 3573 3570 Vector<IssmDouble>* vectauxy = new Vector<IssmDouble>(numberofvertices); 3574 3571 Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices); 3575 3572 3576 3573 /*Update the Deviatoric Stress tensor over the elements*/ 3577 3574 this->DeviatoricStressx(); 3578 3575 3579 3576 /*Calculate the Smoothed Deviatoric Stress tensor*/ 3580 3577 for(int i=0;i<this->elements->Size();i++){ … … 3621 3618 /*Divide for the total weight*/ 3622 3619 for(int i=0;i<numberofvertices;i++){ 3623 _assert_(totalweight[i]>0); 3620 _assert_(totalweight[i]>0); 3624 3621 tauxx[i] = tauxx[i]/totalweight[i]; 3625 3622 tauyy[i] = tauyy[i]/totalweight[i]; … … 3646 3643 void FemModel::ZZErrorEstimator(IssmDouble** pelementerror){/*{{{*/ 3647 3644 3648 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3645 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3649 3646 * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/ 3650 3647 … … 3666 3663 /*Get smoothed deviatoric stress tensor*/ 3667 3664 this->SmoothedDeviatoricStressTensor(&smoothedtauxx,&smoothedtauyy,&smoothedtauxy); 3668 3665 3669 3666 /*Integrate the error over elements*/ 3670 3667 for(int i=0;i<this->elements->Size();i++){ … … 3674 3671 element->GetInputListOnVertices(tauxy,DeviatoricStressxyEnum); 3675 3672 element->GetVerticesSidList(elem_vertices); 3676 3673 3677 3674 /*Integrate*/ 3678 3675 element->GetVerticesCoordinates(&xyz_list); … … 3689 3686 ftxy+=(tauxy[n]-smoothedtauxy[elem_vertices[n]])*basis[n]; 3690 3687 } 3691 error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2 3692 } 3693 /*Set the error in the global vector*/ 3688 error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2 3689 } 3690 /*Set the error in the global vector*/ 3694 3691 sid=element->Sid(); 3695 3692 error = sqrt(error);//sqrt(e^2) … … 3705 3702 /*Serialize and set output*/ 3706 3703 (*pelementerror)=velementerror->ToMPISerial(); 3707 3704 3708 3705 /*Cleanup*/ 3709 3706 xDelete<IssmDouble>(smoothedtauxx); … … 3749 3746 Tria* triaelement = xDynamicCast<Tria*>(element); 3750 3747 weight = triaelement->GetArea();//the tria area is a choice for the weight 3751 3748 3752 3749 /*dH/dx*/ 3753 3750 vecdHdx->SetValue(elem_vertices[0],weight*GradH[0],ADD_VAL); … … 3817 3814 /*Get smoothed deviatoric stress tensor*/ 3818 3815 this->SmoothedGradThickness(&smoothed_dHdx,&smoothed_dHdy); 3819 3816 3820 3817 /*Integrate the error over elements*/ 3821 3818 for(int i=0;i<this->elements->Size();i++){ … … 3903 3900 IssmDouble* x = NULL; 3904 3901 IssmDouble* y = NULL; 3905 IssmDouble* z = NULL; 3902 IssmDouble* z = NULL; 3906 3903 IssmDouble* xyz_list = NULL; 3907 3904 IssmDouble x1,y1,x2,y2,x3,y3; … … 3912 3909 //element->GetVerticesSidList(elem_vertices); 3913 3910 int sid = element->Sid(); 3914 element->GetVerticesCoordinates(&xyz_list); 3911 element->GetVerticesCoordinates(&xyz_list); 3915 3912 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3916 3913 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 3945 3942 _error_("level set type not implemented yet!"); 3946 3943 } 3947 3944 3948 3945 /*Outputs*/ 3949 3946 IssmDouble* zerolevelset_points = NULL; 3950 3947 int npoints = 0; 3951 3948 3952 3949 /*Intermediaries*/ 3953 3950 int elementswidth = this->GetElementsWidth(); … … 3962 3959 int count,sid; 3963 3960 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 3964 3961 3965 3962 /*Use the element center coordinate if level set is zero (grounding line or ice front), otherwise set NAN*/ 3966 3963 for(int i=0;i<this->elements->Size();i++){ … … 3969 3966 element->GetVerticesSidList(elem_vertices); 3970 3967 sid= element->Sid(); 3971 element->GetVerticesCoordinates(&xyz_list); 3968 element->GetVerticesCoordinates(&xyz_list); 3972 3969 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3973 3970 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; 3974 3971 x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1]; 3975 3972 xc = NAN; 3976 yc = NAN; 3973 yc = NAN; 3977 3974 Tria* tria = xDynamicCast<Tria*>(element); 3978 3975 if(tria->IsIceInElement()){/*verify if there is ice in the element*/ 3979 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3976 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3980 3977 abs(levelset[0]*levelset[1])<DBL_EPSILON || abs(levelset[0]*levelset[2])<DBL_EPSILON) { 3981 3978 xc=(x1+x2+x3)/3.; … … 4007 4004 } 4008 4005 } 4009 4006 4010 4007 /*Assign outputs*/ 4011 4008 numberofpoints = npoints; … … 4047 4044 responses_pointer=d_responses; 4048 4045 4049 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4046 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4050 4047 //because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */ 4051 4048 … … 4140 4137 4141 4138 int ns,nsmax; 4142 4139 4143 4140 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4144 4141 ns = elements->Size(); 4145 4142 4146 4143 /*Figure out max of ns: */ 4147 4144 ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); … … 4162 4159 } 4163 4160 } 4164 4161 4165 4162 /*One last time: */ 4166 4163 pUp->Assemble(); … … 4181 4178 4182 4179 int ns,nsmax; 4183 4180 4184 4181 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4185 4182 ns = elements->Size(); 4186 4187 /*First, figure out the surface area of Earth: */ 4183 4184 /*First, figure out the surface area of Earth: */ 4188 4185 for(int i=0;i<ns;i++){ 4189 4186 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4209 4206 } 4210 4207 } 4211 4208 4212 4209 /*One last time: */ 4213 4210 pUp->Assemble(); … … 4226 4223 #endif 4227 4224 #ifdef _HAVE_SEALEVELRISE_ 4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* p Sgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/4225 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pRSLgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop) { /*{{{*/ 4229 4226 4230 4227 /*serialized vectors:*/ … … 4237 4234 IssmDouble eartharea_cpu = 0.; 4238 4235 int ns,nsmax; 4239 4236 4240 4237 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4241 4238 ns = elements->Size(); … … 4261 4258 for(int i=0;i<nsmax;i++){ 4262 4259 if(i<ns){ 4263 4264 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% ");4265 4260 4261 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4262 4266 4263 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4267 element->SealevelriseEustatic(p Sgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);4264 element->SealevelriseEustatic(pRSLgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea); 4268 4265 eustatic_cpu+=eustatic_cpu_e; 4269 4266 } 4270 if(i% 100==0)pSgi->Assemble();4267 if(i%loop==0)pRSLgi->Assemble(); 4271 4268 } 4272 4269 if(VerboseConvergence())_printf0_("\n"); 4273 4270 4274 4271 /*One last time: */ 4275 p Sgi->Assemble();4272 pRSLgi->Assemble(); 4276 4273 4277 4274 /*Sum all eustatic components from all cpus:*/ … … 4285 4282 } 4286 4283 /*}}}*/ 4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* p Sgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/4284 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution,int loop){/*{{{*/ 4288 4285 4289 4286 /*serialized vectors:*/ 4290 IssmDouble* Sg_old=NULL;4291 4287 IssmDouble* RSLg_old=NULL; 4288 4292 4289 IssmDouble eartharea=0; 4293 4290 IssmDouble eartharea_cpu=0; 4294 4291 4295 4292 int ns,nsmax; 4296 4293 4297 4294 /*Serialize vectors from previous iteration:*/ 4298 Sg_old=pSg_old->ToMPISerial();4295 RSLg_old=pRSLg_old->ToMPISerial(); 4299 4296 4300 4297 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ … … 4306 4303 eartharea_cpu += element->GetAreaSpherical(); 4307 4304 } 4308 4305 4309 4306 ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4310 4307 ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); … … 4317 4314 for(int i=0;i<nsmax;i++){ 4318 4315 if(i<ns){ 4319 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf _("\r" << "convolution progress: " << (double)i/(double)ns*100 << "% ");4316 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4320 4317 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4321 element->SealevelriseNonEustatic(p Sgo,Sg_old,latitude,longitude,radius,eartharea);4322 } 4323 if(i% 100==0)pSgo->Assemble();4324 } 4325 if(verboseconvolution)if(VerboseConvergence())_printf _("\n");4326 4318 element->SealevelriseNonEustatic(pRSLgo,RSLg_old,latitude,longitude,radius,eartharea); 4319 } 4320 if(i%loop==0)pRSLgo->Assemble(); 4321 } 4322 if(verboseconvolution)if(VerboseConvergence())_printf0_("\n"); 4323 4327 4324 /*Free ressources:*/ 4328 xDelete<IssmDouble>( Sg_old);4329 } 4330 /*}}}*/ 4331 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* p Sgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/4325 xDelete<IssmDouble>(RSLg_old); 4326 } 4327 /*}}}*/ 4328 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/ 4332 4329 4333 4330 /*serialized vectors:*/ 4334 IssmDouble* Sg_old=NULL;4331 IssmDouble* RSLg_old=NULL; 4335 4332 IssmDouble eartharea=0; 4336 4333 IssmDouble eartharea_cpu=0; 4337 4334 IssmDouble tide_love_h, tide_love_k, fluid_love, moi_e, moi_p, omega, g; 4338 IssmDouble load_love_k2 = -0.30922675; //degree 2 load Love number 4339 IssmDouble m1, m2, m3; 4340 IssmDouble lati, longi, radi, value; 4335 IssmDouble load_love_k2 = -0.30922675; //degree 2 load Love number 4336 IssmDouble m1, m2, m3; 4337 IssmDouble lati, longi, radi, value; 4341 4338 4342 4339 /*Serialize vectors from previous iteration:*/ 4343 Sg_old=pSg_old->ToMPISerial();4340 RSLg_old=pRSLg_old->ToMPISerial(); 4344 4341 4345 4342 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ … … 4351 4348 ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4352 4349 4353 IssmDouble moi_list[3]={0,0,0}; 4354 IssmDouble moi_list_cpu[3]={0,0,0}; 4350 IssmDouble moi_list[3]={0,0,0}; 4351 IssmDouble moi_list_cpu[3]={0,0,0}; 4355 4352 for(int i=0;i<elements->Size();i++){ 4356 4353 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4357 element->SealevelriseMomentOfInertia(&moi_list[0], Sg_old,eartharea);4358 moi_list_cpu[0] += moi_list[0]; 4359 moi_list_cpu[1] += moi_list[1]; 4360 moi_list_cpu[2] += moi_list[2]; 4354 element->SealevelriseMomentOfInertia(&moi_list[0],RSLg_old,eartharea); 4355 moi_list_cpu[0] += moi_list[0]; 4356 moi_list_cpu[1] += moi_list[1]; 4357 moi_list_cpu[2] += moi_list[2]; 4361 4358 } 4362 4359 ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4363 4360 ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4364 // 4361 // 4365 4362 ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4366 4363 ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4367 // 4364 // 4368 4365 ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4369 4366 ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4370 4367 4371 4368 /*pull out some useful parameters: */ 4372 4369 parameters->FindParam(&tide_love_h,SealevelriseTidalLoveHEnum); … … 4378 4375 4379 4376 /*compute perturbation terms for angular velocity vector: */ 4380 m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0]; 4381 m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1]; 4382 m3 = -(1+load_love_k2)/moi_p * moi_list[2]; // term associated with fluid number (3-order-of-magnitude smaller) is negelected 4377 m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0]; 4378 m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1]; 4379 m3 = -(1+load_love_k2)/moi_p * moi_list[2]; // term associated with fluid number (3-order-of-magnitude smaller) is negelected 4383 4380 4384 4381 /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11) 4385 * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3) 4386 * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered) 4387 * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180] 4382 * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3) 4383 * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered) 4384 * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180] 4388 4385 */ 4389 4386 for(int i=0;i<vertices->Size();i++){ … … 4395 4392 lati=latitude[sid]/180*PI; longi=longitude[sid]/180*PI; radi=radius[sid]; 4396 4393 4397 /*only first order terms are considered now: */ 4394 /*only first order terms are considered now: */ 4398 4395 value=((1.0+tide_love_k-tide_love_h)/9.81)*pow(omega*radi,2.0)* 4399 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 4400 4401 p Sgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times4396 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 4397 4398 pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times 4402 4399 } 4403 4400 4404 4401 /*Assemble mesh velocity*/ 4405 p Sgo_rot->Assemble();4406 4402 pRSLgo_rot->Assemble(); 4403 4407 4404 /*Assign output pointers:*/ 4408 *pIxz=moi_list[0];4409 *pIyz=moi_list[1];4410 *pIzz=moi_list[2];4405 if(pIxz)*pIxz=moi_list[0]; 4406 if(pIyz)*pIyz=moi_list[1]; 4407 if(pIzz)*pIzz=moi_list[2]; 4411 4408 4412 4409 /*Free ressources:*/ 4413 xDelete<IssmDouble>( Sg_old);4414 4415 } 4416 /*}}}*/ 4417 void FemModel::Sealevelrise Geodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/4410 xDelete<IssmDouble>(RSLg_old); 4411 4412 } 4413 /*}}}*/ 4414 void FemModel::SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pRSLg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz){/*{{{*/ 4418 4415 4419 4416 /*serialized vectors:*/ 4420 IssmDouble* Sg=NULL;4421 4417 IssmDouble* RSLg=NULL; 4418 4422 4419 IssmDouble eartharea=0; 4423 4420 IssmDouble eartharea_cpu=0; 4424 4421 4425 4422 int ns,nsmax; 4426 4423 4427 4424 /*Serialize vectors from previous iteration:*/ 4428 Sg=pSg->ToMPISerial();4425 RSLg=pRSLg->ToMPISerial(); 4429 4426 4430 4427 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4431 4428 ns = elements->Size(); 4432 4429 4433 4430 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ 4434 4431 for(int i=0;i<ns;i++){ … … 4446 4443 for(int i=0;i<nsmax;i++){ 4447 4444 if(i<ns){ 4445 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4448 4446 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4449 element->SealevelriseGeodetic(pUp,pNorth,pEast, Sg,latitude,longitude,radius,xx,yy,zz,eartharea);4450 } 4451 if(i% 100==0){4447 element->SealevelriseGeodetic(pUp,pNorth,pEast,RSLg,latitude,longitude,radius,xx,yy,zz,eartharea,horiz); 4448 } 4449 if(i%loop==0){ 4452 4450 pUp->Assemble(); 4453 pNorth->Assemble(); 4454 pEast->Assemble(); 4455 } 4456 } 4457 4451 if (horiz){ 4452 pNorth->Assemble(); 4453 pEast->Assemble(); 4454 } 4455 } 4456 } 4457 4458 4458 /*One last time: */ 4459 4459 pUp->Assemble(); 4460 pNorth->Assemble(); 4461 pEast->Assemble(); 4460 if(horiz){ 4461 pNorth->Assemble(); 4462 pEast->Assemble(); 4463 } 4464 if(VerboseConvergence())_printf0_("\n"); 4462 4465 4463 4466 /*Free ressources:*/ 4464 xDelete<IssmDouble>(Sg); 4465 xDelete<IssmDouble>(latitude); 4466 xDelete<IssmDouble>(longitude); 4467 xDelete<IssmDouble>(radius); 4468 xDelete<IssmDouble>(xx); 4469 xDelete<IssmDouble>(yy); 4470 xDelete<IssmDouble>(zz); 4471 } 4472 /*}}}*/ 4473 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* Sg) { /*{{{*/ 4474 4475 IssmDouble* Sg_serial=NULL; 4467 xDelete<IssmDouble>(RSLg); 4468 } 4469 /*}}}*/ 4470 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* RSLg) { /*{{{*/ 4471 4472 IssmDouble* RSLg_serial=NULL; 4476 4473 IssmDouble oceanvalue,oceanvalue_cpu; 4477 4474 IssmDouble oceanarea,oceanarea_cpu; 4478 4475 4479 4476 /*Serialize vectors from previous iteration:*/ 4480 Sg_serial=Sg->ToMPISerial();4477 RSLg_serial=RSLg->ToMPISerial(); 4481 4478 4482 4479 /*Initialize:*/ … … 4488 4485 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4489 4486 oceanarea_cpu += element->OceanArea(); 4490 oceanvalue_cpu += element->OceanAverage( Sg_serial);4487 oceanvalue_cpu += element->OceanAverage(RSLg_serial); 4491 4488 } 4492 4489 ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4493 4490 ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4494 4491 4495 4492 ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4496 4493 ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4497 4494 4498 4495 /*Free ressources:*/ 4499 xDelete<IssmDouble>( Sg_serial);4500 4496 xDelete<IssmDouble>(RSLg_serial); 4497 4501 4498 return oceanvalue/oceanarea; 4502 4499 } … … 4514 4511 int* eplzigzag_counter = NULL; 4515 4512 int eplflip_lock; 4516 4513 4517 4514 HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis(); 4518 4515 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); … … 4521 4518 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4522 4519 recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4523 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4524 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4520 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4521 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4525 4522 GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum); 4526 4523 4527 4524 for (int i=0;i<elements->Size();i++){ 4528 4525 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4542 4539 /*Assemble and serialize*/ 4543 4540 mask->Assemble(); 4544 serial_mask=mask->ToMPISerial(); 4545 4541 serial_mask=mask->ToMPISerial(); 4542 4546 4543 xDelete<int>(eplzigzag_counter); 4547 4544 xDelete<IssmDouble>(serial_rec); … … 4585 4582 int sum_counter; 4586 4583 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4587 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4584 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4588 4585 counter=sum_counter; 4589 4586 *pEplcount = counter; 4590 4587 if(VerboseSolution()) _printf0_(" Number of active nodes in EPL layer: "<< counter <<"\n"); 4588 4589 /*Update dof indexings*/ 4590 this->UpdateConstraintsx(); 4591 4592 } 4593 /*}}}*/ 4594 void FemModel::HydrologyIDSupdateDomainx(IssmDouble* pIDScount){ /*{{{*/ 4595 4596 bool isthermal; 4597 Vector<IssmDouble>* mask = NULL; 4598 Vector<IssmDouble>* active = NULL; 4599 IssmDouble* serial_mask = NULL; 4600 IssmDouble* serial_active = NULL; 4601 4602 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); 4603 parameters->FindParam(&isthermal,TransientIsthermalEnum); 4604 4605 /*When solving a thermal model we update the thawed nodes*/ 4606 if(isthermal){ 4607 /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/ 4608 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum)); 4609 4610 for (int i=0;i<elements->Size();i++){ 4611 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4612 inefanalysis->HydrologyIDSGetMask(mask,element); 4613 } 4614 /*Assemble and serialize*/ 4615 mask->Assemble(); 4616 serial_mask=mask->ToMPISerial(); 4617 delete mask; 4618 } 4619 /*for other cases we just grab the mask from the initialisation value*/ 4620 else{ 4621 GetVectorFromInputsx(&serial_mask,this,HydrologydcMaskThawedNodeEnum,NodeSIdEnum); 4622 } 4623 /*Update Mask and elementize*/ 4624 InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskThawedNodeEnum,NodeSIdEnum); 4625 xDelete<IssmDouble>(serial_mask); 4626 inefanalysis->ElementizeIdsMask(this); 4627 4628 /*get node mask coherent with element mask*/ 4629 active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum)); 4630 for (int i=0;i<elements->Size();i++){ 4631 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4632 inefanalysis->HydrologyIdsGetActive(active,element); 4633 } 4634 4635 /*Assemble and serialize*/ 4636 active->Assemble(); 4637 serial_active=active->ToMPISerial(); 4638 delete active; 4639 4640 /*Update node activation accordingly*/ 4641 int counter =0; 4642 for (int i=0;i<nodes->Size();i++){ 4643 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i)); 4644 if(node->InAnalysis(HydrologyDCInefficientAnalysisEnum)){ 4645 if(serial_active[node->Sid()]==1.){ 4646 node->Activate(); 4647 if(!node->IsClone()) counter++; 4648 } 4649 else{ 4650 node->Deactivate(); 4651 } 4652 } 4653 } 4654 4655 xDelete<IssmDouble>(serial_active); 4656 delete inefanalysis; 4657 int sum_counter; 4658 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4659 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4660 counter=sum_counter; 4661 *pIDScount = counter; 4662 if(VerboseSolution()) _printf0_(" Number of active nodes in IDS layer: "<< counter <<"\n"); 4591 4663 4592 4664 /*Update dof indexings*/ … … 4631 4703 int sum_counter; 4632 4704 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4633 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4705 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4634 4706 counter=sum_counter; 4635 4707 *pL2count = counter; … … 4716 4788 } 4717 4789 /*}}}*/ 4718 #ifdef _HAVE_JAVASCRIPT_ 4790 #ifdef _HAVE_JAVASCRIPT_ 4719 4791 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/ 4720 4792 /*configuration: */ … … 4731 4803 /*From command line arguments, retrieve different filenames needed to create the FemModel: */ 4732 4804 solution_type=StringToEnumx(solution); 4733 4805 4734 4806 /*Create femmodel from input files: */ 4735 4807 profiler->Start(MPROCESSOR); 4736 4808 this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL); 4737 4809 profiler->Stop(MPROCESSOR); 4738 4810 4739 4811 /*Save communicator in the parameters dataset: */ 4740 4812 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 4751 4823 size_t* poutputbuffersize; 4752 4824 4753 4754 4825 /*Before we delete the profiler, report statistics for this run: */ 4755 4826 profiler->Stop(TOTAL); //final tagging … … 4764 4835 ); 4765 4836 _printf0_("\n"); 4766 4837 4767 4838 /*Before we close the output file, recover the buffer and size:*/ 4768 4839 outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum)); … … 4804 4875 4805 4876 /*Open output file once for all and add output file descriptor to parameters*/ 4806 output_fid=open_memstream(&outputbuffer,&outputsize); 4877 output_fid=open_memstream(&outputbuffer,&outputsize); 4807 4878 if(output_fid==NULL)_error_("could not initialize output stream"); 4808 4879 this->parameters->SetParam(output_fid,OutputFilePointerEnum); … … 4820 4891 IssmDouble *newy = NULL; 4821 4892 IssmDouble *newz = NULL; 4893 IssmDouble *newxylist = NULL; 4822 4894 int *newelementslist = NULL; 4895 int* newdatalist = NULL; 4823 4896 int newnumberofvertices = -1; 4824 4897 int newnumberofelements = -1; … … 4845 4918 /*Initialize hmaxvertices with NAN*/ 4846 4919 hmaxvertices_serial=xNew<IssmDouble>(numberofvertices); 4847 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4920 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4848 4921 /*Fill hmaxvertices*/ 4849 4922 if(this->amrbamg->groundingline_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskGroundediceLevelsetEnum); … … 4852 4925 if(this->amrbamg->deviatoricerror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum); 4853 4926 } 4854 4927 4855 4928 if(my_rank==0){ 4856 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); 4857 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the refinement process."); 4858 } 4859 4860 /*Cleanup*/ 4861 xDelete<IssmDouble>(vector_serial); 4862 xDelete<IssmDouble>(hmaxvertices_serial); 4863 delete vector; 4864 4865 /*Send new mesh to others CPU*/ 4866 ISSM_MPI_Bcast(&newnumberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4867 ISSM_MPI_Bcast(&newnumberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4868 if(my_rank){ 4869 newx=xNew<IssmDouble>(newnumberofvertices); 4870 newy=xNew<IssmDouble>(newnumberofvertices); 4871 newz=xNew<IssmDouble>(newnumberofvertices); 4872 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 4873 } 4874 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4875 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4876 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4877 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4878 4879 /*Assign output pointers*/ 4880 *pnewnumberofvertices = newnumberofvertices; 4881 *pnewnumberofelements = newnumberofelements; 4882 *pnewx = newx; 4883 *pnewy = newy; 4884 *pnewz = newz; 4885 *pnewelementslist = newelementslist; 4929 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newdatalist,&newxylist,&newelementslist); 4930 if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the refinement process."); 4931 } 4932 4933 /*Send new mesh to others CPU's*/ 4934 if(my_rank) newdatalist=xNew<int>(2); 4935 ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm()); 4936 newnumberofvertices=newdatalist[0]; 4937 newnumberofelements=newdatalist[1]; 4938 if(my_rank){ 4939 newxylist =xNew<IssmDouble>(newnumberofvertices*2); 4940 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 4941 } 4942 ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4943 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4944 4945 /*Reorganize the data*/ 4946 newx=xNew<IssmDouble>(newnumberofvertices); 4947 newy=xNew<IssmDouble>(newnumberofvertices); 4948 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 4949 for(int i=0;i<newnumberofvertices;i++){ 4950 newx[i] = newxylist[2*i]; 4951 newy[i] = newxylist[2*i+1]; 4952 } 4953 4954 /*Assign output pointers*/ 4955 *pnewnumberofvertices = newnumberofvertices; 4956 *pnewnumberofelements = newnumberofelements; 4957 *pnewx = newx; 4958 *pnewy = newy; 4959 *pnewz = newz; 4960 *pnewelementslist = newelementslist; 4961 4962 /*Cleanup*/ 4963 xDelete<int>(newdatalist); 4964 xDelete<IssmDouble>(newxylist); 4965 xDelete<IssmDouble>(vector_serial); 4966 xDelete<IssmDouble>(hmaxvertices_serial); 4967 delete vector; 4886 4968 } 4887 4969 /*}}}*/ … … 4908 4990 /*Create bamg data structures for bamg*/ 4909 4991 this->amrbamg = new AmrBamg(); 4910 4992 4911 4993 /*Get amr parameters*/ 4912 4994 this->parameters->FindParam(&hmin,AmrHminEnum); … … 4932 5014 4933 5015 /*Re-create original mesh and put it in bamg structure (only cpu 0)*/ 4934 if(my_rank==0){ 5016 if(my_rank==0){ 4935 5017 this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements); 4936 5018 } … … 4946 5028 4947 5029 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 4948 5030 4949 5031 /*Intermediaries*/ 4950 5032 int numberofvertices = this->vertices->NumberOfVertices(); … … 4953 5035 4954 5036 switch(levelset_type){ 4955 case MaskGroundediceLevelsetEnum: 5037 case MaskGroundediceLevelsetEnum: 4956 5038 threshold = this->amrbamg->groundingline_distance; 4957 5039 resolution = this->amrbamg->groundingline_resolution; … … 4967 5049 this->GetVerticeDistanceToZeroLevelSet(&verticedistance,levelset_type); 4968 5050 if(!verticedistance) _error_("verticedistance is NULL!\n"); 4969 5051 4970 5052 /*Fill hmaxVertices*/ 4971 5053 for(int i=0;i<numberofvertices;i++){ … … 4981 5063 /*}}}*/ 4982 5064 void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/ 4983 5065 4984 5066 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 4985 5067 … … 4989 5071 int numberofvertices = this->vertices->NumberOfVertices(); 4990 5072 IssmDouble* maxlength = xNew<IssmDouble>(numberofelements); 4991 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 5073 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 4992 5074 IssmDouble* error_elements = NULL; 4993 5075 IssmDouble* x = NULL; … … 5002 5084 /*Fill variables*/ 5003 5085 switch(errorestimator_type){ 5004 case ThicknessErrorEstimatorEnum: 5086 case ThicknessErrorEstimatorEnum: 5005 5087 threshold = this->amrbamg->thicknesserror_threshold; 5006 5088 groupthreshold = this->amrbamg->thicknesserror_groupthreshold; … … 5027 5109 case ThicknessErrorEstimatorEnum: this->amrbamg->thicknesserror_maximum = maxerror;break; 5028 5110 case DeviatoricStressErrorEstimatorEnum: this->amrbamg->deviatoricerror_maximum = maxerror;break; 5029 } 5111 } 5030 5112 } 5031 5113 5032 5114 /*Get mesh*/ 5033 5115 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&index); 5034 5116 5035 5117 /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/ 5036 5118 for(int i=0;i<numberofelements;i++){ … … 5046 5128 error_vertices[v2]+=error_elements[i]; 5047 5129 error_vertices[v3]+=error_elements[i]; 5048 } 5130 } 5049 5131 5050 5132 /*Fill hmaxvertices with the criteria*/ … … 5060 5142 } 5061 5143 } 5062 /*Now, fill the hmaxvertices if requested*/ 5144 /*Now, fill the hmaxvertices if requested*/ 5063 5145 if(refine){ 5064 5146 for(int j=0;j<elementswidth;j++){ … … 5090 5172 /*Output*/ 5091 5173 IssmDouble* verticedistance; 5092 5174 5093 5175 /*Intermediaries*/ 5094 5176 int numberofvertices = this->vertices->NumberOfVertices(); … … 5102 5184 /*Get vertices coordinates*/ 5103 5185 VertexCoordinatesx(&x,&y,&z,this->vertices,false) ; 5104 5105 /*Get points which level set is zero (center of elements with zero level set)*/ 5186 5187 /*Get points which level set is zero (center of elements with zero level set)*/ 5106 5188 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5107 5189 … … 5112 5194 for(int j=0;j<numberofpoints;j++){ 5113 5195 distance=sqrt((x[i]-levelset_points[2*j])*(x[i]-levelset_points[2*j])+(y[i]-levelset_points[2*j+1])*(y[i]-levelset_points[2*j+1])); 5114 verticedistance[i]=min(distance,verticedistance[i]); 5115 } 5116 } 5196 verticedistance[i]=min(distance,verticedistance[i]); 5197 } 5198 } 5117 5199 5118 5200 /*Assign the pointer*/ … … 5133 5215 /*pnewelementslist keep vertices in Matlab indexing*/ 5134 5216 int my_rank = IssmComm::GetRank(); 5135 int numberofelements = this->elements->NumberOfElements();5136 5217 IssmDouble* gl_distance = NULL; 5137 5218 IssmDouble* if_distance = NULL; … … 5141 5222 IssmDouble* newy = NULL; 5142 5223 IssmDouble* newz = NULL; 5224 IssmDouble* newxylist = NULL; 5143 5225 int* newelementslist = NULL; 5144 int newnumberofvertices = -1; 5226 int* newdatalist = NULL; 5227 int newnumberofvertices = -1; 5145 5228 int newnumberofelements = -1; 5146 5229 … … 5148 5231 if(this->amr->groundingline_distance>0) this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskGroundediceLevelsetEnum); 5149 5232 if(this->amr->icefront_distance>0) this->GetElementDistanceToZeroLevelSet(&if_distance,MaskIceLevelsetEnum); 5150 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5151 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5152 5233 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5234 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5235 5153 5236 if(my_rank==0){ 5154 5237 this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror, 5155 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5156 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 5157 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the ReMeshNeopz."); 5158 } 5159 5160 /*Send new mesh to others CPU*/ 5161 ISSM_MPI_Bcast(&newnumberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 5162 ISSM_MPI_Bcast(&newnumberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 5163 if(my_rank){ 5164 newx=xNew<IssmDouble>(newnumberofvertices); 5165 newy=xNew<IssmDouble>(newnumberofvertices); 5166 newz=xNew<IssmDouble>(newnumberofvertices); 5167 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 5168 } 5169 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5170 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5171 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5172 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5173 5174 /*Assign the pointers*/ 5175 (*pnewelementslist) = newelementslist; //Matlab indexing 5176 (*pnewx) = newx; 5177 (*pnewy) = newy; 5178 (*pnewz) = newz; 5179 *pnewnumberofvertices= newnumberofvertices; 5180 *pnewnumberofelements= newnumberofelements; 5238 &newdatalist,&newxylist,&newelementslist); 5239 if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the ReMeshNeopz."); 5240 } 5241 5242 /*Send new mesh to others CPU's*/ 5243 if(my_rank) newdatalist=xNew<int>(2); 5244 ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm()); 5245 newnumberofvertices=newdatalist[0]; 5246 newnumberofelements=newdatalist[1]; 5247 if(my_rank){ 5248 newxylist =xNew<IssmDouble>(newnumberofvertices*2); 5249 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 5250 } 5251 ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5252 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5253 5254 /*Reorganize the data*/ 5255 newx=xNew<IssmDouble>(newnumberofvertices); 5256 newy=xNew<IssmDouble>(newnumberofvertices); 5257 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 5258 for(int i=0;i<newnumberofvertices;i++){ 5259 newx[i] = newxylist[2*i]; 5260 newy[i] = newxylist[2*i+1]; 5261 } 5262 5263 /*Assign the pointers*/ 5264 (*pnewelementslist) = newelementslist; //Matlab indexing 5265 (*pnewx) = newx; 5266 (*pnewy) = newy; 5267 (*pnewz) = newz; 5268 *pnewnumberofvertices= newnumberofvertices; 5269 *pnewnumberofelements= newnumberofelements; 5181 5270 5182 5271 /*Cleanup*/ 5183 xDelete<IssmDouble>(deviatoricerror); 5184 xDelete<IssmDouble>(thicknesserror); 5185 xDelete<IssmDouble>(gl_distance); 5186 xDelete<IssmDouble>(if_distance); 5272 xDelete<int>(newdatalist); 5273 xDelete<IssmDouble>(newxylist); 5274 xDelete<IssmDouble>(deviatoricerror); 5275 xDelete<IssmDouble>(thicknesserror); 5276 xDelete<IssmDouble>(gl_distance); 5277 xDelete<IssmDouble>(if_distance); 5187 5278 } 5188 5279 /*}}}*/ 5189 5280 void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/ 5190 5281 5191 5282 /*Define variables*/ 5192 5283 int my_rank = IssmComm::GetRank(); … … 5197 5288 IssmDouble* z = NULL; 5198 5289 int* elements = NULL; 5199 5290 5200 5291 /*Initialize field as NULL for now*/ 5201 5292 this->amr = NULL; … … 5205 5296 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements); 5206 5297 5207 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5298 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5208 5299 /*Just CPU #0 should keep AMR object*/ 5209 5300 /*Initialize refinement pattern*/ 5210 5301 this->SetRefPatterns(); 5211 5302 this->amr = new AdaptiveMeshRefinement(); 5212 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5303 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5213 5304 /*Get amr parameters*/ 5214 5305 this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum); … … 5223 5314 this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum); 5224 5315 this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum); 5225 if(my_rank==0){ 5316 if(my_rank==0){ 5226 5317 this->amr->CreateInitialMesh(numberofvertices,numberofelements,x,y,elements); 5227 5318 } … … 5244 5335 /*Output*/ 5245 5336 IssmDouble* elementdistance; 5246 5337 5247 5338 /*Intermediaries*/ 5248 5339 int numberofelements = this->elements->NumberOfElements(); … … 5253 5344 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 5254 5345 int numberofpoints; 5255 5256 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5346 5347 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5257 5348 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5258 5349 … … 5260 5351 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 5261 5352 int sid = element->Sid(); 5262 element->GetVerticesCoordinates(&xyz_list); 5353 element->GetVerticesCoordinates(&xyz_list); 5263 5354 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 5264 5355 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 5270 5361 for(int j=0;j<numberofpoints;j++){ 5271 5362 distance =sqrt((xc-levelset_points[2*j])*(xc-levelset_points[2*j])+(yc-levelset_points[2*j+1])*(yc-levelset_points[2*j+1])); 5272 mindistance=min(distance,mindistance); 5363 mindistance=min(distance,mindistance); 5273 5364 } 5274 5365 velementdistance->SetValue(sid,mindistance,INS_VAL); 5275 5366 xDelete<IssmDouble>(xyz_list); 5276 } 5367 } 5277 5368 5278 5369 /*Assemble*/ -
issm/trunk/src/c/classes/FemModel.h
r22758 r23189 1 1 /* 2 * FemModel.h: 2 * FemModel.h: 3 3 */ 4 4 … … 47 47 Nodes *nodes; //one set of nodes 48 48 Parameters *parameters; //one set of parameters, independent of the analysis_type 49 Results *results; //results that cannot be fit into the elements 49 Results *results; //results that cannot be fit into the elements 50 50 Vertices *vertices; //one set of vertices 51 51 … … 80 80 void Solve(void); 81 81 82 /*Modules*/ 82 /*Modules*/ 83 83 void BalancethicknessMisfitx(IssmDouble* pV); 84 84 void CalvingRateVonmisesx(); … … 139 139 #endif 140 140 #ifdef _HAVE_SEALEVELRISE_ 141 void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius );142 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution );143 void SealevelriseRotationalFeedback(Vector<IssmDouble>* p Sgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius);144 void Sealevelrise Geodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz);141 void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop); 142 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution,int loop); 143 void SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius); 144 void SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz); 145 145 IssmDouble SealevelriseOceanAverage(Vector<IssmDouble>* Sg); 146 146 #endif 147 147 void HydrologyEPLupdateDomainx(IssmDouble* pEplcount); 148 void HydrologyIDSupdateDomainx(IssmDouble* pIDScount); 148 149 void TimeAdaptx(IssmDouble* pdt); 149 150 void UpdateConstraintsExtrudeFromBasex(); -
issm/trunk/src/c/classes/IoModel.cpp
r22758 r23189 130 130 131 131 this->my_elements=NULL; 132 this->my_faces=NULL; 133 this->my_edges=NULL; 132 134 this->my_vertices=NULL; 133 135 … … 157 159 bool autodiff=false; 158 160 bool iscontrol=false; 159 161 160 162 /*First, keep track of the file handle: */ 161 163 this->fid=iomodel_handle; … … 192 194 /*Initialize permanent data: */ 193 195 this->my_elements = NULL; 196 this->my_faces = NULL; 197 this->my_edges = NULL; 194 198 this->my_vertices = NULL; 195 199 … … 236 240 237 241 xDelete<bool>(this->my_elements); 242 xDelete<bool>(this->my_faces); 243 xDelete<bool>(this->my_edges); 238 244 xDelete<int>(this->my_vertices); 239 245 … … 422 428 this->FetchData(&autodiff,"md.autodiff.isautodiff"); 423 429 this->FetchData(&iscontrol,"md.inversion.iscontrol"); 424 430 425 431 if(trace || (autodiff && !iscontrol)){ 426 432 … … 506 512 507 513 char** stringarray=*pstringarray; 508 514 509 515 if(numstrings){ 510 516 for(int i=0;i<numstrings;i++){ … … 597 603 /*Read the integer and broadcast it to other cpus:*/ 598 604 if(fread(&integer,sizeof(int),1,this->fid)!=1) _error_("could not read integer "); 599 605 600 606 /*Convert codes to Enums if needed*/ 601 607 if(strcmp(record_name,"md.smb.model")==0) integer = IoCodeToEnumSMB(integer); … … 662 668 } else if(strcmp(record_name,"md.thermal.fe")==0){ 663 669 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 670 } else if(strcmp(record_name,"md.levelset.fe")==0){ 671 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 664 672 } else if(strcmp(record_name,"md.groundingline.migration")==0){ 673 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 674 } else if(strcmp(record_name,"md.groundingline.friction_interpolation")==0){ 675 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 676 } else if(strcmp(record_name,"md.groundingline.melt_interpolation")==0){ 665 677 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 666 678 } else if(strcmp(record_name,"md.masstransport.hydrostatic_adjustment")==0){ … … 805 817 } else if(strcmp(record_name,"md.thermal.fe")==0){ 806 818 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 819 } else if(strcmp(record_name,"md.levelset.fe")==0){ 820 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 807 821 } else if(strcmp(record_name,"md.groundingline.migration")==0){ 822 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 823 } else if(strcmp(record_name,"md.groundingline.friction_interpolation")==0){ 824 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 825 } else if(strcmp(record_name,"md.groundingline.melt_interpolation")==0){ 808 826 this->AddConstant(new IoConstant(StringToEnumx(string),record_name)); 809 827 } else if(strcmp(record_name,"md.masstransport.hydrostatic_adjustment")==0){ … … 955 973 /*recover my_rank:*/ 956 974 int my_rank=IssmComm::GetRank(); 957 975 958 976 /*Set file pointer to beginning of the data: */ 959 977 fid=this->SetFilePointerToData(&code,NULL,data_name); … … 1126 1144 } 1127 1145 } 1128 1146 1129 1147 /*output: */ 1130 1148 int M,N; … … 1817 1835 /*check we are indeed finding a string, not something else: */ 1818 1836 if(codes[i]!=4)_error_("expecting a string for \""<<data_name<<"\""); 1819 1837 1820 1838 /*We have to read a string from disk. First read the dimensions of the string, then the string: */ 1821 1839 fsetpos(fid,file_positions+i); … … 1846 1864 xDelete<int>(codes); 1847 1865 xDelete<fpos_t>(file_positions); 1848 1866 1849 1867 /*Assign output pointers: */ 1850 1868 *pstrings=strings; … … 1867 1885 /*recover my_rank:*/ 1868 1886 int my_rank=IssmComm::GetRank(); 1869 1887 1870 1888 /*Get file pointers to beginning of the data (multiple instances of it): */ 1871 1889 file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name); … … 1882 1900 1883 1901 if(code!=2)_error_("expecting an integer for \""<<data_name<<"\""); 1884 1902 1885 1903 /*We have to read a integer from disk. First read the dimensions of the integer, then the integer: */ 1886 1904 fsetpos(fid,file_positions+i); … … 1895 1913 } 1896 1914 } 1897 1915 1898 1916 /*Free ressources:*/ 1899 1917 xDelete<fpos_t>(file_positions); … … 1920 1938 /*recover my_rank:*/ 1921 1939 int my_rank=IssmComm::GetRank(); 1922 1940 1923 1941 /*Get file pointers to beginning of the data (multiple instances of it): */ 1924 1942 file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name); … … 1935 1953 1936 1954 if(code!=3)_error_("expecting a double for \""<<data_name<<"\""); 1937 1955 1938 1956 /*We have to read a double from disk: */ 1939 1957 fsetpos(fid,file_positions+i); … … 1948 1966 } 1949 1967 } 1950 1968 1951 1969 /*Free ressources:*/ 1952 1970 xDelete<fpos_t>(file_positions); … … 1977 1995 /*recover my_rank:*/ 1978 1996 int my_rank=IssmComm::GetRank(); 1979 1997 1980 1998 /*Get file pointers to beginning of the data (multiple instances of it): */ 1981 1999 file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name); … … 2006 2024 } 2007 2025 ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2008 2009 2026 2010 2027 /*Now allocate matrix: */ … … 2031 2048 else 2032 2049 matrix=NULL; 2033 2034 2050 2035 2051 /*Assign: */ 2036 2052 mdims[i]=M; … … 2039 2055 } 2040 2056 } 2041 2057 2042 2058 /*Free ressources:*/ 2043 2059 xDelete<fpos_t>(file_positions); … … 2081 2097 /*recover my_rank:*/ 2082 2098 int my_rank=IssmComm::GetRank(); 2083 2099 2084 2100 /*Get file pointers to beginning of the data (multiple instances of it): */ 2085 2101 file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name); … … 2110 2126 } 2111 2127 ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2112 2113 2128 2114 2129 /*Now allocate matrix: */ … … 2136 2151 else 2137 2152 integer_matrix=NULL; 2138 2139 2153 2140 2154 /*Assign: */ 2141 2155 mdims[i]=M; … … 2144 2158 } 2145 2159 } 2146 2160 2147 2161 /*Free ressources:*/ 2148 2162 xDelete<fpos_t>(file_positions); … … 2368 2382 vector_types = xNew<int>(num_instances); 2369 2383 } 2370 2384 2371 2385 /*Reset FILE* position to the beginning of the file, and start again, this time saving the data information 2372 2386 * as we find it: */ … … 2411 2425 vector_types[counter] = vector_type; 2412 2426 fgetpos(fid,file_positions+counter); 2413 2427 2414 2428 /*backup and skip over the record, as we have more work to do: */ 2415 2429 if(5<=record_code && record_code<=7) fseek(fid,-sizeof(int),SEEK_CUR); 2416 2430 fseek(fid,-sizeof(int),SEEK_CUR); 2417 2431 fseek(fid,-sizeof(int),SEEK_CUR); 2418 2432 2419 2433 /*increment counter: */ 2420 2434 counter++; -
issm/trunk/src/c/classes/IoModel.h
r22758 r23189 64 64 /*Partitioning*/ 65 65 bool *my_elements; 66 bool *my_faces; 67 bool *my_edges; 66 68 int *my_vertices; 67 69 -
issm/trunk/src/c/classes/Loads/Friction.cpp
r22758 r23189 13 13 #include "../classes.h" 14 14 #include "shared/shared.h" 15 /*}}}*/ 15 /*}}}*/ 16 16 17 17 /*Constructors/destructors*/ … … 60 60 61 61 /*diverse: */ 62 int CoupledFlag;63 62 IssmDouble q_exp; 64 63 IssmDouble C_param; 65 64 IssmDouble As; 66 IssmDouble Neff;67 65 IssmDouble n; 68 66 IssmDouble alpha; … … 70 68 IssmDouble vx,vy,vz,vmag; 71 69 IssmDouble alpha_complement; 72 IssmDouble base,sealevel,thickness;73 70 74 71 /*Recover parameters: */ 75 72 element->GetInputValue(&q_exp,FrictionQEnum); 76 73 element->GetInputValue(&C_param,FrictionCEnum); 77 78 74 element->GetInputValue(&As,gauss,FrictionAsEnum); 79 75 element->GetInputValue(&n,gauss,MaterialsRheologyNEnum); 80 element->GetInputValue(&thickness, gauss,ThicknessEnum); 81 element->GetInputValue(&base, gauss,BaseEnum); 82 element->GetInputValue(&sealevel, gauss,SealevelEnum); 83 84 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 85 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 86 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 87 element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum); 88 89 switch(CoupledFlag){ 90 case 0: 91 Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel)); 92 break; 93 case 1: 94 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 95 break; 96 case 2: 97 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 98 break; 99 default: 100 _error_("not supported"); 101 } 102 103 if(Neff<0)Neff=0; 76 77 /*Get effective pressure*/ 78 IssmDouble Neff = EffectivePressure(gauss); 104 79 105 80 //We need the velocity magnitude to evaluate the basal stress: … … 174 149 void Friction::GetAlphaViscousComplement(IssmDouble* palpha_complement, Gauss* gauss){/*{{{*/ 175 150 176 /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p. 177 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 151 /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p. 152 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 178 153 * alpha_complement= Neff ^r * vel ^s*/ 179 154 180 155 /*diverse: */ 181 int CoupledFlag;182 156 IssmDouble r,s; 183 157 IssmDouble vx,vy,vz,vmag; 184 158 IssmDouble drag_p,drag_q; 185 IssmDouble Neff;186 159 IssmDouble drag_coefficient; 187 IssmDouble base,thickness,sealevel;188 160 IssmDouble alpha_complement; 189 161 … … 191 163 element->GetInputValue(&drag_p,FrictionPEnum); 192 164 element->GetInputValue(&drag_q,FrictionQEnum); 193 element->GetInputValue(&thickness, gauss,ThicknessEnum);194 element->GetInputValue(&base, gauss,BaseEnum);195 element->GetInputValue(&sealevel, gauss,SealevelEnum);196 165 element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum); 197 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 198 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 199 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 200 element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum); 201 //compute r and q coefficients: */ 166 167 /*compute r and q coefficients: */ 202 168 r=drag_q/drag_p; 203 169 s=1./drag_p; 204 170 205 //From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing or coupled to hydrologymodel: 206 switch(CoupledFlag){ 207 case 0: 208 Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel)); 209 break; 210 case 1: 211 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 212 break; 213 case 2: 214 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 215 break; 216 default: 217 _error_("not supported"); 218 } 219 if(Neff<0)Neff=0; 171 /*Get effective pressure*/ 172 IssmDouble Neff = EffectivePressure(gauss); 220 173 221 174 //We need the velocity magnitude to evaluate the basal stress: … … 242 195 /*Check to prevent dividing by zero if vmag==0*/ 243 196 if(vmag==0. && (s-1.)<0.) alpha_complement=0.; 244 else alpha_complement=pow(Neff,r)*pow(vmag,(s-1));_assert_(!xIsNan<IssmDouble>(alpha_complement)); 197 else alpha_complement=pow(Neff,r)*pow(vmag,(s-1)); 198 199 _assert_(!xIsNan<IssmDouble>(alpha_complement)); 200 _assert_(!xIsInf<IssmDouble>(alpha_complement)); 245 201 246 202 /*Assign output pointers:*/ … … 273 229 break; 274 230 case 8: 275 GetAlpha2S ommers(palpha2,gauss);231 GetAlpha2Shakti(palpha2,gauss); 276 232 break; 277 233 case 9: 278 234 GetAlpha2Josh(palpha2,gauss); 279 235 break; 236 case 10: 237 GetAlpha2PISM(palpha2,gauss); 238 break; 280 239 default: 281 240 _error_("Friction law "<< this->law <<" not supported"); … … 285 244 void Friction::GetAlpha2Coulomb(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 286 245 287 /*This routine calculates the basal friction coefficient 246 /*This routine calculates the basal friction coefficient 288 247 alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/ 289 248 290 249 /*diverse: */ 291 int CoupledFlag;292 250 IssmDouble r,s; 293 251 IssmDouble drag_p, drag_q; 294 IssmDouble Neff;295 252 IssmDouble thickness,base,floatation_thickness,sealevel; 296 253 IssmDouble vx,vy,vz,vmag; … … 306 263 element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum); 307 264 element->GetInputValue(&drag_coefficient_coulomb, gauss,FrictionCoefficientcoulombEnum); 308 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 309 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 310 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 311 element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum); 265 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 266 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 267 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 312 268 313 269 //compute r and q coefficients: */ … … 315 271 s=1./drag_p; 316 272 317 //From base and thickness, compute effective pressure when drag is viscous: 318 switch(CoupledFlag){ 319 case 0: 320 Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel)); 321 break; 322 case 1: 323 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 324 break; 325 case 2: 326 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 327 break; 328 default: 329 _error_("not supported"); 330 } 331 332 if(Neff<0)Neff=0; 333 273 /*Get effective pressure*/ 274 IssmDouble Neff = EffectivePressure(gauss); 275 276 /*Compute velocity magnitude*/ 334 277 switch(dim){ 335 278 case 1: … … 370 313 void Friction::GetAlpha2Hydro(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 371 314 372 /*This routine calculates the basal friction coefficient 315 /*This routine calculates the basal friction coefficient 373 316 Based on Gagliardini 2007, needs a good effective pressure computation 374 317 Not tested so far so use at your own risks … … 378 321 379 322 /*diverse: */ 380 int CoupledFlag;381 323 IssmDouble q_exp; 382 324 IssmDouble C_param; 383 325 IssmDouble As; 384 385 IssmDouble Neff;386 326 IssmDouble n; 387 327 … … 391 331 IssmDouble vx,vy,vz,vmag; 392 332 IssmDouble alpha2; 393 IssmDouble base,thickness,sealevel;394 333 395 334 /*Recover parameters: */ … … 398 337 element->GetInputValue(&As,gauss,FrictionAsEnum); 399 338 element->GetInputValue(&n,gauss,MaterialsRheologyNEnum); 400 element->GetInputValue(&thickness, gauss,ThicknessEnum); 401 element->GetInputValue(&base, gauss,BaseEnum); 402 element->GetInputValue(&sealevel, gauss,SealevelEnum); 403 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 404 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 405 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 406 element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum); 407 408 switch(CoupledFlag){ 409 case 0: 410 Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel)); 411 break; 412 case 1: 413 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 414 break; 415 case 2: 416 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 417 break; 418 default: 419 _error_("not supported"); 420 } 421 422 if(Neff<0)Neff=0; 423 339 340 /*Get effective pressure*/ 341 IssmDouble Neff = EffectivePressure(gauss); 342 343 /*Compute velocity magnitude*/ 424 344 switch(dim){ 425 345 case 1: … … 453 373 Gamma=(Chi/(1. + alpha * pow(Chi,q_exp))); 454 374 /*Check to prevent dividing by zero if vmag==0*/ 455 if(vmag==0.) alpha2=0.; 375 if(vmag==0.) alpha2=0.; 456 376 else if (Neff==0) alpha2=0.0; 457 377 else alpha2=Neff * C_param * pow(Gamma,1./n) * 1/vmag; … … 461 381 *palpha2=alpha2; 462 382 }/*}}}*/ 463 void Friction::GetAlpha2S ommers(IssmDouble* palpha2, Gauss* gauss){/*{{{*/383 void Friction::GetAlpha2Shakti(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 464 384 465 385 /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff, with Neff=rho_ice*g*thickness+rho_ice*g*(head-base)*/ … … 570 490 void Friction::GetAlpha2Viscous(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 571 491 572 /*This routine calculates the basal friction coefficient 492 /*This routine calculates the basal friction coefficient 573 493 alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/ 574 494 575 495 /*diverse: */ 576 int CoupledFlag;577 496 IssmDouble r,s; 578 497 IssmDouble drag_p, drag_q; 579 IssmDouble Neff;580 IssmDouble thickness,base,sealevel;581 498 IssmDouble vx,vy,vz,vmag; 582 499 IssmDouble drag_coefficient; … … 586 503 element->GetInputValue(&drag_p,FrictionPEnum); 587 504 element->GetInputValue(&drag_q,FrictionQEnum); 588 element->GetInputValue(&thickness, gauss,ThicknessEnum);589 element->GetInputValue(&base, gauss,BaseEnum);590 element->GetInputValue(&sealevel, gauss,SealevelEnum);591 505 element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum); 592 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 593 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 594 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 595 element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum); 596 //compute r and q coefficients: */ 506 507 /*compute r and q coefficients: */ 597 508 r=drag_q/drag_p; 598 509 s=1./drag_p; 599 510 600 //From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing: 601 switch(CoupledFlag){ 602 case 0: 603 Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel)); 604 break; 605 case 1: 606 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 607 break; 608 case 2: 609 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 610 break; 611 default: 612 _error_("not supported"); 613 } 614 if(Neff<0)Neff=0; 615 511 /*Get effective pressure*/ 512 IssmDouble Neff = EffectivePressure(gauss); 513 514 /*Compute velocity magnitude*/ 616 515 switch(dim){ 617 516 case 1: … … 644 543 void Friction::GetAlpha2WaterLayer(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 645 544 646 /*This routine calculates the basal friction coefficient 545 /*This routine calculates the basal friction coefficient 647 546 alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/ 648 547 … … 776 675 *palpha2=alpha2; 777 676 }/*}}}*/ 677 void Friction::GetAlpha2PISM(IssmDouble* palpha2, Gauss* gauss){/*{{{*/ 678 /*Here, we want to parameterize the friction using a pseudoplastic friction law, 679 * computing the basal shear stress as 680 * 681 * alpha2 = tau_c (u_b/(abs(u_b)^(1-q)*u_0^q)) 682 * 683 * The yield stress tau_c is a function of the effective pressure N 684 * using a Mohr-Coloumb criterion, so that 685 * tau_c = tan(phi)*N, 686 * where phi is the till friction angle, representing sediment strength 687 * 688 * The effective pressure is given by Eq. (5) in Aschwanden et al. 2016: 689 * 690 * N = delta * P0 * 10^((e_0/Cc)(1-(W/Wmax))) 691 * 692 * W is calculated by a non-conserving hydrology model in HydrologyPismAnalysis.cpp 693 * 694 * see Aschwanden et al. 2016 and Bueler and Brown, 2009 for more details 695 */ 696 697 /*compute ice overburden pressure P0*/ 698 IssmDouble thickness,base,P0; 699 element->GetInputValue(&thickness, gauss,ThicknessEnum); 700 element->GetInputValue(&base, gauss,BaseEnum); 701 //element->GetInputValue(&sealevel, gauss,SealevelEnum); 702 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 703 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 704 P0 = gravity*rho_ice*thickness; 705 706 /*Compute effective pressure*/ 707 IssmDouble N,delta,W,Wmax,e0,Cc; 708 element->parameters->FindParam(&delta,FrictionDeltaEnum); 709 element->parameters->FindParam(&e0,FrictionVoidRatioEnum); 710 element->GetInputValue(&Cc,gauss,FrictionSedimentCompressibilityCoefficientEnum); 711 element->GetInputValue(&W,gauss,WatercolumnEnum); 712 element->GetInputValue(&Wmax,gauss,HydrologyWatercolumnMaxEnum); 713 714 /*Check that water column height is within 0 and upper bound, correct if needed*/ 715 if(W>Wmax) W=Wmax; 716 if(W<0) W=0.; 717 718 N = delta*P0*pow(10.,(e0/Cc)*(1.-W/Wmax)); 719 720 /*Get till friction angles, defined by user [deg]*/ 721 IssmDouble phi; 722 element->GetInputValue(&phi,gauss,FrictionTillFrictionAngleEnum); 723 724 /*Convert till friction angle from user-defined deg to rad, which Matlab uses*/ 725 phi = phi*PI/180.; 726 727 /*Compute yield stress following a Mohr-Colomb criterion*/ 728 IssmDouble tau_c = N*tan(phi); 729 730 /*Compute basal speed*/ 731 IssmDouble ub; 732 element->GetInputValue(&ub,gauss,VelEnum); 733 734 /*now compute alpha^2*/ 735 IssmDouble u0,q; 736 element->parameters->FindParam(&u0,FrictionThresholdSpeedEnum); 737 element->parameters->FindParam(&q,FrictionPseudoplasticityExponentEnum); 738 IssmDouble alpha2 = tau_c/(pow(ub+1.e-10,1.-q)*pow(u0,q)); 739 740 /*Final checks in debuging mode*/ 741 _assert_(!xIsNan<IssmDouble>(alpha2)); 742 _assert_(!xIsInf<IssmDouble>(alpha2)); 743 744 /*Assign output pointers:*/ 745 *palpha2=alpha2; 746 }/*}}}*/ 747 748 IssmDouble Friction::EffectivePressure(Gauss* gauss){/*{{{*/ 749 /*Get effective pressure as a function of flag */ 750 751 /*diverse: */ 752 int coupled_flag; 753 IssmDouble thickness,base,sealevel; 754 IssmDouble p_ice,p_water; 755 IssmDouble Neff; 756 757 /*Recover parameters: */ 758 element->parameters->FindParam(&coupled_flag,FrictionCouplingEnum); 759 760 /*From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing:*/ 761 switch(coupled_flag){ 762 case 0:{ 763 element->GetInputValue(&thickness, gauss,ThicknessEnum); 764 element->GetInputValue(&base, gauss,BaseEnum); 765 element->GetInputValue(&sealevel, gauss,SealevelEnum); 766 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 767 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 768 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 769 p_ice = gravity*rho_ice*thickness; 770 p_water = rho_water*gravity*(sealevel-base); 771 Neff = p_ice - p_water; 772 } 773 break; 774 case 1:{ 775 element->GetInputValue(&thickness, gauss,ThicknessEnum); 776 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 777 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 778 p_ice = gravity*rho_ice*thickness; 779 p_water = 0.; 780 Neff = p_ice - p_water; 781 } 782 break; 783 case 2:{ 784 element->GetInputValue(&thickness, gauss,ThicknessEnum); 785 element->GetInputValue(&base, gauss,BaseEnum); 786 element->GetInputValue(&sealevel, gauss,SealevelEnum); 787 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum); 788 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 789 IssmDouble gravity = element->GetMaterialParameter(ConstantsGEnum); 790 p_ice = gravity*rho_ice*thickness; 791 p_water = max(0.,rho_water*gravity*(sealevel-base)); 792 Neff = p_ice - p_water; 793 } 794 break; 795 case 3: 796 element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum); 797 break; 798 case 4: 799 element->GetInputValue(&Neff,gauss,EffectivePressureEnum); 800 break; 801 default: 802 _error_("not supported"); 803 } 804 805 /*Make sure Neff is positive*/ 806 if(Neff<0.) Neff=0.; 807 808 /*Return effective pressure*/ 809 return Neff; 810 811 }/*}}}*/ -
issm/trunk/src/c/classes/Loads/Friction.h
r21729 r23189 37 37 void GetAlpha2Hydro(IssmDouble* palpha2,Gauss* gauss); 38 38 void GetAlpha2Josh(IssmDouble* palpha2,Gauss* gauss); 39 void GetAlpha2S ommers(IssmDouble* palpha2,Gauss* gauss);39 void GetAlpha2Shakti(IssmDouble* palpha2,Gauss* gauss); 40 40 void GetAlpha2Temp(IssmDouble* palpha2,Gauss* gauss); 41 41 void GetAlpha2Viscous(IssmDouble* palpha2,Gauss* gauss); … … 43 43 void GetAlpha2Weertman(IssmDouble* palpha2,Gauss* gauss); 44 44 void GetAlpha2WeertmanTemp(IssmDouble* palpha2,Gauss* gauss); 45 void GetAlpha2PISM(IssmDouble* palpha2,Gauss* gauss); 46 47 IssmDouble EffectivePressure(Gauss* gauss); 45 48 }; 46 49 -
issm/trunk/src/c/classes/Loads/Moulin.cpp
r21341 r23189 178 178 179 179 switch(analysis_type){ 180 181 case HydrologyS ommersAnalysisEnum:182 pe = this->CreatePVectorHydrologyS ommers();180 181 case HydrologyShaktiAnalysisEnum: 182 pe = this->CreatePVectorHydrologyShakti(); 183 183 break; 184 184 case HydrologyDCInefficientAnalysisEnum: … … 337 337 /*}}}*/ 338 338 339 ElementVector* Moulin::CreatePVectorHydrologyS ommers(void){/*{{{*/339 ElementVector* Moulin::CreatePVectorHydrologyShakti(void){/*{{{*/ 340 340 341 341 /*If this node is not the master node (belongs to another partition of the … … 395 395 IssmDouble moulin_load,dt; 396 396 ElementVector* pe=new ElementVector(&node,1,this->parameters); 397 397 398 398 this->element->GetInputValue(&moulin_load,node,HydrologydcBasalMoulinInputEnum); 399 399 parameters->FindParam(&dt,TimesteppingTimeStepEnum); 400 400 401 401 pe->values[0]=moulin_load*dt; 402 402 /*Clean up and return*/ -
issm/trunk/src/c/classes/Loads/Moulin.h
r21341 r23189 80 80 /*}}}*/ 81 81 82 ElementVector* CreatePVectorHydrologyS ommers(void);82 ElementVector* CreatePVectorHydrologyShakti(void); 83 83 ElementVector* CreatePVectorHydrologyDCInefficient(void); 84 84 ElementVector* CreatePVectorHydrologyDCEfficient(void); -
issm/trunk/src/c/classes/Loads/Neumannflux.cpp
r21341 r23189 30 30 /*}}}*/ 31 31 Neumannflux::Neumannflux(int neumannflux_id,int i,IoModel* iomodel,int* segments,int in_analysis_type){/*{{{*/ 32 33 32 34 33 /*Some sanity checks*/ … … 190 189 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */ 191 190 switch(analysis_type){ 192 case HydrologyS ommersAnalysisEnum:191 case HydrologyShaktiAnalysisEnum: 193 192 /*Nothing!*/ 194 193 break; … … 213 212 214 213 switch(analysis_type){ 215 case HydrologyS ommersAnalysisEnum:216 pe=CreatePVectorHydrologyS ommers();214 case HydrologyShaktiAnalysisEnum: 215 pe=CreatePVectorHydrologyShakti(); 217 216 break; 218 217 default: … … 346 345 347 346 /*Neumannflux management*/ 348 ElementVector* Neumannflux::CreatePVectorHydrologyS ommers(void){/*{{{*/347 ElementVector* Neumannflux::CreatePVectorHydrologyShakti(void){/*{{{*/ 349 348 350 349 /* constants*/ -
issm/trunk/src/c/classes/Loads/Neumannflux.h
r21341 r23189 73 73 /*}}}*/ 74 74 /*Neumannflux management:{{{*/ 75 ElementVector* CreatePVectorHydrologyS ommers(void);75 ElementVector* CreatePVectorHydrologyShakti(void); 76 76 /*}}}*/ 77 77 -
issm/trunk/src/c/classes/Loads/Pengrid.cpp
r21341 r23189 170 170 void Pengrid::Configure(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){/*{{{*/ 171 171 172 /*Take care of hooking up all objects for this load, ie links the objects in the hooks to their respective 172 /*Take care of hooking up all objects for this load, ie links the objects in the hooks to their respective 173 173 * datasets, using internal ids and offsets hidden in hooks: */ 174 174 hnode->configure(nodesin); … … 195 195 /*No loads applied, do nothing, originaly used for moulin input: */ 196 196 return; 197 197 198 198 } 199 199 /*}}}*/ … … 416 416 void Pengrid::ConstraintActivateHydrologyDCInefficient(int* punstable){/*{{{*/ 417 417 418 // The penalty is stable if it doesn't change during two consecutive iterations. 418 // The penalty is stable if it doesn't change during two consecutive iterations. 419 419 int unstable=0; 420 420 int new_active; … … 422 422 IssmDouble pressure; 423 423 IssmDouble h; 424 IssmDouble h_max; 424 IssmDouble h_max; 425 425 HydrologyDCInefficientAnalysis* inefanalysis = NULL; 426 426 … … 440 440 /*Get sediment water head h*/ 441 441 inefanalysis = new HydrologyDCInefficientAnalysis(); 442 element->GetInputValue(&h,node,SedimentHead Enum);442 element->GetInputValue(&h,node,SedimentHeadHydrostepEnum); 443 443 inefanalysis->GetHydrologyDCInefficientHmax(&h_max,element,node); 444 444 parameters->FindParam(&penalty_lock,HydrologydcPenaltyLockEnum); … … 476 476 void Pengrid::ConstraintActivateThermal(int* punstable){/*{{{*/ 477 477 478 // The penalty is stable if it doesn't change during to successive iterations. 478 // The penalty is stable if it doesn't change during to successive iterations. 479 479 IssmDouble pressure; 480 480 IssmDouble temperature; -
issm/trunk/src/c/classes/Materials/Matestar.cpp
r22758 r23189 109 109 110 110 if(marshall_direction==MARSHALLING_BACKWARD)helement=new Hook(); 111 111 112 112 MARSHALLING_ENUM(MatestarEnum); 113 113 MARSHALLING(mid); -
issm/trunk/src/c/classes/Materials/Matice.cpp
r22758 r23189 135 135 //if(helement) helement->DeepEcho(); 136 136 //else _printf_(" helement = NULL\n"); 137 137 138 138 _printf_(" element:\n"); 139 139 _printf_(" note: element not printed to avoid recursion.\n"); … … 143 143 /*}}}*/ 144 144 void Matice::Echo(void){/*{{{*/ 145 145 146 146 _printf_("Matice:\n"); 147 147 _printf_(" mid: " << mid << "\n"); 148 148 _printf_(" isdamaged: " << isdamaged << "\n"); 149 149 _printf_(" isenhanced: " << isenhanced << "\n"); 150 150 151 151 /*helement and element Echo were commented to avoid recursion.*/ 152 152 /*Example: element->Echo calls matice->Echo which calls element->Echo etc*/ … … 155 155 //if(helement) helement->Echo(); 156 156 //else _printf_(" helement = NULL\n"); 157 157 158 158 _printf_(" element:\n"); 159 159 _printf_(" note: element not printed to avoid recursion.\n"); … … 167 167 168 168 if(marshall_direction==MARSHALLING_BACKWARD)helement=new Hook(); 169 169 170 170 MARSHALLING_ENUM(MaticeEnum); 171 171 MARSHALLING(mid); … … 541 541 IssmDouble exx,eyy,exy,exz,eyz; 542 542 543 544 543 if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 545 544 (epsilon[3]==0) && (epsilon[4]==0)){ -
issm/trunk/src/c/classes/Materials/Matlitho.cpp
r22758 r23189 37 37 this->radius=xNew<IssmDouble>(this->numlayers+1); 38 38 xMemCpy<IssmDouble>(this->radius, iomodel->Data("md.materials.radius"),this->numlayers+1); 39 39 40 40 this->viscosity=xNew<IssmDouble>(this->numlayers); 41 41 xMemCpy<IssmDouble>(this->viscosity, iomodel->Data("md.materials.viscosity"),this->numlayers); 42 42 43 43 this->lame_lambda=xNew<IssmDouble>(this->numlayers); 44 44 xMemCpy<IssmDouble>(this->lame_lambda, iomodel->Data("md.materials.lame_lambda"),this->numlayers); 45 45 46 46 this->lame_mu=xNew<IssmDouble>(this->numlayers); 47 47 xMemCpy<IssmDouble>(this->lame_mu, iomodel->Data("md.materials.lame_mu"),this->numlayers); … … 61 61 this->issolid=xNew<IssmDouble>(this->numlayers); 62 62 xMemCpy<IssmDouble>(this->issolid, iomodel->Data("md.materials.issolid"),this->numlayers); 63 63 64 64 /*isburgersd= xNew<IssmDouble>(this->numlayers); 65 65 this->isburgers=xNew<bool>(this->numlayers); 66 66 xMemCpy<IssmDouble>(isburgersd, iomodel->Data("md.materials.isburgers"),this->numlayers); 67 67 for (int i=0;i<this->numlayers;i++)this->isburgers[i]=reCast<bool,IssmDouble>(isburgersd[i]); 68 68 69 69 issolidd= xNew<IssmDouble>(this->numlayers); 70 70 this->issolid=xNew<bool>(this->numlayers); 71 71 xMemCpy<IssmDouble>(issolidd, iomodel->Data("md.materials.issolid"),this->numlayers); 72 72 for (int i=0;i<this->numlayers;i++)this->issolid[i]=reCast<bool,IssmDouble>(issolidd[i]);*/ 73 73 74 74 /*free ressources: */ 75 75 xDelete<IssmDouble>(isburgersd); … … 78 78 /*}}}*/ 79 79 Matlitho::~Matlitho(){/*{{{*/ 80 80 81 81 xDelete<IssmDouble>(radius); 82 82 xDelete<IssmDouble>(viscosity); -
issm/trunk/src/c/classes/Materials/Matpar.cpp
r22758 r23189 59 59 mantle_shear_modulus = 0; 60 60 mantle_density = 0; 61 61 62 62 earth_density = 0; 63 63 … … 149 149 /*Nothing to add*/ 150 150 } 151 else if(hydrology_model==HydrologysommersEnum){ 151 else if(hydrology_model==HydrologyshaktiEnum){ 152 /*Nothing to add*/ 153 } 154 else if(hydrology_model==HydrologypismEnum){ 152 155 /*Nothing to add*/ 153 156 } … … 250 253 /*Nothing to add*/ 251 254 } 252 else if(hydrology_model==Hydrologys ommersEnum){255 else if(hydrology_model==HydrologyshaktiEnum){ 253 256 /*Nothing to add*/ 254 257 } … … 338 341 matpar->mantle_shear_modulus=this->mantle_shear_modulus; 339 342 matpar->mantle_density=this->mantle_density; 340 343 341 344 matpar->earth_density=this->earth_density; 342 345 … … 439 442 MARSHALLING(mantle_shear_modulus); 440 443 MARSHALLING(mantle_density); 441 444 442 445 //slr: 443 446 MARSHALLING(earth_density); -
issm/trunk/src/c/classes/Materials/Matpar.h
r22758 r23189 118 118 void ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");}; 119 119 void ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");}; 120 void ViscosityBFS(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not supported");}; 121 void ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");}; 122 void ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");}; 120 123 /*}}}*/ 121 124 /*Numerics: {{{*/ -
issm/trunk/src/c/classes/Misfit.cpp
r22758 r23189 23 23 #include "../classes/gauss/Gauss.h" 24 24 /*}}}*/ 25 25 26 26 /*Misfit constructors, destructors :*/ 27 27 Misfit::Misfit(){/*{{{*/ … … 42 42 43 43 this->definitionenum=in_definitionenum; 44 44 45 45 this->name = xNew<char>(strlen(in_name)+1); 46 46 xMemCpy<char>(this->name,in_name,strlen(in_name)+1); … … 48 48 this->timeinterpolation = xNew<char>(strlen(in_timeinterpolation)+1); 49 49 xMemCpy<char>(this->timeinterpolation,in_timeinterpolation,strlen(in_timeinterpolation)+1); 50 50 51 51 this->model_enum=in_model_enum; 52 52 this->observation_enum=in_observation_enum; 53 53 this->weights_enum=in_weights_enum; 54 54 this->local=in_local; 55 55 56 56 this->misfit=0; 57 57 this->lock=0; … … 111 111 /*}}}*/ 112 112 IssmDouble Misfit::Response(FemModel* femmodel){/*{{{*/ 113 113 114 114 /*diverse: */ 115 115 IssmDouble time,starttime,finaltime; 116 116 IssmDouble dt; 117 117 118 118 /*recover time parameters: */ 119 119 femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum); … … 130 130 IssmDouble all_area_t; 131 131 132 133 132 /*If we are locked, return time average: */ 134 133 if(this->lock)return misfit/(time-starttime); … … 144 143 area_t=all_area_t; 145 144 misfit_t=all_misfit_t; 146 145 147 146 /*Divide by surface area if not nill!: */ 148 147 if (area_t!=0) misfit_t=misfit_t/area_t; … … 164 163 IssmDouble* weights= NULL; 165 164 int msize,osize,wsize; 166 165 167 166 /*Are we transient?:*/ 168 167 if (time==0){ 169 168 IssmDouble misfit_t=0.; 170 169 171 170 /*get global vectors: */ 172 171 GetVectorFromInputsx(&model,&msize,femmodel,model_enum); … … 190 189 } 191 190 else{ 192 191 193 192 IssmDouble misfit_t=0.; 194 193 IssmDouble all_misfit_t=0.; … … 201 200 GetVectorFromInputsx(&observation,&osize,femmodel,observation_enum);_assert_(msize==osize); 202 201 GetVectorFromInputsx(&weights,&wsize,femmodel,weights_enum); _assert_(wsize==msize); 203 202 204 203 int count=0; 205 204 for (int i=0;i<msize;i++){ … … 215 214 /*Do we lock? i.e. are we at final_time? :*/ 216 215 if(time==finaltime)this->lock=1; 217 216 218 217 /*Free ressources:*/ 219 218 xDelete<IssmDouble>(model); … … 227 226 } /*}}}*/ 228 227 else{ /*global computation: {{{ */ 229 228 230 229 IssmDouble model, observation; 231 230 232 231 /*If we are locked, return time average: */ 233 232 if(this->lock)return misfit/(time-starttime); … … 239 238 Input* input = element->GetInput(observation_enum); _assert_(input); 240 239 input->GetInputAverage(&observation); 241 240 242 241 /*Add this time's contribution to curent misfit: */ 243 242 misfit+=dt*(model-observation); 244 243 245 244 /*Do we lock? i.e. are we at final_time? :*/ 246 245 if(time==finaltime)this->lock=1; 247 246 248 247 /*What we return is the value of misfit / time: */ 249 248 return misfit/(time-starttime); -
issm/trunk/src/c/classes/Nodalvalue.cpp
r22758 r23189 87 87 /*}}}*/ 88 88 IssmDouble Nodalvalue::Response(FemModel* femmodel){/*{{{*/ 89 89 90 90 /*output:*/ 91 91 IssmDouble value; -
issm/trunk/src/c/classes/Node.cpp
r21729 r23189 498 498 /*}}}*/ 499 499 void Node::SetApproximation(int in_approximation){/*{{{*/ 500 500 501 501 this->approximation = in_approximation; 502 502 } -
issm/trunk/src/c/classes/Nodes.cpp
r21341 r23189 349 349 ISSM_MPI_Allreduce((void*)&flag,(void*)&allflag,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm()); 350 350 351 if(allflag){ 352 return true; 353 } 354 else{ 355 return false; 356 } 357 } 358 /*}}}*/ 351 if(allflag) return true; 352 else return false; 353 } 354 /*}}}*/ -
issm/trunk/src/c/classes/Numberedcostfunction.cpp
r22758 r23189 8 8 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" 9 9 #endif 10 11 10 12 11 /*Headers:*/ … … 30 29 31 30 /*}}}*/ 32 31 33 32 /*Numberedcostfunction constructors, destructors :*/ 34 33 Numberedcostfunction::Numberedcostfunction(){/*{{{*/ … … 110 109 /*}}}*/ 111 110 IssmDouble Numberedcostfunction::Response(FemModel* femmodel){/*{{{*/ 112 111 113 112 _assert_(number_cost_functions>0 && number_cost_functions<1e3); 114 113 … … 157 156 } 158 157 /*}}}*/ 159 -
issm/trunk/src/c/classes/Params/BoolParam.cpp
r21341 r23189 63 63 } 64 64 /*}}}*/ 65 -
issm/trunk/src/c/classes/Params/DataSetParam.cpp
r22758 r23189 55 55 56 56 if(marshall_direction==MARSHALLING_BACKWARD)value=new DataSet(); 57 57 58 58 MARSHALLING_ENUM(DataSetParamEnum); 59 59 MARSHALLING(enum_type); -
issm/trunk/src/c/classes/Params/DoubleMatArrayParam.cpp
r21341 r23189 233 233 } 234 234 /*}}}*/ 235 -
issm/trunk/src/c/classes/Params/DoubleMatParam.cpp
r21341 r23189 116 116 /*DoubleMatParam specific routines:*/ 117 117 void DoubleMatParam::GetParameterValueByPointer(IssmDouble** pIssmDoublearray,int* pM,int* pN){/*{{{*/ 118 118 119 119 /*Assign output pointers:*/ 120 120 if(pM) *pM=M; -
issm/trunk/src/c/classes/Params/DoubleVecParam.cpp
r22758 r23189 116 116 /*DoubleVecParam specific routines:*/ 117 117 void DoubleVecParam::GetParameterValueByPointer(IssmDouble** pIssmDoublearray,int* pM){/*{{{*/ 118 118 119 119 /*Assign output pointers:*/ 120 120 if(pM) *pM=M; -
issm/trunk/src/c/classes/Params/IntParam.cpp
r21341 r23189 64 64 } 65 65 /*}}}*/ 66 -
issm/trunk/src/c/classes/Params/StringArrayParam.cpp
r22758 r23189 83 83 84 84 MARSHALLING_ENUM(StringArrayParamEnum); 85 85 86 86 MARSHALLING(enum_type); 87 87 MARSHALLING(numstrings); -
issm/trunk/src/c/classes/Params/StringParam.cpp
r22758 r23189 55 55 56 56 if(marshall_direction==MARSHALLING_FORWARD || marshall_direction == MARSHALLING_SIZE)size=strlen(value)+1; 57 57 58 58 MARSHALLING_ENUM(StringParamEnum); 59 59 MARSHALLING(enum_type); -
issm/trunk/src/c/classes/Profiler.cpp
r22758 r23189 100 100 if(this->running[tag]) _error_("Tag "<<tag<<" has not been stopped"); 101 101 102 103 102 #ifdef _HAVE_MPI_ 104 103 return this->time[tag]; … … 143 142 _assert_(tag<MAXIMUMSIZE); 144 143 if(this->running[tag]) _error_("Tag "<<tag<<" is already running"); 145 146 144 147 145 /*If mpisync requested, make sure all the cpus are at the same point in the execution: */ … … 184 182 if(!this->running[tag]) _error_("Tag "<<tag<<" is not running"); 185 183 186 187 184 /*If mpisync requested, make sure all the cpus are at the same point in the execution: */ 188 185 if(!dontmpisync){ -
issm/trunk/src/c/classes/Regionaloutput.cpp
r22758 r23189 155 155 } 156 156 /*}}}*/ 157 -
issm/trunk/src/c/classes/Vertex.cpp
r22822 r23189 20 20 } 21 21 /*}}}*/ 22 Vertex::Vertex(int vertex_id, int vertex_sid,int i, IoModel* iomodel){/*{{{*/22 Vertex::Vertex(int vertex_id, int vertex_sid,int vertex_lid,int i, IoModel* iomodel){/*{{{*/ 23 23 24 24 this->id = vertex_id; 25 25 this->sid = vertex_sid; 26 26 this->pid = UNDEF; 27 this->lid = vertex_lid; 27 28 28 29 _assert_(iomodel->Data("md.mesh.x") && iomodel->Data("md.mesh.y") && iomodel->Data("md.mesh.z")); … … 60 61 this->connectivity = iomodel->numbernodetoelementconnectivity[i]; 61 62 62 } 63 /*}}}*/ 63 }/*}}}*/ 64 64 Vertex::~Vertex(){/*{{{*/ 65 65 return; … … 84 84 _printf_(" sid: " << sid << "\n"); 85 85 _printf_(" pid: " << pid << "\n"); 86 _printf_(" lid: " << lid << "\n"); 86 87 _printf_(" x: " << x << "\n"); 87 88 _printf_(" y: " << y << "\n"); … … 104 105 MARSHALLING(sid); 105 106 MARSHALLING(pid); 107 MARSHALLING(lid); 106 108 MARSHALLING(x); 107 109 MARSHALLING(y); … … 113 115 /*}}}*/ 114 116 int Vertex::ObjectEnum(void){/*{{{*/ 115 116 117 return VertexEnum; 117 118 } 119 /*}}}*/ 118 }/*}}}*/ 120 119 121 120 /*Vertex management: */ … … 172 171 /*}}}*/ 173 172 int Vertex::Pid(void){ return pid; }/*{{{*/ 173 /*}}}*/ 174 int Vertex::Lid(void){ return lid; }/*{{{*/ 174 175 /*}}}*/ 175 176 void Vertex::SetClone(int* minranks){/*{{{*/ -
issm/trunk/src/c/classes/Vertex.h
r22822 r23189 25 25 int sid; // "serial" id (rank of this vertex if the dataset was on 1 cpu) 26 26 int pid; // "parallel" id 27 int lid; // "local" id 27 28 IssmDouble x; 28 29 IssmDouble y; … … 36 37 /*Vertex constructors, destructors {{{*/ 37 38 Vertex(); 38 Vertex(int id, int sid, 39 Vertex(int id, int sid,int lid,int i, IoModel* iomodel); 39 40 ~Vertex(); 40 41 /*}}}*/ … … 59 60 void OffsetPids(int pidcount); 60 61 int Pid(void); 62 int Lid(void); 61 63 void SetClone(int* minranks); 62 64 void ShowTruePids(int* borderpids); -
issm/trunk/src/c/classes/gauss/GaussSeg.cpp
r21341 r23189 31 31 this->numgauss = order; 32 32 GaussLegendreLinear(&pcoords1,&pweights,order); 33 33 34 34 this->coords1=xNew<IssmDouble>(numgauss); 35 35 this->weights=xNew<IssmDouble>(numgauss); -
issm/trunk/src/c/classes/kriging/Observations.cpp
r22758 r23189 741 741 xDelete<IssmPDouble>(counter); 742 742 }/*}}}*/ 743
Note:
See TracChangeset
for help on using the changeset viewer.