Changeset 22898
- Timestamp:
- 07/04/18 07:48:56 (7 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/HydrologyDCInefficientAnalysis.cpp
r22860 r22898 100 100 iomodel->FetchDataToInput(elements,"md.initialization.sediment_head",SedimentHeadHydrostepEnum); 101 101 iomodel->FetchDataToInput(elements,"md.hydrology.sediment_transmitivity",HydrologydcSedimentTransmitivityEnum); 102 iomodel->FetchDataToInput(elements,"md.hydrology.mask_thawed_node",HydrologydcMaskThawedNodeEnum); 102 103 if(iomodel->domaintype!=Domain2DhorizontalEnum){ 103 104 iomodel->FetchDataToInput(elements,"md.mesh.vertexonbase",MeshVertexonbaseEnum); … … 184 185 185 186 /*Intermediaries*/ 187 bool thawed_element; 186 188 int domaintype; 187 189 Element* basalelement; … … 199 201 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet"); 200 202 } 203 204 Input* thawed_element_input = basalelement->GetInput(HydrologydcMaskThawedEltEnum); _assert_(thawed_element_input); 205 thawed_element_input->GetInputValue(&thawed_element); 206 207 /*Check that all nodes are active, else return empty matrix*/ 208 if(!thawed_element) { 209 if(domaintype!=Domain2DhorizontalEnum){ 210 basalelement->DeleteMaterials(); 211 delete basalelement; 212 } 213 return NULL; 214 } 215 201 216 202 217 /*Intermediaries */ … … 297 312 298 313 /*Intermediaries*/ 299 int domaintype; 314 bool thawed_element; 315 int domaintype; 300 316 Element* basalelement; 301 317 … … 311 327 break; 312 328 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet"); 329 } 330 331 Input* thawed_element_input = basalelement->GetInput(HydrologydcMaskThawedEltEnum); _assert_(thawed_element_input); 332 thawed_element_input->GetInputValue(&thawed_element); 333 334 /*Check that all nodes are active, else return empty matrix*/ 335 if(!thawed_element) { 336 if(domaintype!=Domain2DhorizontalEnum){ 337 basalelement->DeleteMaterials(); 338 delete basalelement; 339 } 340 return NULL; 313 341 } 314 342 … … 626 654 _error_("UnconfinedFlag is 0 or 1"); 627 655 } 628 629 /*Let's deal with the frozen parts for which transmitivity is zero*/630 if (isthermal){631 element->GetInputValue(&meltingrate,gauss,BasalforcingsGroundediceMeltingRateEnum);632 element->GetInputValue(&groundedice,gauss,MaskGroundediceLevelsetEnum);633 if ((meltingrate<=0.0) && (groundedice>0)) sediment_transmitivity=0.;634 }635 636 656 return sediment_transmitivity; 637 657 }/*}}}*/ … … 738 758 } 739 759 }/*}}}*/ 760 761 void HydrologyDCInefficientAnalysis::HydrologyIDSGetMask(Vector<IssmDouble>* vec_mask, Element* element){ 762 bool active_element; 763 int domaintype; 764 Element* basalelement=NULL; 765 766 /*Get basal element*/ 767 element->FindParam(&domaintype,DomainTypeEnum); 768 switch(domaintype){ 769 case Domain2DhorizontalEnum: 770 basalelement = element; 771 break; 772 case Domain3DEnum: 773 if(!element->IsOnBase()) return; 774 basalelement = element->SpawnBasalElement(); 775 break; 776 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet"); 777 } 778 /*Intermediaries*/ 779 int numnodes = basalelement->GetNumberOfNodes(); 780 IssmDouble* meltingrate = xNew<IssmDouble>(numnodes); 781 IssmDouble* groundedice = xNew<IssmDouble>(numnodes); 782 783 basalelement->GetInputListOnVertices(&meltingrate[0],BasalforcingsGroundediceMeltingRateEnum); 784 basalelement->GetInputListOnVertices(&groundedice[0],MaskGroundediceLevelsetEnum); 785 786 /*if melting rate is not positive and node is not floating, deactivate*/ 787 for(int i=0;i<numnodes;i++){ 788 if ((meltingrate[i]<=0.0) && (groundedice[i]>0)){ 789 vec_mask->SetValue(basalelement->nodes[i]->Sid(),0.,INS_VAL); 790 } 791 else{ 792 vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL); 793 } 794 } 795 796 if(domaintype!=Domain2DhorizontalEnum){ 797 basalelement->DeleteMaterials(); 798 delete basalelement; 799 } 800 xDelete<IssmDouble>(meltingrate); 801 xDelete<IssmDouble>(groundedice); 802 } 803 void HydrologyDCInefficientAnalysis::ElementizeIdsMask(FemModel* femmodel){/*{{{*/ 804 805 bool element_active; 806 Element* element=NULL; 807 808 for(int i=0;i<femmodel->elements->Size();i++){ 809 element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 810 Input* node_mask_input = element->GetInput(HydrologydcMaskThawedNodeEnum); _assert_(node_mask_input); 811 812 if(node_mask_input->Max()>0.){ 813 element_active = true; 814 } 815 else{ 816 element_active = false; 817 } 818 element->AddInput(new BoolInput(HydrologydcMaskThawedEltEnum,element_active)); 819 } 820 }/*}}}*/ -
issm/trunk-jpl/src/c/analyses/HydrologyDCInefficientAnalysis.h
r21436 r22898 1 /*! \file HydrologyDCInefficientAnalysis.h 1 /*! \file HydrologyDCInefficientAnalysis.h 2 2 * \brief: header file for generic external result object 3 3 */ … … 8 8 /*Headers*/ 9 9 #include "./Analysis.h" 10 class Node; 10 class Node; 11 11 class Input; 12 12 class HydrologyDCInefficientAnalysis: public Analysis{ … … 40 40 IssmDouble GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_head_input); 41 41 void ElementizeEplMask(FemModel* femmodel); 42 void HydrologyIDSGetMask(Vector<IssmDouble>* vec_mask, Element* element); 43 void ElementizeIdsMask(FemModel* femmodel); 42 44 }; 43 45 #endif -
issm/trunk-jpl/src/c/classes/Elements/Element.cpp
r22873 r22898 2069 2069 name==HydrologydcEplThicknessHydrostepEnum || 2070 2070 name==HydrologydcMaskEplactiveNodeEnum || 2071 name==HydrologydcMaskThawedNodeEnum || 2071 2072 name==HydrologyHeadEnum || 2072 2073 name==HydrologyHeadOldEnum || -
issm/trunk-jpl/src/c/classes/FemModel.cpp
r22704 r22898 136 136 bool traceon=true; 137 137 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 138 139 /*Store the communicator, but do not set it as a global variable, as this has already 140 140 * been done by the FemModel that called this copy constructor: */ 141 141 IssmComm::SetComm(incomm); … … 152 152 this->amrbamg = NULL; 153 153 #endif 154 154 155 155 /*Save communicator in the parameters dataset: */ 156 156 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 182 182 if(parameters)delete parameters; 183 183 if(results)delete results; 184 184 185 185 #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_) 186 186 if(amr)delete amr; … … 206 206 /*First, recover the name of the restart file: */ 207 207 parameters->FindParam(&restartfilename,RestartFileNameEnum); 208 208 209 209 /*Open file for writing: */ 210 210 restartfid=pfopen(restartfilename,"wb"); … … 215 215 /*Create buffer to hold marshalled femmodel: */ 216 216 this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE); 217 femmodel_buffer=xNew<char>(femmodel_size); 217 femmodel_buffer=xNew<char>(femmodel_size); 218 218 /*Keep track of initial position of femmodel_buffer: */ 219 219 femmodel_buffer_ini=femmodel_buffer; 220 220 221 221 /*Marshall:*/ 222 222 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD); … … 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"); … … 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; … … 700 700 analyses_temp[numanalyses++]=EsaAnalysisEnum; 701 701 break; 702 702 703 703 case SealevelriseSolutionEnum: 704 704 analyses_temp[numanalyses++]=SealevelriseAnalysisEnum; … … 825 825 826 826 /*run solution core: */ 827 profiler->Start(CORE); 828 solutioncore(this); 827 profiler->Start(CORE); 828 solutioncore(this); 829 829 profiler->Stop(CORE); 830 830 831 831 /*run AD core if needed: */ 832 profiler->Start(ADCORE); 833 ad_core(this); 832 profiler->Start(ADCORE); 833 ad_core(this); 834 834 profiler->Stop(ADCORE); 835 835 … … 1121 1121 /*Broadcast and plug into response: */ 1122 1122 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()); 1123 ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 1124 1124 1125 1125 /*Assign output pointers: */ … … 1268 1268 num_segments = mdims_array[counter-1]; 1269 1269 1270 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1270 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1271 1271 * When we find one, use the element to compute the mass flux on the segment: */ 1272 1272 for(i=0;i<num_segments;i++){ … … 1315 1315 /*Figure out maximum across the cluster: */ 1316 1316 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()); 1317 ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1318 1318 maxabsvx=node_maxabsvx; 1319 1319 … … 1339 1339 /*Figure out maximum across the cluster: */ 1340 1340 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()); 1341 ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1342 1342 maxabsvy=node_maxabsvy; 1343 1343 … … 1363 1363 /*Figure out maximum across the cluster: */ 1364 1364 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()); 1365 ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1366 1366 maxabsvz=node_maxabsvz; 1367 1367 … … 1406 1406 /*Figure out maximum across the cluster: */ 1407 1407 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()); 1408 ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1409 1409 maxvel=node_maxvel; 1410 1410 … … 1430 1430 /*Figure out maximum across the cluster: */ 1431 1431 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()); 1432 ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1433 1433 maxvx=node_maxvx; 1434 1434 … … 1454 1454 /*Figure out maximum across the cluster: */ 1455 1455 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()); 1456 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1457 1457 maxvy=node_maxvy; 1458 1458 … … 1478 1478 /*Figure out maximum across the cluster: */ 1479 1479 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()); 1480 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1481 1481 maxvz=node_maxvz; 1482 1482 … … 1502 1502 /*Figure out minimum across the cluster: */ 1503 1503 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()); 1504 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1505 1505 minvel=node_minvel; 1506 1506 … … 1526 1526 /*Figure out minimum across the cluster: */ 1527 1527 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()); 1528 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1529 1529 minvx=node_minvx; 1530 1530 … … 1550 1550 /*Figure out minimum across the cluster: */ 1551 1551 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()); 1552 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1553 1553 minvy=node_minvy; 1554 1554 … … 1574 1574 /*Figure out minimum across the cluster: */ 1575 1575 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()); 1576 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1577 1577 minvz=node_minvz; 1578 1578 … … 1619 1619 omega_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 1620 1620 1621 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1621 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1622 1622 //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 1623 1623 J+=weight*1/2*pow(dp[0]*dp[0]+dp[1]*dp[1],2)*Jdet*gauss->weight; … … 1678 1678 omega0_input->GetInputValue(&p0,gauss); 1679 1679 1680 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1680 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1681 1681 //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 1682 1682 J+=weight*1/2*pow(p - p0,2)*Jdet*gauss->weight; … … 1902 1902 ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1903 1903 ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1904 1904 1905 1905 if(results_on_nodes){ 1906 1906 … … 1955 1955 IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols); 1956 1956 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols); 1957 1957 1958 1958 /*Fill-in matrix*/ 1959 1959 for(int j=0;j<elements->Size();j++){ … … 1964 1964 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1965 1965 xDelete<IssmDouble>(values); 1966 1966 1967 1967 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time)); 1968 1968 xDelete<IssmDouble>(allvalues); … … 2012 2012 int domaintype; 2013 2013 this->parameters->FindParam(&domaintype,DomainTypeEnum); 2014 2014 2015 2015 /*1: go throug all elements of this partition and figure out how many 2016 2016 * segments we have (corresopnding to levelset = 0)*/ … … 2132 2132 case VelEnum: this->ElementResponsex(responses,VelEnum); break; 2133 2133 case FrictionCoefficientEnum: NodalValuex(responses, FrictionCoefficientEnum,elements,nodes, vertices, loads, materials, parameters); break; 2134 default: 2134 default: 2135 2135 if(response_descriptor_enum>=Outputdefinition1Enum && response_descriptor_enum <=Outputdefinition100Enum){ 2136 2136 IssmDouble double_result = OutputDefinitionsResponsex(this,response_descriptor_enum); 2137 2137 *responses=double_result; 2138 2138 } 2139 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2140 break; 2139 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2140 break; 2141 2141 } 2142 2142 … … 2269 2269 thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 2270 2270 2271 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2271 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2272 2272 J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 2273 2273 } … … 2460 2460 analysis->UpdateConstraints(this); 2461 2461 delete analysis; 2462 2462 2463 2463 /*Second, constraints might be time dependent: */ 2464 SpcNodesx(nodes,constraints,parameters,analysis_type); 2464 SpcNodesx(nodes,constraints,parameters,analysis_type); 2465 2465 2466 2466 /*Now, update degrees of freedoms: */ … … 2473 2473 IssmDouble *surface = NULL; 2474 2474 IssmDouble *bed = NULL; 2475 2475 2476 2476 if(VerboseSolution()) _printf0_(" updating vertices positions\n"); 2477 2477 … … 2512 2512 2513 2513 /*AMR*/ 2514 #if !defined(_HAVE_ADOLC_) 2514 #if !defined(_HAVE_ADOLC_) 2515 2515 void FemModel::ReMesh(void){/*{{{*/ 2516 2516 … … 2522 2522 int newnumberofvertices = -1; 2523 2523 int newnumberofelements = -1; 2524 bool* my_elements = NULL; 2524 bool* my_elements = NULL; 2525 2525 int* my_vertices = NULL; 2526 2526 int elementswidth = this->GetElementsWidth();//just tria elements in this version … … 2528 2528 bool isgroundingline; 2529 2529 2530 /*Branch to specific amr depending on requested method*/ 2530 /*Branch to specific amr depending on requested method*/ 2531 2531 this->parameters->FindParam(&amrtype,AmrTypeEnum); 2532 2532 switch(amrtype){ … … 2541 2541 default: _error_("not implemented yet"); 2542 2542 } 2543 2543 2544 2544 /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/ 2545 2545 this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices); … … 2572 2572 2573 2573 /*As the domain is 2D, it is not necessary to create nodes for this analysis*/ 2574 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2574 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2575 2575 2576 2576 this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes); … … 2602 2602 //SetCurrentConfiguration(analysis_type); 2603 2603 2604 this->analysis_counter=i; 2604 this->analysis_counter=i; 2605 2605 /*Now, plug analysis_counter and analysis_type inside the parameters: */ 2606 2606 this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum); … … 2619 2619 2620 2620 ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters); 2621 if(i==0){ 2621 if(i==0){ 2622 2622 VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices 2623 2623 } … … 2663 2663 /*Insert bedrock from mismip+ setup*/ 2664 2664 /*This was used to Misomip project/simulations*/ 2665 2665 2666 2666 if(VerboseSolution())_printf0_(" call Mismip bedrock adjust module\n"); 2667 2667 … … 2680 2680 by = 500./(1.+exp((-2./4000.)*(y-80000./2.-24000.)))+500./(1.+exp((2./4000.)*(y-80000./2.+24000.))); 2681 2681 r[i] = max(bx+by,-720.); 2682 } 2682 } 2683 2683 /*insert new bedrock*/ 2684 2684 element->AddInput(BedEnum,&r[0],P1Enum); … … 2693 2693 2694 2694 if(VerboseSolution())_printf0_(" call adjust base and thickness module\n"); 2695 2695 2696 2696 int numvertices = this->GetElementsWidth(); 2697 2697 IssmDouble rho_water,rho_ice,density,base_float; … … 2705 2705 for(int el=0;el<this->elements->Size();el++){ 2706 2706 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el)); 2707 2707 2708 2708 element->GetInputListOnVertices(&s[0],SurfaceEnum); 2709 2709 element->GetInputListOnVertices(&r[0],BedEnum); … … 2717 2717 base_float = rho_ice*s[i]/(rho_ice-rho_water); 2718 2718 if(r[i]>base_float){ 2719 b[i] = r[i]; 2720 } 2719 b[i] = r[i]; 2720 } 2721 2721 else { 2722 b[i] = base_float; 2723 } 2722 b[i] = base_float; 2723 } 2724 2724 2725 2725 if(fabs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!"); 2726 2726 /*update thickness and mask grounded ice level set*/ 2727 2727 h[i] = s[i]-b[i]; 2728 phi[i] = h[i]+r[i]/density; 2728 phi[i] = h[i]+r[i]/density; 2729 2729 } 2730 2730 … … 2734 2734 element->AddInput(BaseEnum,&b[0],P1Enum); 2735 2735 } 2736 2736 2737 2737 /*Delete*/ 2738 2738 xDelete<IssmDouble>(phi); … … 2762 2762 Vector<IssmDouble>* input_interpolations = NULL; 2763 2763 IssmDouble* input_interpolations_serial = NULL; 2764 int* pos = NULL; 2764 int* pos = NULL; 2765 2765 IssmDouble value = 0; 2766 2766 … … 2782 2782 P0input_interp = xNew<int>(numP0inputs); 2783 2783 P1input_enums = xNew<int>(numP1inputs); 2784 P1input_interp = xNew<int>(numP1inputs); 2784 P1input_interp = xNew<int>(numP1inputs); 2785 2785 } 2786 2786 numP0inputs = 0; … … 2814 2814 } 2815 2815 } 2816 2817 /*Get P0 and P1 inputs over the elements*/ 2816 2817 /*Get P0 and P1 inputs over the elements*/ 2818 2818 pos = xNew<int>(elementswidth); 2819 2819 vP0inputs= new Vector<IssmDouble>(numberofelements*numP0inputs); … … 2821 2821 for(int i=0;i<this->elements->Size();i++){ 2822 2822 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2823 2823 2824 2824 /*Get P0 inputs*/ 2825 2825 for(int j=0;j<numP0inputs;j++){ 2826 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2826 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2827 2827 input->GetInputAverage(&value); 2828 2828 pos[0]=element->Sid()*numP0inputs+j; 2829 /*Insert input in the vector*/ 2829 /*Insert input in the vector*/ 2830 2830 vP0inputs->SetValues(1,pos,&value,INS_VAL); 2831 2831 } 2832 2832 2833 2833 /*Get P1 inputs*/ 2834 2834 for(int j=0;j<numP1inputs;j++){ … … 2837 2837 pos[1]=element->vertices[1]->Sid()*numP1inputs+j; 2838 2838 pos[2]=element->vertices[2]->Sid()*numP1inputs+j; 2839 /*Insert input in the vector*/ 2840 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2839 /*Insert input in the vector*/ 2840 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2841 2841 } 2842 2842 } … … 2847 2847 P0inputs=vP0inputs->ToMPISerial(); 2848 2848 P1inputs=vP1inputs->ToMPISerial(); 2849 2849 2850 2850 /*Assign pointers*/ 2851 *pnumP0inputs = numP0inputs; 2852 *pP0inputs = P0inputs; 2851 *pnumP0inputs = numP0inputs; 2852 *pP0inputs = P0inputs; 2853 2853 *pP0input_enums = P0input_enums; 2854 2854 *pP0input_interp = P0input_interp; 2855 *pnumP1inputs = numP1inputs; 2856 *pP1inputs = P1inputs; 2855 *pnumP1inputs = numP1inputs; 2856 *pP1inputs = P1inputs; 2857 2857 *pP1input_enums = P1input_enums; 2858 *pP1input_interp = P1input_interp; 2858 *pP1input_interp = P1input_interp; 2859 2859 2860 2860 /*Cleanup*/ … … 2867 2867 /*}}}*/ 2868 2868 void FemModel::InterpolateInputs(Vertices* newfemmodel_vertices,Elements* newfemmodel_elements){/*{{{*/ 2869 2869 2870 2870 int numberofelements = this->elements->NumberOfElements(); //global, entire old mesh 2871 2871 int newnumberofelements = newfemmodel_elements->Size(); //just on the new partition … … 2883 2883 int* P1input_enums = NULL; 2884 2884 int* P1input_interp = NULL; 2885 IssmDouble* values = NULL; 2885 IssmDouble* values = NULL; 2886 2886 IssmDouble* vector = NULL; 2887 2887 IssmDouble* x = NULL;//global, entire old mesh … … 2895 2895 IssmDouble* newyc = NULL;//just on the new partition 2896 2896 int* newelementslist = NULL;//just on the new partition 2897 int* sidtoindex = NULL;//global vertices sid to partition index 2897 int* sidtoindex = NULL;//global vertices sid to partition index 2898 2898 2899 2899 /*Get old P0 and P1 inputs (entire mesh)*/ … … 2928 2928 2929 2929 /*Insert P0 and P1 inputs into the new elements (just on the new partition)*/ 2930 values=xNew<IssmDouble>(elementswidth); 2930 values=xNew<IssmDouble>(elementswidth); 2931 2931 for(int i=0;i<newfemmodel_elements->Size();i++){//just on the new partition 2932 2932 Element* element=xDynamicCast<Element*>(newfemmodel_elements->GetObjectByOffset(i)); 2933 2933 /*newP0inputs is just on the new partition*/ 2934 2934 for(int j=0;j<numP0inputs;j++){ 2935 switch(P0input_interp[j]){ 2935 switch(P0input_interp[j]){ 2936 2936 case P0Enum: 2937 2937 case DoubleInputEnum: 2938 2938 element->AddInput(new DoubleInput(P0input_enums[j],newP0inputs[i*numP0inputs+j])); 2939 2939 break; 2940 case IntInputEnum: 2940 case IntInputEnum: 2941 2941 element->AddInput(new IntInput(P0input_enums[j],reCast<int>(newP0inputs[i*numP0inputs+j]))); 2942 2942 break; … … 2956 2956 } 2957 2957 } 2958 2958 2959 2959 /*Cleanup*/ 2960 2960 xDelete<IssmDouble>(P0inputs); … … 2995 2995 2996 2996 if(!this->elements || !this->vertices || !this->results || !this->parameters) return; 2997 2997 2998 2998 parameters->FindParam(&step,StepEnum); 2999 2999 parameters->FindParam(&time,TimeEnum); … … 3013 3013 this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum, 3014 3014 y,numberofvertices,1,step,time)); 3015 3015 3016 3016 /*Cleanup*/ 3017 3017 xDelete<IssmDouble>(x); … … 3074 3074 /*Assemble*/ 3075 3075 vmasklevelset->Assemble(); 3076 3076 3077 3077 /*Serialize and set output*/ 3078 3078 (*pmasklevelset)=vmasklevelset->ToMPISerial(); … … 3088 3088 3089 3089 /*newelementslist is in Matlab indexing*/ 3090 3090 3091 3091 /*Creating connectivity table*/ 3092 3092 int* connectivity=NULL; … … 3099 3099 connectivity[vertexid-1]+=1;//Matlab to C indexing 3100 3100 } 3101 } 3101 } 3102 3102 3103 3103 /*Create vertex and insert in vertices*/ 3104 3104 for(int i=0;i<newnumberofvertices;i++){ 3105 3105 if(my_vertices[i]){ 3106 Vertex *newvertex=new Vertex(); 3106 Vertex *newvertex=new Vertex(); 3107 3107 newvertex->id=i+1; 3108 3108 newvertex->sid=i; … … 3115 3115 newvertex->connectivity=connectivity[i]; 3116 3116 newvertex->clone=false;//itapopo check this 3117 vertices->AddObject(newvertex); 3118 } 3117 vertices->AddObject(newvertex); 3118 } 3119 3119 } 3120 3120 … … 3143 3143 } 3144 3144 else newtria->element_type_list=NULL; 3145 3145 3146 3146 /*Element hook*/ 3147 3147 int matpar_id=newnumberofelements+1; //retrieve material parameter id (last pointer in femodel->materials) … … 3149 3149 /*retrieve vertices ids*/ 3150 3150 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 3151 for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 3152 3152 /*Setting the hooks*/ 3153 3153 newtria->numanalyses =this->nummodels; … … 3161 3161 /*Clean up*/ 3162 3162 xDelete<int>(vertex_ids); 3163 elements->AddObject(newtria); 3164 } 3163 elements->AddObject(newtria); 3164 } 3165 3165 } 3166 3166 … … 3172 3172 for(int i=0;i<newnumberofelements;i++){ 3173 3173 if(my_elements[i]){ 3174 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3175 } 3176 } 3177 3174 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3175 } 3176 } 3177 3178 3178 /*Add new constant material property to materials, at the end: */ 3179 3179 Matpar *newmatpar=static_cast<Matpar*>(this->materials->GetObjectByOffset(this->materials->Size()-1)->copy()); 3180 3180 newmatpar->SetMid(newnumberofelements+1); 3181 materials->AddObject(newmatpar);//put it at the end of the materials 3181 materials->AddObject(newmatpar);//put it at the end of the materials 3182 3182 } 3183 3183 /*}}}*/ … … 3186 3186 int lid=0; 3187 3187 for(int j=0;j<newnumberofvertices;j++){ 3188 if(my_vertices[j]){ 3189 3190 Node* newnode=new Node(); 3191 3188 if(my_vertices[j]){ 3189 3190 Node* newnode=new Node(); 3191 3192 3192 /*id: */ 3193 3193 newnode->id=nodecounter+j+1; … … 3195 3195 newnode->lid=lid++; 3196 3196 newnode->analysis_enum=analysis_enum; 3197 3197 3198 3198 /*Initialize coord_system: Identity matrix by default*/ 3199 3199 for(int k=0;k<3;k++) for(int l=0;l<3;l++) newnode->coord_system[k][l]=0.0; 3200 3200 for(int k=0;k<3;k++) newnode->coord_system[k][k]=1.0; 3201 3201 3202 3202 /*indexing:*/ 3203 3203 newnode->indexingupdate=true; 3204 3204 3205 3205 Analysis* analysis=EnumToAnalysis(analysis_enum); 3206 3206 int *doftypes=NULL; … … 3216 3216 /*Stressbalance Horiz*/ 3217 3217 if(analysis_enum==StressbalanceAnalysisEnum){ 3218 // itapopo this code is rarely used. 3218 // itapopo this code is rarely used. 3219 3219 /*Coordinate system provided, convert to coord_system matrix*/ 3220 3220 //XZvectorsToCoordinateSystem(&this->coord_system[0][0],&iomodel->Data(StressbalanceReferentialEnum)[j*6]); … … 3231 3231 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3232 3232 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3233 3233 3234 3234 int numberofvertices = femmodel_vertices->NumberOfVertices(); 3235 3235 int numberofelements = femmodel_elements->NumberOfElements(); … … 3237 3237 IssmDouble* x = NULL; 3238 3238 IssmDouble* y = NULL; 3239 IssmDouble* z = NULL; 3239 IssmDouble* z = NULL; 3240 3240 int* elementslist = NULL; 3241 3241 int* elem_vertices = NULL; … … 3246 3246 /*Get vertices coordinates*/ 3247 3247 VertexCoordinatesx(&x,&y,&z,femmodel_vertices,false) ; 3248 3248 3249 3249 /*Get element vertices*/ 3250 3250 elem_vertices = xNew<int>(elementswidth); … … 3261 3261 vid3->SetValue(element->sid,elem_vertices[2],INS_VAL); 3262 3262 } 3263 3263 3264 3264 /*Assemble*/ 3265 3265 vid1->Assemble(); … … 3271 3271 id2 = vid2->ToMPISerial(); 3272 3272 id3 = vid3->ToMPISerial(); 3273 3273 3274 3274 /*Construct elements list*/ 3275 3275 elementslist=xNew<int>(numberofelements*elementswidth); … … 3280 3280 elementslist[elementswidth*i+2] = reCast<int>(id3[i])+1; //InterpMesh wants Matlab indexing 3281 3281 } 3282 3282 3283 3283 /*Assign pointers*/ 3284 3284 *px = x; … … 3301 3301 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3302 3302 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3303 3303 3304 3304 int numberofvertices = femmodel_vertices->Size(); //number of vertices of this partition 3305 3305 int numbertotalofvertices = femmodel_vertices->NumberOfVertices(); //number total of vertices (entire mesh) … … 3308 3308 IssmDouble* x = NULL; 3309 3309 IssmDouble* y = NULL; 3310 IssmDouble* z = NULL; 3310 IssmDouble* z = NULL; 3311 3311 int* elementslist = NULL; 3312 3312 int* sidtoindex = NULL; 3313 3313 int* elem_vertices = NULL; 3314 3314 3315 3315 /*Get vertices coordinates of this partition*/ 3316 3316 sidtoindex = xNewZeroInit<int>(numbertotalofvertices);//entire mesh, all vertices … … 3318 3318 y = xNew<IssmDouble>(numberofvertices);//just this partitio; 3319 3319 z = xNew<IssmDouble>(numberofvertices);//just this partitio; 3320 3320 3321 3321 /*Go through in this partition (vertices)*/ 3322 3322 for(int i=0;i<numberofvertices;i++){//just this partition 3323 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3323 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3324 3324 /*Attention: no spherical coordinates*/ 3325 3325 x[i]=vertex->GetX(); … … 3334 3334 elementslist = xNew<int>(numberofelements*elementswidth); 3335 3335 if(numberofelements*elementswidth<0) _error_("numberofelements negative."); 3336 3336 3337 3337 for(int i=0;i<numberofelements;i++){//just this partition 3338 3338 Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i)); … … 3341 3341 elementslist[elementswidth*i+1] = sidtoindex[elem_vertices[1]]+1; //InterpMesh wants Matlab indexing 3342 3342 elementslist[elementswidth*i+2] = sidtoindex[elem_vertices[2]]+1; //InterpMesh wants Matlab indexing 3343 } 3344 3343 } 3344 3345 3345 /*Assign pointers*/ 3346 3346 *px = x; … … 3348 3348 *pz = z; 3349 3349 *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type. 3350 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3350 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3351 3351 3352 3352 /*Cleanup*/ … … 3359 3359 /*OTHERS CONSTRAINTS MUST BE IMPLEMENTED*/ 3360 3360 if(analysis_enum!=StressbalanceAnalysisEnum) return; 3361 3361 3362 3362 int numberofnodes_analysistype= this->nodes->NumberOfNodes(analysis_enum); 3363 int dofpernode = 2; //vx and vy 3363 int dofpernode = 2; //vx and vy 3364 3364 int numberofcols = dofpernode*2; //to keep dofs and flags in the vspc vector 3365 3365 int numberofvertices = this->vertices->NumberOfVertices(); //global, entire old mesh … … 3385 3385 newy=xNew<IssmDouble>(newnumberofvertices);//just the new partition 3386 3386 for(int i=0;i<newnumberofvertices;i++){//just the new partition 3387 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3387 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3388 3388 /*Attention: no spherical coordinates*/ 3389 3389 newx[i]=vertex->GetX(); … … 3393 3393 /*Get spcvx and spcvy of old mesh*/ 3394 3394 for(int i=0;i<this->constraints->Size();i++){ 3395 3395 3396 3396 Constraint* constraint=(Constraint*)constraints->GetObjectByOffset(i); 3397 3397 if(!constraint->InAnalysis(analysis_enum)) _error_("AMR create constraints for "<<EnumToStringx(analysis_enum)<<" not supported yet!\n"); … … 3400 3400 int dof = spcstatic->GetDof(); 3401 3401 int node = spcstatic->GetNodeId(); 3402 IssmDouble spcvalue = spcstatic->GetValue(); 3402 IssmDouble spcvalue = spcstatic->GetValue(); 3403 3403 int nodeindex = node-1; 3404 3404 3405 3405 /*vx and vx flag insertion*/ 3406 3406 if(dof==0) {//vx 3407 3407 vspc->SetValue(nodeindex*numberofcols,spcvalue,INS_VAL); //vx 3408 3408 vspc->SetValue(nodeindex*numberofcols+dofpernode,1,INS_VAL);//vxflag 3409 } 3409 } 3410 3410 /*vy and vy flag insertion*/ 3411 3411 if(dof==1){//vy … … 3423 3423 spc,numberofvertices,numberofcols, 3424 3424 newx,newy,newnumberofvertices,NULL); 3425 3425 3426 3426 /*Now, insert the interpolated constraints in the data set (constraints)*/ 3427 3427 count=0; … … 3440 3440 /*spcvy*/ 3441 3441 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)); 3442 newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 3443 3443 //add count'th spc, on node i+1, setting dof 1 to vx. 3444 3444 count++; … … 3497 3497 bool *my_elements = NULL; 3498 3498 int *my_vertices = NULL; 3499 3500 _assert_(newnumberofvertices>0); 3501 _assert_(newnumberofelements>0); 3499 3500 _assert_(newnumberofvertices>0); 3501 _assert_(newnumberofelements>0); 3502 3502 epart=xNew<int>(newnumberofelements); 3503 3503 npart=xNew<int>(newnumberofvertices); 3504 3504 index=xNew<int>(elementswidth*newnumberofelements); 3505 3505 3506 3506 for (int i=0;i<newnumberofelements;i++){ 3507 3507 for (int j=0;j<elementswidth;j++){ … … 3523 3523 for (int i=0;i<newnumberofvertices;i++) npart[i]=0; 3524 3524 } 3525 else _error_("At least one processor is required"); 3525 else _error_("At least one processor is required"); 3526 3526 3527 3527 my_vertices=xNew<int>(newnumberofvertices); … … 3533 3533 for(int i=0;i<newnumberofelements;i++){ 3534 3534 /*!All elements have been partitioned above, only deal with elements for this cpu: */ 3535 if(my_rank==epart[i]){ 3535 if(my_rank==epart[i]){ 3536 3536 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 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 3540 3540 will hold which vertices belong to this partition*/ 3541 3541 for(int j=0;j<elementswidth;j++){ 3542 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3542 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3543 3543 my_vertices[newelementslist[elementswidth*i+j]-1]=1;//newelementslist is in Matlab indexing 3544 3544 } … … 3552 3552 /*Free ressources:*/ 3553 3553 xDelete<int>(epart); 3554 xDelete<int>(npart); 3554 xDelete<int>(npart); 3555 3555 xDelete<int>(index); 3556 3556 } 3557 3557 /*}}}*/ 3558 3558 void FemModel::SmoothedDeviatoricStressTensor(IssmDouble** ptauxx,IssmDouble** ptauyy,IssmDouble** ptauxy){/*{{{*/ 3559 3559 3560 3560 int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements 3561 3561 int numberofvertices = this->vertices->NumberOfVertices(); 3562 3562 IssmDouble weight = 0.; 3563 IssmDouble* tauxx = NULL; 3564 IssmDouble* tauyy = NULL; 3565 IssmDouble* tauxy = NULL; 3563 IssmDouble* tauxx = NULL; 3564 IssmDouble* tauyy = NULL; 3565 IssmDouble* tauxy = NULL; 3566 3566 IssmDouble* totalweight = NULL; 3567 3567 IssmDouble* deviatoricstressxx = xNew<IssmDouble>(elementswidth); … … 3573 3573 Vector<IssmDouble>* vectauxy = new Vector<IssmDouble>(numberofvertices); 3574 3574 Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices); 3575 3575 3576 3576 /*Update the Deviatoric Stress tensor over the elements*/ 3577 3577 this->DeviatoricStressx(); 3578 3578 3579 3579 /*Calculate the Smoothed Deviatoric Stress tensor*/ 3580 3580 for(int i=0;i<this->elements->Size();i++){ … … 3621 3621 /*Divide for the total weight*/ 3622 3622 for(int i=0;i<numberofvertices;i++){ 3623 _assert_(totalweight[i]>0); 3623 _assert_(totalweight[i]>0); 3624 3624 tauxx[i] = tauxx[i]/totalweight[i]; 3625 3625 tauyy[i] = tauyy[i]/totalweight[i]; … … 3646 3646 void FemModel::ZZErrorEstimator(IssmDouble** pelementerror){/*{{{*/ 3647 3647 3648 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3648 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3649 3649 * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/ 3650 3650 … … 3666 3666 /*Get smoothed deviatoric stress tensor*/ 3667 3667 this->SmoothedDeviatoricStressTensor(&smoothedtauxx,&smoothedtauyy,&smoothedtauxy); 3668 3668 3669 3669 /*Integrate the error over elements*/ 3670 3670 for(int i=0;i<this->elements->Size();i++){ … … 3674 3674 element->GetInputListOnVertices(tauxy,DeviatoricStressxyEnum); 3675 3675 element->GetVerticesSidList(elem_vertices); 3676 3676 3677 3677 /*Integrate*/ 3678 3678 element->GetVerticesCoordinates(&xyz_list); … … 3689 3689 ftxy+=(tauxy[n]-smoothedtauxy[elem_vertices[n]])*basis[n]; 3690 3690 } 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*/ 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*/ 3694 3694 sid=element->Sid(); 3695 3695 error = sqrt(error);//sqrt(e^2) … … 3705 3705 /*Serialize and set output*/ 3706 3706 (*pelementerror)=velementerror->ToMPISerial(); 3707 3707 3708 3708 /*Cleanup*/ 3709 3709 xDelete<IssmDouble>(smoothedtauxx); … … 3749 3749 Tria* triaelement = xDynamicCast<Tria*>(element); 3750 3750 weight = triaelement->GetArea();//the tria area is a choice for the weight 3751 3751 3752 3752 /*dH/dx*/ 3753 3753 vecdHdx->SetValue(elem_vertices[0],weight*GradH[0],ADD_VAL); … … 3817 3817 /*Get smoothed deviatoric stress tensor*/ 3818 3818 this->SmoothedGradThickness(&smoothed_dHdx,&smoothed_dHdy); 3819 3819 3820 3820 /*Integrate the error over elements*/ 3821 3821 for(int i=0;i<this->elements->Size();i++){ … … 3903 3903 IssmDouble* x = NULL; 3904 3904 IssmDouble* y = NULL; 3905 IssmDouble* z = NULL; 3905 IssmDouble* z = NULL; 3906 3906 IssmDouble* xyz_list = NULL; 3907 3907 IssmDouble x1,y1,x2,y2,x3,y3; … … 3912 3912 //element->GetVerticesSidList(elem_vertices); 3913 3913 int sid = element->Sid(); 3914 element->GetVerticesCoordinates(&xyz_list); 3914 element->GetVerticesCoordinates(&xyz_list); 3915 3915 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3916 3916 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 3945 3945 _error_("level set type not implemented yet!"); 3946 3946 } 3947 3947 3948 3948 /*Outputs*/ 3949 3949 IssmDouble* zerolevelset_points = NULL; 3950 3950 int npoints = 0; 3951 3951 3952 3952 /*Intermediaries*/ 3953 3953 int elementswidth = this->GetElementsWidth(); … … 3962 3962 int count,sid; 3963 3963 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 3964 3964 3965 3965 /*Use the element center coordinate if level set is zero (grounding line or ice front), otherwise set NAN*/ 3966 3966 for(int i=0;i<this->elements->Size();i++){ … … 3969 3969 element->GetVerticesSidList(elem_vertices); 3970 3970 sid= element->Sid(); 3971 element->GetVerticesCoordinates(&xyz_list); 3971 element->GetVerticesCoordinates(&xyz_list); 3972 3972 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3973 3973 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; 3974 3974 x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1]; 3975 3975 xc = NAN; 3976 yc = NAN; 3976 yc = NAN; 3977 3977 Tria* tria = xDynamicCast<Tria*>(element); 3978 3978 if(tria->IsIceInElement()){/*verify if there is ice in the element*/ 3979 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3979 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3980 3980 abs(levelset[0]*levelset[1])<DBL_EPSILON || abs(levelset[0]*levelset[2])<DBL_EPSILON) { 3981 3981 xc=(x1+x2+x3)/3.; … … 4007 4007 } 4008 4008 } 4009 4009 4010 4010 /*Assign outputs*/ 4011 4011 numberofpoints = npoints; … … 4047 4047 responses_pointer=d_responses; 4048 4048 4049 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4049 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4050 4050 //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 4051 … … 4140 4140 4141 4141 int ns,nsmax; 4142 4142 4143 4143 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4144 4144 ns = elements->Size(); 4145 4145 4146 4146 /*Figure out max of ns: */ 4147 4147 ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); … … 4162 4162 } 4163 4163 } 4164 4164 4165 4165 /*One last time: */ 4166 4166 pUp->Assemble(); … … 4181 4181 4182 4182 int ns,nsmax; 4183 4183 4184 4184 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4185 4185 ns = elements->Size(); 4186 4187 /*First, figure out the surface area of Earth: */ 4186 4187 /*First, figure out the surface area of Earth: */ 4188 4188 for(int i=0;i<ns;i++){ 4189 4189 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4209 4209 } 4210 4210 } 4211 4211 4212 4212 /*One last time: */ 4213 4213 pUp->Assemble(); … … 4237 4237 IssmDouble eartharea_cpu = 0.; 4238 4238 int ns,nsmax; 4239 4239 4240 4240 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4241 4241 ns = elements->Size(); … … 4261 4261 for(int i=0;i<nsmax;i++){ 4262 4262 if(i<ns){ 4263 4263 4264 4264 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4265 4265 4266 4266 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4267 4267 element->SealevelriseEustatic(pSgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea); … … 4271 4271 } 4272 4272 if(VerboseConvergence())_printf0_("\n"); 4273 4273 4274 4274 /*One last time: */ 4275 4275 pSgi->Assemble(); … … 4289 4289 /*serialized vectors:*/ 4290 4290 IssmDouble* Sg_old=NULL; 4291 4291 4292 4292 IssmDouble eartharea=0; 4293 4293 IssmDouble eartharea_cpu=0; 4294 4294 4295 4295 int ns,nsmax; 4296 4296 4297 4297 /*Serialize vectors from previous iteration:*/ 4298 4298 Sg_old=pSg_old->ToMPISerial(); … … 4306 4306 eartharea_cpu += element->GetAreaSpherical(); 4307 4307 } 4308 4308 4309 4309 ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4310 4310 ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); … … 4324 4324 } 4325 4325 if(verboseconvolution)if(VerboseConvergence())_printf_("\n"); 4326 4326 4327 4327 /*Free ressources:*/ 4328 4328 xDelete<IssmDouble>(Sg_old); … … 4336 4336 IssmDouble eartharea_cpu=0; 4337 4337 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; 4338 IssmDouble load_love_k2 = -0.30922675; //degree 2 load Love number 4339 IssmDouble m1, m2, m3; 4340 IssmDouble lati, longi, radi, value; 4341 4341 4342 4342 /*Serialize vectors from previous iteration:*/ … … 4351 4351 ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4352 4352 4353 IssmDouble moi_list[3]={0,0,0}; 4354 IssmDouble moi_list_cpu[3]={0,0,0}; 4353 IssmDouble moi_list[3]={0,0,0}; 4354 IssmDouble moi_list_cpu[3]={0,0,0}; 4355 4355 for(int i=0;i<elements->Size();i++){ 4356 4356 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4357 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]; 4358 moi_list_cpu[0] += moi_list[0]; 4359 moi_list_cpu[1] += moi_list[1]; 4360 moi_list_cpu[2] += moi_list[2]; 4361 4361 } 4362 4362 ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4363 4363 ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4364 // 4364 // 4365 4365 ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4366 4366 ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4367 // 4367 // 4368 4368 ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4369 4369 ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4370 4370 4371 4371 /*pull out some useful parameters: */ 4372 4372 parameters->FindParam(&tide_love_h,SealevelriseTidalLoveHEnum); … … 4378 4378 4379 4379 /*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 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 4383 4383 4384 4384 /* 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] 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] 4388 4388 */ 4389 4389 for(int i=0;i<vertices->Size();i++){ … … 4395 4395 lati=latitude[sid]/180*PI; longi=longitude[sid]/180*PI; radi=radius[sid]; 4396 4396 4397 /*only first order terms are considered now: */ 4397 /*only first order terms are considered now: */ 4398 4398 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 4399 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 4400 4401 4401 pSgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times 4402 4402 } … … 4404 4404 /*Assemble mesh velocity*/ 4405 4405 pSgo_rot->Assemble(); 4406 4406 4407 4407 /*Assign output pointers:*/ 4408 4408 *pIxz=moi_list[0]; … … 4412 4412 /*Free ressources:*/ 4413 4413 xDelete<IssmDouble>(Sg_old); 4414 4414 4415 4415 } 4416 4416 /*}}}*/ … … 4419 4419 /*serialized vectors:*/ 4420 4420 IssmDouble* Sg=NULL; 4421 4421 4422 4422 IssmDouble eartharea=0; 4423 4423 IssmDouble eartharea_cpu=0; 4424 4424 4425 4425 int ns,nsmax; 4426 4426 4427 4427 /*Serialize vectors from previous iteration:*/ 4428 4428 Sg=pSg->ToMPISerial(); … … 4430 4430 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4431 4431 ns = elements->Size(); 4432 4432 4433 4433 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ 4434 4434 for(int i=0;i<ns;i++){ … … 4455 4455 } 4456 4456 } 4457 4457 4458 4458 /*One last time: */ 4459 4459 pUp->Assemble(); … … 4492 4492 ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4493 4493 ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4494 4494 4495 4495 ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4496 4496 ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); … … 4498 4498 /*Free ressources:*/ 4499 4499 xDelete<IssmDouble>(Sg_serial); 4500 4500 4501 4501 return oceanvalue/oceanarea; 4502 4502 } … … 4514 4514 int* eplzigzag_counter = NULL; 4515 4515 int eplflip_lock; 4516 4516 4517 4517 HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis(); 4518 4518 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); … … 4521 4521 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4522 4522 recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4523 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4524 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4523 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4524 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4525 4525 GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum); 4526 4526 4527 4527 for (int i=0;i<elements->Size();i++){ 4528 4528 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4542 4542 /*Assemble and serialize*/ 4543 4543 mask->Assemble(); 4544 serial_mask=mask->ToMPISerial(); 4545 4544 serial_mask=mask->ToMPISerial(); 4545 4546 4546 xDelete<int>(eplzigzag_counter); 4547 4547 xDelete<IssmDouble>(serial_rec); … … 4585 4585 int sum_counter; 4586 4586 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()); 4587 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4588 4588 counter=sum_counter; 4589 4589 *pEplcount = counter; 4590 4590 if(VerboseSolution()) _printf0_(" Number of active nodes in EPL layer: "<< counter <<"\n"); 4591 4592 /*Update dof indexings*/ 4593 this->UpdateConstraintsx(); 4594 4595 } 4596 /*}}}*/ 4597 void FemModel::HydrologyIDSupdateDomainx(IssmDouble* pIDScount){ /*{{{*/ 4598 4599 bool isthermal; 4600 Vector<IssmDouble>* mask = NULL; 4601 IssmDouble* serial_mask = NULL; 4602 4603 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); 4604 parameters->FindParam(&isthermal,TransientIsthermalEnum); 4605 4606 /*When solving a thermal model we update the thawed nodes*/ 4607 if(isthermal){ 4608 /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/ 4609 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum)); 4610 4611 for (int i=0;i<elements->Size();i++){ 4612 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4613 inefanalysis->HydrologyIDSGetMask(mask,element); 4614 } 4615 /*Assemble and serialize*/ 4616 mask->Assemble(); 4617 serial_mask=mask->ToMPISerial(); 4618 delete mask; 4619 } 4620 /*for other cases we just grab the mask from the initialisation value*/ 4621 else{ 4622 GetVectorFromInputsx(&serial_mask,this,HydrologydcMaskThawedNodeEnum,NodeSIdEnum); 4623 } 4624 /*Update node activation accordingly*/ 4625 int counter =0; 4626 for (int i=0;i<nodes->Size();i++){ 4627 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i)); 4628 if(node->InAnalysis(HydrologyDCInefficientAnalysisEnum)){ 4629 if(serial_mask[node->Sid()]==1.){ 4630 node->Activate(); 4631 if(!node->IsClone()) counter++; 4632 } 4633 else{ 4634 node->Deactivate(); 4635 } 4636 } 4637 } 4638 4639 /*Update Mask*/ 4640 InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskThawedNodeEnum,NodeSIdEnum); 4641 xDelete<IssmDouble>(serial_mask); 4642 inefanalysis->ElementizeIdsMask(this); 4643 4644 int sum_counter; 4645 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4646 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4647 counter=sum_counter; 4648 *pIDScount = counter; 4649 if(VerboseSolution()) _printf0_(" Number of active nodes in IDS layer: "<< counter <<"\n"); 4591 4650 4592 4651 /*Update dof indexings*/ … … 4631 4690 int sum_counter; 4632 4691 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()); 4692 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4634 4693 counter=sum_counter; 4635 4694 *pL2count = counter; … … 4716 4775 } 4717 4776 /*}}}*/ 4718 #ifdef _HAVE_JAVASCRIPT_ 4777 #ifdef _HAVE_JAVASCRIPT_ 4719 4778 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/ 4720 4779 /*configuration: */ … … 4731 4790 /*From command line arguments, retrieve different filenames needed to create the FemModel: */ 4732 4791 solution_type=StringToEnumx(solution); 4733 4792 4734 4793 /*Create femmodel from input files: */ 4735 4794 profiler->Start(MPROCESSOR); 4736 4795 this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL); 4737 4796 profiler->Stop(MPROCESSOR); 4738 4797 4739 4798 /*Save communicator in the parameters dataset: */ 4740 4799 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 4751 4810 size_t* poutputbuffersize; 4752 4811 4753 4812 4754 4813 /*Before we delete the profiler, report statistics for this run: */ 4755 4814 profiler->Stop(TOTAL); //final tagging … … 4764 4823 ); 4765 4824 _printf0_("\n"); 4766 4825 4767 4826 /*Before we close the output file, recover the buffer and size:*/ 4768 4827 outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum)); … … 4804 4863 4805 4864 /*Open output file once for all and add output file descriptor to parameters*/ 4806 output_fid=open_memstream(&outputbuffer,&outputsize); 4865 output_fid=open_memstream(&outputbuffer,&outputsize); 4807 4866 if(output_fid==NULL)_error_("could not initialize output stream"); 4808 4867 this->parameters->SetParam(output_fid,OutputFilePointerEnum); … … 4845 4904 /*Initialize hmaxvertices with NAN*/ 4846 4905 hmaxvertices_serial=xNew<IssmDouble>(numberofvertices); 4847 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4906 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4848 4907 /*Fill hmaxvertices*/ 4849 4908 if(this->amrbamg->groundingline_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskGroundediceLevelsetEnum); … … 4852 4911 if(this->amrbamg->deviatoricerror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum); 4853 4912 } 4854 4913 4855 4914 if(my_rank==0){ 4856 4915 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); … … 4872 4931 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 4873 4932 } 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()); 4933 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4934 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4935 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4936 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4878 4937 4879 4938 /*Assign output pointers*/ … … 4908 4967 /*Create bamg data structures for bamg*/ 4909 4968 this->amrbamg = new AmrBamg(); 4910 4969 4911 4970 /*Get amr parameters*/ 4912 4971 this->parameters->FindParam(&hmin,AmrHminEnum); … … 4932 4991 4933 4992 /*Re-create original mesh and put it in bamg structure (only cpu 0)*/ 4934 if(my_rank==0){ 4993 if(my_rank==0){ 4935 4994 this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements); 4936 4995 } … … 4946 5005 4947 5006 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 4948 5007 4949 5008 /*Intermediaries*/ 4950 5009 int numberofvertices = this->vertices->NumberOfVertices(); … … 4953 5012 4954 5013 switch(levelset_type){ 4955 case MaskGroundediceLevelsetEnum: 5014 case MaskGroundediceLevelsetEnum: 4956 5015 threshold = this->amrbamg->groundingline_distance; 4957 5016 resolution = this->amrbamg->groundingline_resolution; … … 4967 5026 this->GetVerticeDistanceToZeroLevelSet(&verticedistance,levelset_type); 4968 5027 if(!verticedistance) _error_("verticedistance is NULL!\n"); 4969 5028 4970 5029 /*Fill hmaxVertices*/ 4971 5030 for(int i=0;i<numberofvertices;i++){ … … 4981 5040 /*}}}*/ 4982 5041 void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/ 4983 5042 4984 5043 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 4985 5044 … … 4989 5048 int numberofvertices = this->vertices->NumberOfVertices(); 4990 5049 IssmDouble* maxlength = xNew<IssmDouble>(numberofelements); 4991 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 5050 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 4992 5051 IssmDouble* error_elements = NULL; 4993 5052 IssmDouble* x = NULL; … … 5002 5061 /*Fill variables*/ 5003 5062 switch(errorestimator_type){ 5004 case ThicknessErrorEstimatorEnum: 5063 case ThicknessErrorEstimatorEnum: 5005 5064 threshold = this->amrbamg->thicknesserror_threshold; 5006 5065 groupthreshold = this->amrbamg->thicknesserror_groupthreshold; … … 5027 5086 case ThicknessErrorEstimatorEnum: this->amrbamg->thicknesserror_maximum = maxerror;break; 5028 5087 case DeviatoricStressErrorEstimatorEnum: this->amrbamg->deviatoricerror_maximum = maxerror;break; 5029 } 5088 } 5030 5089 } 5031 5090 5032 5091 /*Get mesh*/ 5033 5092 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&index); 5034 5093 5035 5094 /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/ 5036 5095 for(int i=0;i<numberofelements;i++){ … … 5046 5105 error_vertices[v2]+=error_elements[i]; 5047 5106 error_vertices[v3]+=error_elements[i]; 5048 } 5107 } 5049 5108 5050 5109 /*Fill hmaxvertices with the criteria*/ … … 5060 5119 } 5061 5120 } 5062 /*Now, fill the hmaxvertices if requested*/ 5121 /*Now, fill the hmaxvertices if requested*/ 5063 5122 if(refine){ 5064 5123 for(int j=0;j<elementswidth;j++){ … … 5090 5149 /*Output*/ 5091 5150 IssmDouble* verticedistance; 5092 5151 5093 5152 /*Intermediaries*/ 5094 5153 int numberofvertices = this->vertices->NumberOfVertices(); … … 5102 5161 /*Get vertices coordinates*/ 5103 5162 VertexCoordinatesx(&x,&y,&z,this->vertices,false) ; 5104 5105 /*Get points which level set is zero (center of elements with zero level set)*/ 5163 5164 /*Get points which level set is zero (center of elements with zero level set)*/ 5106 5165 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5107 5166 … … 5112 5171 for(int j=0;j<numberofpoints;j++){ 5113 5172 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 } 5173 verticedistance[i]=min(distance,verticedistance[i]); 5174 } 5175 } 5117 5176 5118 5177 /*Assign the pointer*/ … … 5148 5207 if(this->amr->groundingline_distance>0) this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskGroundediceLevelsetEnum); 5149 5208 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 5209 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5210 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5211 5153 5212 if(my_rank==0){ 5154 5213 this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror, 5155 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5214 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5156 5215 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 5157 5216 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the ReMeshNeopz."); … … 5167 5226 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 5168 5227 } 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*/ 5228 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5229 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5230 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5231 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5232 5233 /*Assign the pointers*/ 5175 5234 (*pnewelementslist) = newelementslist; //Matlab indexing 5176 5235 (*pnewx) = newx; … … 5188 5247 /*}}}*/ 5189 5248 void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/ 5190 5249 5191 5250 /*Define variables*/ 5192 5251 int my_rank = IssmComm::GetRank(); … … 5197 5256 IssmDouble* z = NULL; 5198 5257 int* elements = NULL; 5199 5258 5200 5259 /*Initialize field as NULL for now*/ 5201 5260 this->amr = NULL; … … 5205 5264 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements); 5206 5265 5207 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5266 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5208 5267 /*Just CPU #0 should keep AMR object*/ 5209 5268 /*Initialize refinement pattern*/ 5210 5269 this->SetRefPatterns(); 5211 5270 this->amr = new AdaptiveMeshRefinement(); 5212 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5271 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5213 5272 /*Get amr parameters*/ 5214 5273 this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum); … … 5223 5282 this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum); 5224 5283 this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum); 5225 if(my_rank==0){ 5284 if(my_rank==0){ 5226 5285 this->amr->CreateInitialMesh(numberofvertices,numberofelements,x,y,elements); 5227 5286 } … … 5244 5303 /*Output*/ 5245 5304 IssmDouble* elementdistance; 5246 5305 5247 5306 /*Intermediaries*/ 5248 5307 int numberofelements = this->elements->NumberOfElements(); … … 5253 5312 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 5254 5313 int numberofpoints; 5255 5256 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5314 5315 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5257 5316 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5258 5317 … … 5260 5319 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 5261 5320 int sid = element->Sid(); 5262 element->GetVerticesCoordinates(&xyz_list); 5321 element->GetVerticesCoordinates(&xyz_list); 5263 5322 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 5264 5323 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 5270 5329 for(int j=0;j<numberofpoints;j++){ 5271 5330 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); 5331 mindistance=min(distance,mindistance); 5273 5332 } 5274 5333 velementdistance->SetValue(sid,mindistance,INS_VAL); 5275 5334 xDelete<IssmDouble>(xyz_list); 5276 } 5335 } 5277 5336 5278 5337 /*Assemble*/ -
issm/trunk-jpl/src/c/classes/FemModel.h
r22418 r22898 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(); … … 135 135 #endif 136 136 #ifdef _HAVE_ESA_ 137 void EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pX, Vector<IssmDouble>* pY, IssmDouble* xx, IssmDouble* yy); 138 void EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz); 137 void EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pX, Vector<IssmDouble>* pY, IssmDouble* xx, IssmDouble* yy); 138 void EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz); 139 139 #endif 140 140 #ifdef _HAVE_SEALEVELRISE_ … … 142 142 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution); 143 143 void SealevelriseRotationalFeedback(Vector<IssmDouble>* pSgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius); 144 void SealevelriseGeodetic(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); 144 void SealevelriseGeodetic(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); 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-jpl/src/c/cores/hydrology_core.cpp
r22856 r22898 13 13 14 14 /*intermediary*/ 15 int hydrology_model; 16 int solution_type; 17 int numoutputs=0; 18 bool save_results; 19 bool modify_loads=true; 20 char **requested_outputs = NULL; 15 int hydrology_model; 16 int solution_type; 17 int numoutputs = 0; 18 bool save_results; 19 bool modify_loads = true; 20 char **requested_outputs = NULL; 21 IssmDouble ThawedNodes; 21 22 22 23 /*first recover parameters common to all solutions*/ … … 45 46 else if (hydrology_model==HydrologydcEnum){ 46 47 /*intermediary: */ 47 bool isefficientlayer; 48 int step,hydroslices; 49 IssmDouble time,init_time,hydrotime,yts; 50 IssmDouble dt,hydrodt; 48 bool isefficientlayer; 49 bool isthermal; 50 int step,hydroslices; 51 IssmDouble time,init_time,hydrotime,yts; 52 IssmDouble dt,hydrodt; 51 53 52 54 femmodel->parameters->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum); … … 57 59 femmodel->parameters->FindParam(&yts,ConstantsYtsEnum); 58 60 59 init_time = time-dt; //getting the time back to the start of the timestep 60 hydrotime=init_time; 61 hydrodt=dt/hydroslices; //computing hydro dt from dt and a divider 62 femmodel->parameters->AddObject(new DoubleParam(HydrologydtEnum,hydrodt)); 63 if(hydroslices>1){ 64 /*define which variable needs to be averaged on the sub-timestep and initialize as needed*/ 65 if (isefficientlayer){ 66 int inputtostack[4]={EffectivePressureHydrostepEnum,SedimentHeadHydrostepEnum,EplHeadHydrostepEnum,HydrologydcEplThicknessHydrostepEnum}; 67 int stackedinput[4]={EffectivePressureStackedEnum,SedimentHeadStackedEnum,EplHeadStackedEnum,HydrologydcEplThicknessStackedEnum}; 68 int averagedinput[4]={EffectivePressureEnum,SedimentHeadEnum,EplHeadEnum,HydrologydcEplThicknessEnum}; 69 femmodel->InitTransientOutputx(&stackedinput[0],4); 70 while(hydrotime<time-(yts*DBL_EPSILON)){ //loop on hydro dts 71 hydrotime+=hydrodt; 72 /*save preceding timestep*/ 73 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum); 61 femmodel->parameters->FindParam(&isthermal,TransientIsthermalEnum); 62 /*first we exclude frozen nodes of the solved nodes*/ 63 femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum); 64 femmodel->HydrologyIDSupdateDomainx(&ThawedNodes); 65 if(ThawedNodes>0){ 66 init_time = time-dt; //getting the time back to the start of the timestep 67 hydrotime=init_time; 68 hydrodt=dt/hydroslices; //computing hydro dt from dt and a divider 69 femmodel->parameters->AddObject(new DoubleParam(HydrologydtEnum,hydrodt)); 70 if(hydroslices>1){ 71 /*define which variable needs to be averaged on the sub-timestep and initialize as needed*/ 72 if (isefficientlayer){ 73 int inputtostack[4]={EffectivePressureHydrostepEnum,SedimentHeadHydrostepEnum,EplHeadHydrostepEnum,HydrologydcEplThicknessHydrostepEnum}; 74 int stackedinput[4]={EffectivePressureStackedEnum,SedimentHeadStackedEnum,EplHeadStackedEnum,HydrologydcEplThicknessStackedEnum}; 75 int averagedinput[4]={EffectivePressureEnum,SedimentHeadEnum,EplHeadEnum,HydrologydcEplThicknessEnum}; 76 femmodel->InitTransientOutputx(&stackedinput[0],4); 77 while(hydrotime<time-(yts*DBL_EPSILON)){ //loop on hydro dts 78 hydrotime+=hydrodt; 79 /*save preceding timestep*/ 80 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum); 81 InputDuplicatex(femmodel,EplHeadHydrostepEnum,EplHeadOldEnum); 82 InputDuplicatex(femmodel,HydrologydcEplThicknessHydrostepEnum,HydrologydcEplThicknessOldEnum); 83 /*Proceed now to heads computations*/ 84 solutionsequence_hydro_nonlinear(femmodel); 85 /*If we have a sub-timestep we stack the variables here*/ 86 femmodel->StackTransientOutputx(&inputtostack[0],&stackedinput[0],hydrotime,4); 87 } 88 femmodel->AverageTransientOutputx(&stackedinput[0],&averagedinput[0],init_time,4); 89 } 90 else{ 91 int inputtostack[2]={EffectivePressureHydrostepEnum,SedimentHeadHydrostepEnum}; 92 int stackedinput[2]={EffectivePressureStackedEnum,SedimentHeadStackedEnum}; 93 int averagedinput[2]={EffectivePressureEnum,SedimentHeadEnum}; 94 femmodel->InitTransientOutputx(&stackedinput[0],2); 95 while(hydrotime<time-(yts*DBL_EPSILON)){ //loop on hydro dts 96 hydrotime+=hydrodt; 97 /*save preceding timestep*/ 98 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum); 99 /*Proceed now to heads computations*/ 100 solutionsequence_hydro_nonlinear(femmodel); 101 /*If we have a sub-timestep we stack the variables here*/ 102 femmodel->StackTransientOutputx(&inputtostack[0],&stackedinput[0],hydrotime,2); 103 } 104 femmodel->AverageTransientOutputx(&stackedinput[0],&averagedinput[0],init_time,2); 105 } 106 } 107 else{ 108 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum); 109 if (isefficientlayer){ 74 110 InputDuplicatex(femmodel,EplHeadHydrostepEnum,EplHeadOldEnum); 75 111 InputDuplicatex(femmodel,HydrologydcEplThicknessHydrostepEnum,HydrologydcEplThicknessOldEnum); 76 /*Proceed now to heads computations*/77 solutionsequence_hydro_nonlinear(femmodel);78 /*If we have a sub-timestep we stack the variables here*/79 femmodel->StackTransientOutputx(&inputtostack[0],&stackedinput[0],hydrotime,4);80 112 } 81 femmodel->AverageTransientOutputx(&stackedinput[0],&averagedinput[0],init_time,4); 113 /*Proceed now to heads computations*/ 114 solutionsequence_hydro_nonlinear(femmodel); 82 115 } 83 else{84 int inputtostack[2]={EffectivePressureHydrostepEnum,SedimentHeadHydrostepEnum};85 int stackedinput[2]={EffectivePressureStackedEnum,SedimentHeadStackedEnum};86 int averagedinput[2]={EffectivePressureEnum,SedimentHeadEnum};87 femmodel->InitTransientOutputx(&stackedinput[0],2);88 while(hydrotime<time-(yts*DBL_EPSILON)){ //loop on hydro dts89 hydrotime+=hydrodt;90 /*save preceding timestep*/91 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum);92 /*Proceed now to heads computations*/93 solutionsequence_hydro_nonlinear(femmodel);94 /*If we have a sub-timestep we stack the variables here*/95 femmodel->StackTransientOutputx(&inputtostack[0],&stackedinput[0],hydrotime,2);96 }97 femmodel->AverageTransientOutputx(&stackedinput[0],&averagedinput[0],init_time,2);98 }99 }100 else{101 InputDuplicatex(femmodel,SedimentHeadHydrostepEnum,SedimentHeadOldEnum);102 if (isefficientlayer){103 InputDuplicatex(femmodel,EplHeadHydrostepEnum,EplHeadOldEnum);104 InputDuplicatex(femmodel,HydrologydcEplThicknessHydrostepEnum,HydrologydcEplThicknessOldEnum);105 }106 /*Proceed now to heads computations*/107 solutionsequence_hydro_nonlinear(femmodel);108 116 } 109 117 } 110 118 else if (hydrology_model==HydrologysommersEnum){ 111 119 femmodel->SetCurrentConfiguration(HydrologySommersAnalysisEnum); 112 120 InputDuplicatex(femmodel,HydrologyHeadEnum,HydrologyHeadOldEnum); 113 121 solutionsequence_shakti_nonlinear(femmodel); 114 122 if(VerboseSolution()) _printf0_(" updating gap height\n"); … … 122 130 if(save_results){ 123 131 if(VerboseSolution()) _printf0_(" saving results \n"); 124 femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs); 132 if(hydrology_model==HydrologydcEnum && ThawedNodes==0){ 133 if(VerboseSolution()) _printf0_(" No thawed node hydro is skiped \n");} 134 else{ 135 femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs); 136 } 125 137 } 126 138 /*Free ressources:*/ -
issm/trunk-jpl/src/c/cores/transient_core.cpp
r22848 r22898 1 1 /*!\file: transient_3d_core.cpp 2 * \brief: core of the transient_3d solution 3 */ 2 * \brief: core of the transient_3d solution 3 */ 4 4 5 5 #ifdef HAVE_CONFIG_H … … 142 142 InterpFromMeshToMesh2dx(&base_oceangrid,index_ice,lon_ice,lat_ice,ngrids_ice,nels_ice, 143 143 icebase,ngrids_ice,1, 144 oceangridx,oceangridy,ngrids_ocean,options); 144 oceangridx,oceangridy,ngrids_ocean,options); 145 145 delete options; 146 146 … … 239 239 int ngrids_ice=femmodel->vertices->NumberOfVertices(); 240 240 int nels_ice=femmodel->elements->NumberOfElements(); 241 241 242 242 /*Recover mesh and inputs needed*/ 243 243 femmodel->parameters->FindParam(&rho_ice,MaterialsRhoIceEnum); … … 253 253 InterpFromMeshToMesh2dx(&base_oceangrid,index_ice,lon_ice,lat_ice,ngrids_ice,nels_ice, 254 254 icebase,ngrids_ice,1, 255 oceangridx,oceangridy,ngrids_ocean,NULL); 256 255 oceangridx,oceangridy,ngrids_ocean,NULL); 256 257 257 /*Send and receive data*/ 258 258 ISSM_MPI_Send(&time,1,ISSM_MPI_DOUBLE,0,10001001,tomitgcmcomm); … … 267 267 InterpFromMeshToMesh2dx(&melt_mesh,index_ocean,oceangridx,oceangridy,ngrids_ocean,nels_ocean, 268 268 oceanmelt,ngrids_ocean,1, 269 lon_ice,lat_ice,ngrids_ice,NULL); 269 lon_ice,lat_ice,ngrids_ice,NULL); 270 270 271 271 for(int i=0;i<ngrids_ice;i++) melt_mesh[i]=-melt_mesh[i]/rho_ice; //heat flux provided by ocean is in kg/m^2/s … … 293 293 /*}}}*/ 294 294 295 if(isthermal && domaintype==Domain3DEnum){ 295 if(isthermal && domaintype==Domain3DEnum){ 296 296 if(issmb){ 297 297 bool isenthalpy; … … 327 327 femmodel->UpdateVertexPositionsx(); 328 328 } 329 329 330 330 if(isgroundingline){ 331 331 if(VerboseSolution()) _printf0_(" computing new grounding line position\n"); … … 338 338 femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum); 339 339 extrudefrombase_core(femmodel); 340 340 341 341 if(save_results){ 342 342 int outputs[3] = {SurfaceEnum,BaseEnum,MaskGroundediceLevelsetEnum}; … … 356 356 /*esa: */ 357 357 if(isesa) esa_core(femmodel); 358 358 359 359 /*Sea level rise: */ 360 360 if(isslr || iscoupler) sealevelrise_core(femmodel); … … 367 367 femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1,save_results); 368 368 } 369 369 370 370 if(save_results){ 371 371 if(VerboseSolution()) _printf0_(" saving temporary results\n"); … … 402 402 } 403 403 } 404 404 405 405 if(!iscontrol || !isautodiff) femmodel->RequestedDependentsx(); 406 406 if(iscontrol && isautodiff) femmodel->parameters->SetParam(dependent_objects,AutodiffDependentObjectsEnum); 407 407 408 /*Free ressources:*/ 408 /*Free ressources:*/ 409 409 if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);} 410 410 } -
issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
r22856 r22898 441 441 HydrologydcMaskEplactiveEltEnum, 442 442 HydrologydcMaskEplactiveNodeEnum, 443 HydrologydcMaskThawedEltEnum, 444 HydrologydcMaskThawedNodeEnum, 443 445 HydrologydcSedimentTransmitivityEnum, 444 446 HydrologyEnglacialInputEnum, -
issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
r22856 r22898 447 447 case HydrologydcMaskEplactiveEltEnum : return "HydrologydcMaskEplactiveElt"; 448 448 case HydrologydcMaskEplactiveNodeEnum : return "HydrologydcMaskEplactiveNode"; 449 case HydrologydcMaskThawedEltEnum : return "HydrologydcMaskThawedElt"; 450 case HydrologydcMaskThawedNodeEnum : return "HydrologydcMaskThawedNode"; 449 451 case HydrologydcSedimentTransmitivityEnum : return "HydrologydcSedimentTransmitivity"; 450 452 case HydrologyEnglacialInputEnum : return "HydrologyEnglacialInput"; -
issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
r22856 r22898 456 456 else if (strcmp(name,"HydrologydcMaskEplactiveElt")==0) return HydrologydcMaskEplactiveEltEnum; 457 457 else if (strcmp(name,"HydrologydcMaskEplactiveNode")==0) return HydrologydcMaskEplactiveNodeEnum; 458 else if (strcmp(name,"HydrologydcMaskThawedElt")==0) return HydrologydcMaskThawedEltEnum; 459 else if (strcmp(name,"HydrologydcMaskThawedNode")==0) return HydrologydcMaskThawedNodeEnum; 458 460 else if (strcmp(name,"HydrologydcSedimentTransmitivity")==0) return HydrologydcSedimentTransmitivityEnum; 459 461 else if (strcmp(name,"HydrologyEnglacialInput")==0) return HydrologyEnglacialInputEnum; … … 504 506 else if (strcmp(name,"Pressure")==0) return PressureEnum; 505 507 else if (strcmp(name,"RheologyBAbsGradient")==0) return RheologyBAbsGradientEnum; 506 else if (strcmp(name,"RheologyBbarAbsGradient")==0) return RheologyBbarAbsGradientEnum;507 else if (strcmp(name,"Sealevel")==0) return SealevelEnum;508 508 else stage=5; 509 509 } 510 510 if(stage==5){ 511 if (strcmp(name,"SealevelriseDeltathickness")==0) return SealevelriseDeltathicknessEnum; 511 if (strcmp(name,"RheologyBbarAbsGradient")==0) return RheologyBbarAbsGradientEnum; 512 else if (strcmp(name,"Sealevel")==0) return SealevelEnum; 513 else if (strcmp(name,"SealevelriseDeltathickness")==0) return SealevelriseDeltathicknessEnum; 512 514 else if (strcmp(name,"SedimentHeadHydrostep")==0) return SedimentHeadHydrostepEnum; 513 515 else if (strcmp(name,"SedimentHeadOld")==0) return SedimentHeadOldEnum; … … 627 629 else if (strcmp(name,"VzMesh")==0) return VzMeshEnum; 628 630 else if (strcmp(name,"VzSSA")==0) return VzSSAEnum; 629 else if (strcmp(name,"Watercolumn")==0) return WatercolumnEnum;630 else if (strcmp(name,"WaterColumnOld")==0) return WaterColumnOldEnum;631 631 else stage=6; 632 632 } 633 633 if(stage==6){ 634 if (strcmp(name,"WaterfractionDrainage")==0) return WaterfractionDrainageEnum; 634 if (strcmp(name,"Watercolumn")==0) return WatercolumnEnum; 635 else if (strcmp(name,"WaterColumnOld")==0) return WaterColumnOldEnum; 636 else if (strcmp(name,"WaterfractionDrainage")==0) return WaterfractionDrainageEnum; 635 637 else if (strcmp(name,"WaterfractionDrainageIntegrated")==0) return WaterfractionDrainageIntegratedEnum; 636 638 else if (strcmp(name,"Waterfraction")==0) return WaterfractionEnum; … … 750 752 else if (strcmp(name,"FSpressure")==0) return FSpressureEnum; 751 753 else if (strcmp(name,"FSSolver")==0) return FSSolverEnum; 752 else if (strcmp(name,"FSvelocity")==0) return FSvelocityEnum;753 else if (strcmp(name,"GaussPenta")==0) return GaussPentaEnum;754 754 else stage=7; 755 755 } 756 756 if(stage==7){ 757 if (strcmp(name,"GaussSeg")==0) return GaussSegEnum; 757 if (strcmp(name,"FSvelocity")==0) return FSvelocityEnum; 758 else if (strcmp(name,"GaussPenta")==0) return GaussPentaEnum; 759 else if (strcmp(name,"GaussSeg")==0) return GaussSegEnum; 758 760 else if (strcmp(name,"GaussTetra")==0) return GaussTetraEnum; 759 761 else if (strcmp(name,"GaussTria")==0) return GaussTriaEnum; … … 873 875 else if (strcmp(name,"MaxAbsVz")==0) return MaxAbsVzEnum; 874 876 else if (strcmp(name,"MaxDivergence")==0) return MaxDivergenceEnum; 875 else if (strcmp(name,"MaxVel")==0) return MaxVelEnum;876 else if (strcmp(name,"MaxVx")==0) return MaxVxEnum;877 877 else stage=8; 878 878 } 879 879 if(stage==8){ 880 if (strcmp(name,"MaxVy")==0) return MaxVyEnum; 880 if (strcmp(name,"MaxVel")==0) return MaxVelEnum; 881 else if (strcmp(name,"MaxVx")==0) return MaxVxEnum; 882 else if (strcmp(name,"MaxVy")==0) return MaxVyEnum; 881 883 else if (strcmp(name,"MaxVz")==0) return MaxVzEnum; 882 884 else if (strcmp(name,"Melange")==0) return MelangeEnum; … … 996 998 else if (strcmp(name,"Outputdefinition88")==0) return Outputdefinition88Enum; 997 999 else if (strcmp(name,"Outputdefinition89")==0) return Outputdefinition89Enum; 998 else if (strcmp(name,"Outputdefinition8")==0) return Outputdefinition8Enum;999 else if (strcmp(name,"Outputdefinition90")==0) return Outputdefinition90Enum;1000 1000 else stage=9; 1001 1001 } 1002 1002 if(stage==9){ 1003 if (strcmp(name,"Outputdefinition91")==0) return Outputdefinition91Enum; 1003 if (strcmp(name,"Outputdefinition8")==0) return Outputdefinition8Enum; 1004 else if (strcmp(name,"Outputdefinition90")==0) return Outputdefinition90Enum; 1005 else if (strcmp(name,"Outputdefinition91")==0) return Outputdefinition91Enum; 1004 1006 else if (strcmp(name,"Outputdefinition92")==0) return Outputdefinition92Enum; 1005 1007 else if (strcmp(name,"Outputdefinition93")==0) return Outputdefinition93Enum; … … 1119 1121 else if (strcmp(name,"TotalSmbScaled")==0) return TotalSmbScaledEnum; 1120 1122 else if (strcmp(name,"TransientArrayParam")==0) return TransientArrayParamEnum; 1121 else if (strcmp(name,"TransientInput")==0) return TransientInputEnum;1122 else if (strcmp(name,"TransientParam")==0) return TransientParamEnum;1123 1123 else stage=10; 1124 1124 } 1125 1125 if(stage==10){ 1126 if (strcmp(name,"TransientSolution")==0) return TransientSolutionEnum; 1126 if (strcmp(name,"TransientInput")==0) return TransientInputEnum; 1127 else if (strcmp(name,"TransientParam")==0) return TransientParamEnum; 1128 else if (strcmp(name,"TransientSolution")==0) return TransientSolutionEnum; 1127 1129 else if (strcmp(name,"Tria")==0) return TriaEnum; 1128 1130 else if (strcmp(name,"TriaInput")==0) return TriaInputEnum; -
issm/trunk-jpl/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp
r22551 r22898 1 1 /*!\file: solutionsequence_hydro_nonlinear.cpp 2 * \brief: core of the hydro solution 3 */ 2 * \brief: core of the hydro solution 3 */ 4 4 5 5 #include "../toolkits/toolkits.h" … … 12 12 void solutionsequence_hydro_nonlinear(FemModel* femmodel){ 13 13 /*solution : */ 14 Vector<IssmDouble>* ug_sed=NULL; 15 Vector<IssmDouble>* uf_sed=NULL; 16 Vector<IssmDouble>* uf_sed_sub_iter=NULL; 14 Vector<IssmDouble>* ug_sed=NULL; 15 Vector<IssmDouble>* uf_sed=NULL; 16 Vector<IssmDouble>* uf_sed_sub_iter=NULL; 17 17 Vector<IssmDouble>* ug_sed_main_iter=NULL; 18 18 19 Vector<IssmDouble>* ug_epl=NULL; 19 Vector<IssmDouble>* ug_epl=NULL; 20 20 Vector<IssmDouble>* uf_epl=NULL; 21 Vector<IssmDouble>* uf_epl_sub_iter=NULL; 21 Vector<IssmDouble>* uf_epl_sub_iter=NULL; 22 22 Vector<IssmDouble>* ug_epl_sub_iter=NULL; 23 23 Vector<IssmDouble>* ug_epl_main_iter=NULL; 24 24 25 Vector<IssmDouble>* ys=NULL; 25 Vector<IssmDouble>* ys=NULL; 26 26 Vector<IssmDouble>* dug=NULL; 27 27 Vector<IssmDouble>* duf=NULL; … … 35 35 HydrologyDCInefficientAnalysis* inefanalysis = NULL; 36 36 HydrologyDCEfficientAnalysis* effanalysis = NULL; 37 37 38 38 bool sedconverged,eplconverged,hydroconverged; 39 39 bool isefficientlayer; … … 58 58 59 59 /*Retrieve inputs as the initial state for the non linear iteration*/ 60 GetSolutionFromInputsx(&ug_sed,femmodel); 60 GetSolutionFromInputsx(&ug_sed,femmodel); 61 61 Reducevectorgtofx(&uf_sed, ug_sed, femmodel->nodes,femmodel->parameters); 62 /*Initialize the thawed element mask*/ 62 63 if(isefficientlayer) { 63 64 inefanalysis = new HydrologyDCInefficientAnalysis(); … … 87 88 InputUpdateFromConstantx(femmodel,false,ConvergedEnum); 88 89 femmodel->UpdateConstraintsx(); 89 90 90 91 /*Reset constraint on the ZigZag Lock*/ 91 92 ResetConstraintsx(femmodel); … … 126 127 if(sedconverged)break; 127 128 } 128 129 129 130 /*}}}*//*End of the sediment penalization loop*/ 130 131 sedconverged=false; 131 132 132 133 /*Checking convegence on the value of the sediment head*/ 133 134 duf=uf_sed_sub_iter->Duplicate();_assert_(duf); … … 184 185 inefanalysis->ElementizeEplMask(femmodel); 185 186 /*}}}*/ 186 187 187 188 if(VerboseSolution()) _printf0_("Building EPL Matrix...\n"); 188 189 SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel); … … 197 198 uf_epl_sub_iter=uf_epl->Duplicate(); 198 199 uf_epl->Copy(uf_epl_sub_iter); 199 delete ug_epl; 200 delete ug_epl; 200 201 Mergesolutionfromftogx(&ug_epl,uf_epl,ys,femmodel->nodes,femmodel->parameters); delete ys; 201 202 InputUpdateFromSolutionx(femmodel,ug_epl); 202 203 ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel); 203 204 204 205 dug=ug_epl_sub_iter->Duplicate();_assert_(dug); 205 206 ug_epl_sub_iter->Copy(dug); … … 218 219 /* if(ThickCount<L2Count)eplconverged=true; */ 219 220 eplcount++; 220 221 221 222 delete ug_epl_sub_iter; 222 223 if(eplconverged){ … … 235 236 //compute norm(du)/norm(u) 236 237 dug=ug_sed_main_iter->Duplicate(); _assert_(dug); 237 ug_sed_main_iter->Copy(dug); 238 ug_sed_main_iter->Copy(dug); 238 239 dug->AYPX(ug_sed,-1.0); 239 ndu_sed=dug->Norm(NORM_TWO); 240 ndu_sed=dug->Norm(NORM_TWO); 240 241 delete dug; 241 242 nu_sed=ug_sed_main_iter->Norm(NORM_TWO); … … 243 244 if (xIsNan<IssmDouble>(ndu_sed) || xIsNan<IssmDouble>(nu_sed)) _error_("Sed convergence criterion is NaN!"); 244 245 if (ndu_sed==0.0 && nu_sed==0.0) nu_sed=1.0e-6; /*Hacking the case where the Sediment is used but empty*/ 245 dug=ug_epl_main_iter->Duplicate();_assert_(dug); 246 ug_epl_main_iter->Copy(dug); 246 dug=ug_epl_main_iter->Duplicate();_assert_(dug); 247 ug_epl_main_iter->Copy(dug); 247 248 dug->AYPX(ug_epl,-1.0); 248 ndu_epl=dug->Norm(NORM_TWO); 249 ndu_epl=dug->Norm(NORM_TWO); 249 250 delete dug; 250 251 nu_epl=ug_epl_main_iter->Norm(NORM_TWO); … … 257 258 hydroconverged=true; 258 259 } 259 else{ 260 else{ 260 261 if(VerboseConvergence()) _printf0_(setw(50) << left << " Sediment Convergence criterion:" << ndu_sed/nu_sed*100 << "%, aiming lower than " << eps_hyd*100 << " %\n"); 261 262 if(VerboseConvergence()) _printf0_(setw(50) << left << " EPL Convergence criterion:" << ndu_epl/nu_epl*100 << "%, aiming lower than " << eps_hyd*100 << " %\n");
Note:
See TracChangeset
for help on using the changeset viewer.