Changeset 22955 for issm/trunk-jpl/src/c/classes/FemModel.cpp
- Timestamp:
- 07/16/18 15:39:26 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/FemModel.cpp
r22902 r22955 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; … … 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(); … … 4226 4226 #endif 4227 4227 #ifdef _HAVE_SEALEVELRISE_ 4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* p Sgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pRSLgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop) { /*{{{*/ 4229 4229 4230 4230 /*serialized vectors:*/ … … 4262 4262 if(i<ns){ 4263 4263 4264 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% ");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 element->SealevelriseEustatic(p Sgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);4267 element->SealevelriseEustatic(pRSLgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea); 4268 4268 eustatic_cpu+=eustatic_cpu_e; 4269 4269 } 4270 if(i% 100==0)pSgi->Assemble();4270 if(i%loop==0)pRSLgi->Assemble(); 4271 4271 } 4272 4272 if(VerboseConvergence())_printf0_("\n"); 4273 4273 4274 4274 /*One last time: */ 4275 p Sgi->Assemble();4275 pRSLgi->Assemble(); 4276 4276 4277 4277 /*Sum all eustatic components from all cpus:*/ … … 4285 4285 } 4286 4286 /*}}}*/ 4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* p Sgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution,int loop){/*{{{*/ 4288 4288 4289 4289 /*serialized vectors:*/ 4290 IssmDouble* Sg_old=NULL;4291 4290 IssmDouble* RSLg_old=NULL; 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 Sg_old=pSg_old->ToMPISerial();4298 RSLg_old=pRSLg_old->ToMPISerial(); 4299 4299 4300 4300 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ … … 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()); … … 4317 4317 for(int i=0;i<nsmax;i++){ 4318 4318 if(i<ns){ 4319 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf _("\r" << "convolution progress: " << (double)i/(double)ns*100 << "% ");4319 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4320 4320 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 4321 element->SealevelriseNonEustatic(pRSLgo,RSLg_old,latitude,longitude,radius,eartharea); 4322 } 4323 if(i%loop==0)pRSLgo->Assemble(); 4324 } 4325 if(verboseconvolution)if(VerboseConvergence())_printf0_("\n"); 4326 4327 4327 /*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){/*{{{*/4328 xDelete<IssmDouble>(RSLg_old); 4329 } 4330 /*}}}*/ 4331 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/ 4332 4332 4333 4333 /*serialized vectors:*/ 4334 IssmDouble* Sg_old=NULL;4334 IssmDouble* RSLg_old=NULL; 4335 4335 IssmDouble eartharea=0; 4336 4336 IssmDouble eartharea_cpu=0; … … 4341 4341 4342 4342 /*Serialize vectors from previous iteration:*/ 4343 Sg_old=pSg_old->ToMPISerial();4343 RSLg_old=pRSLg_old->ToMPISerial(); 4344 4344 4345 4345 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ … … 4355 4355 for(int i=0;i<elements->Size();i++){ 4356 4356 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4357 element->SealevelriseMomentOfInertia(&moi_list[0], Sg_old,eartharea);4357 element->SealevelriseMomentOfInertia(&moi_list[0],RSLg_old,eartharea); 4358 4358 moi_list_cpu[0] += moi_list[0]; 4359 4359 moi_list_cpu[1] += moi_list[1]; … … 4399 4399 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 4400 4400 4401 p Sgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times4401 pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times 4402 4402 } 4403 4403 4404 4404 /*Assemble mesh velocity*/ 4405 p Sgo_rot->Assemble();4405 pRSLgo_rot->Assemble(); 4406 4406 4407 4407 /*Assign output pointers:*/ 4408 *pIxz=moi_list[0];4409 *pIyz=moi_list[1];4410 *pIzz=moi_list[2];4408 if(pIxz)*pIxz=moi_list[0]; 4409 if(pIyz)*pIyz=moi_list[1]; 4410 if(pIzz)*pIzz=moi_list[2]; 4411 4411 4412 4412 /*Free ressources:*/ 4413 xDelete<IssmDouble>(Sg_old); 4414 4415 } 4416 /*}}}*/ 4417 void FemModel::SealevelriseGeodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/ 4413 xDelete<IssmDouble>(RSLg_old); 4414 4415 4416 } 4417 /*}}}*/ 4418 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 4419 4419 4420 /*serialized vectors:*/ 4420 IssmDouble* Sg=NULL;4421 4421 IssmDouble* RSLg=NULL; 4422 4422 4423 IssmDouble eartharea=0; 4423 4424 IssmDouble eartharea_cpu=0; 4424 4425 4425 4426 int ns,nsmax; 4426 4427 4427 4428 /*Serialize vectors from previous iteration:*/ 4428 Sg=pSg->ToMPISerial();4429 RSLg=pRSLg->ToMPISerial(); 4429 4430 4430 4431 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4431 4432 ns = elements->Size(); 4432 4433 4433 4434 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ 4434 4435 for(int i=0;i<ns;i++){ … … 4446 4447 for(int i=0;i<nsmax;i++){ 4447 4448 if(i<ns){ 4449 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4448 4450 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){4451 element->SealevelriseGeodetic(pUp,pNorth,pEast,RSLg,latitude,longitude,radius,xx,yy,zz,eartharea,horiz); 4452 } 4453 if(i%loop==0){ 4452 4454 pUp->Assemble(); 4453 pNorth->Assemble(); 4454 pEast->Assemble(); 4455 } 4456 } 4457 4455 if (horiz){ 4456 pNorth->Assemble(); 4457 pEast->Assemble(); 4458 } 4459 } 4460 } 4461 4458 4462 /*One last time: */ 4459 4463 pUp->Assemble(); 4460 pNorth->Assemble(); 4461 pEast->Assemble(); 4464 if(horiz){ 4465 pNorth->Assemble(); 4466 pEast->Assemble(); 4467 } 4468 if(VerboseConvergence())_printf0_("\n"); 4462 4469 4463 4470 /*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; 4471 xDelete<IssmDouble>(RSLg); 4472 } 4473 /*}}}*/ 4474 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* RSLg) { /*{{{*/ 4475 4476 IssmDouble* RSLg_serial=NULL; 4476 4477 IssmDouble oceanvalue,oceanvalue_cpu; 4477 4478 IssmDouble oceanarea,oceanarea_cpu; 4478 4479 4479 4480 /*Serialize vectors from previous iteration:*/ 4480 Sg_serial=Sg->ToMPISerial();4481 RSLg_serial=RSLg->ToMPISerial(); 4481 4482 4482 4483 /*Initialize:*/ … … 4488 4489 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4489 4490 oceanarea_cpu += element->OceanArea(); 4490 oceanvalue_cpu += element->OceanAverage( Sg_serial);4491 oceanvalue_cpu += element->OceanAverage(RSLg_serial); 4491 4492 } 4492 4493 ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4493 4494 ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4494 4495 4495 4496 ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4496 4497 ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4497 4498 4498 4499 /*Free ressources:*/ 4499 xDelete<IssmDouble>( Sg_serial);4500 4500 xDelete<IssmDouble>(RSLg_serial); 4501 4501 4502 return oceanvalue/oceanarea; 4502 4503 } … … 4514 4515 int* eplzigzag_counter = NULL; 4515 4516 int eplflip_lock; 4516 4517 4517 4518 HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis(); 4518 4519 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); … … 4521 4522 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4522 4523 recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4523 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4524 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4524 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4525 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4525 4526 GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum); 4526 4527 4527 4528 for (int i=0;i<elements->Size();i++){ 4528 4529 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4542 4543 /*Assemble and serialize*/ 4543 4544 mask->Assemble(); 4544 serial_mask=mask->ToMPISerial(); 4545 4545 serial_mask=mask->ToMPISerial(); 4546 4546 4547 xDelete<int>(eplzigzag_counter); 4547 4548 xDelete<IssmDouble>(serial_rec); … … 4585 4586 int sum_counter; 4586 4587 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()); 4588 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4588 4589 counter=sum_counter; 4589 4590 *pEplcount = counter; 4590 4591 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 Vector<IssmDouble>* active = NULL;4602 IssmDouble* serial_mask = NULL;4603 IssmDouble* serial_active = NULL;4604 4605 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis();4606 parameters->FindParam(&isthermal,TransientIsthermalEnum);4607 4608 /*When solving a thermal model we update the thawed nodes*/4609 if(isthermal){4610 /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/4611 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));4612 4613 for (int i=0;i<elements->Size();i++){4614 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4615 inefanalysis->HydrologyIDSGetMask(mask,element);4616 }4617 /*Assemble and serialize*/4618 mask->Assemble();4619 serial_mask=mask->ToMPISerial();4620 delete mask;4621 }4622 /*for other cases we just grab the mask from the initialisation value*/4623 else{4624 GetVectorFromInputsx(&serial_mask,this,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);4625 }4626 /*Update Mask and elementize*/4627 InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);4628 xDelete<IssmDouble>(serial_mask);4629 inefanalysis->ElementizeIdsMask(this);4630 4631 /*get node mask coherent with element mask*/4632 active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));4633 for (int i=0;i<elements->Size();i++){4634 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4635 inefanalysis->HydrologyIdsGetActive(active,element);4636 }4637 4638 /*Assemble and serialize*/4639 active->Assemble();4640 serial_active=active->ToMPISerial();4641 delete active;4642 4643 /*Update node activation accordingly*/4644 int counter =0;4645 for (int i=0;i<nodes->Size();i++){4646 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));4647 if(node->InAnalysis(HydrologyDCInefficientAnalysisEnum)){4648 if(serial_active[node->Sid()]==1.){4649 node->Activate();4650 if(!node->IsClone()) counter++;4651 }4652 else{4653 node->Deactivate();4654 }4655 }4656 }4657 4658 xDelete<IssmDouble>(serial_active);4659 delete inefanalysis;4660 int sum_counter;4661 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );4662 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());4663 counter=sum_counter;4664 *pIDScount = counter;4665 if(VerboseSolution()) _printf0_(" Number of active nodes in IDS layer: "<< counter <<"\n");4666 4592 4667 4593 /*Update dof indexings*/ … … 4706 4632 int sum_counter; 4707 4633 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4708 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4634 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4709 4635 counter=sum_counter; 4710 4636 *pL2count = counter; … … 4791 4717 } 4792 4718 /*}}}*/ 4793 #ifdef _HAVE_JAVASCRIPT_ 4719 #ifdef _HAVE_JAVASCRIPT_ 4794 4720 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/ 4795 4721 /*configuration: */ … … 4806 4732 /*From command line arguments, retrieve different filenames needed to create the FemModel: */ 4807 4733 solution_type=StringToEnumx(solution); 4808 4734 4809 4735 /*Create femmodel from input files: */ 4810 4736 profiler->Start(MPROCESSOR); 4811 4737 this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL); 4812 4738 profiler->Stop(MPROCESSOR); 4813 4739 4814 4740 /*Save communicator in the parameters dataset: */ 4815 4741 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 4826 4752 size_t* poutputbuffersize; 4827 4753 4828 4754 4829 4755 /*Before we delete the profiler, report statistics for this run: */ 4830 4756 profiler->Stop(TOTAL); //final tagging … … 4839 4765 ); 4840 4766 _printf0_("\n"); 4841 4767 4842 4768 /*Before we close the output file, recover the buffer and size:*/ 4843 4769 outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum)); … … 4879 4805 4880 4806 /*Open output file once for all and add output file descriptor to parameters*/ 4881 output_fid=open_memstream(&outputbuffer,&outputsize); 4807 output_fid=open_memstream(&outputbuffer,&outputsize); 4882 4808 if(output_fid==NULL)_error_("could not initialize output stream"); 4883 4809 this->parameters->SetParam(output_fid,OutputFilePointerEnum); … … 4887 4813 }/*}}}*/ 4888 4814 #endif 4815 4889 4816 4890 4817 #if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_) … … 4920 4847 /*Initialize hmaxvertices with NAN*/ 4921 4848 hmaxvertices_serial=xNew<IssmDouble>(numberofvertices); 4922 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4849 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4923 4850 /*Fill hmaxvertices*/ 4924 4851 if(this->amrbamg->groundingline_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskGroundediceLevelsetEnum); … … 4927 4854 if(this->amrbamg->deviatoricerror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum); 4928 4855 } 4929 4856 4930 4857 if(my_rank==0){ 4931 4858 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); … … 4947 4874 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 4948 4875 } 4949 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4950 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4951 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4952 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4876 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4877 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4878 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4879 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4953 4880 4954 4881 /*Assign output pointers*/ … … 4983 4910 /*Create bamg data structures for bamg*/ 4984 4911 this->amrbamg = new AmrBamg(); 4985 4912 4986 4913 /*Get amr parameters*/ 4987 4914 this->parameters->FindParam(&hmin,AmrHminEnum); … … 5007 4934 5008 4935 /*Re-create original mesh and put it in bamg structure (only cpu 0)*/ 5009 if(my_rank==0){ 4936 if(my_rank==0){ 5010 4937 this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements); 5011 4938 } … … 5021 4948 5022 4949 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 5023 4950 5024 4951 /*Intermediaries*/ 5025 4952 int numberofvertices = this->vertices->NumberOfVertices(); … … 5028 4955 5029 4956 switch(levelset_type){ 5030 case MaskGroundediceLevelsetEnum: 4957 case MaskGroundediceLevelsetEnum: 5031 4958 threshold = this->amrbamg->groundingline_distance; 5032 4959 resolution = this->amrbamg->groundingline_resolution; … … 5042 4969 this->GetVerticeDistanceToZeroLevelSet(&verticedistance,levelset_type); 5043 4970 if(!verticedistance) _error_("verticedistance is NULL!\n"); 5044 4971 5045 4972 /*Fill hmaxVertices*/ 5046 4973 for(int i=0;i<numberofvertices;i++){ … … 5056 4983 /*}}}*/ 5057 4984 void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/ 5058 4985 5059 4986 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 5060 4987 … … 5064 4991 int numberofvertices = this->vertices->NumberOfVertices(); 5065 4992 IssmDouble* maxlength = xNew<IssmDouble>(numberofelements); 5066 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 4993 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 5067 4994 IssmDouble* error_elements = NULL; 5068 4995 IssmDouble* x = NULL; … … 5077 5004 /*Fill variables*/ 5078 5005 switch(errorestimator_type){ 5079 case ThicknessErrorEstimatorEnum: 5006 case ThicknessErrorEstimatorEnum: 5080 5007 threshold = this->amrbamg->thicknesserror_threshold; 5081 5008 groupthreshold = this->amrbamg->thicknesserror_groupthreshold; … … 5102 5029 case ThicknessErrorEstimatorEnum: this->amrbamg->thicknesserror_maximum = maxerror;break; 5103 5030 case DeviatoricStressErrorEstimatorEnum: this->amrbamg->deviatoricerror_maximum = maxerror;break; 5104 } 5031 } 5105 5032 } 5106 5033 5107 5034 /*Get mesh*/ 5108 5035 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&index); 5109 5036 5110 5037 /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/ 5111 5038 for(int i=0;i<numberofelements;i++){ … … 5121 5048 error_vertices[v2]+=error_elements[i]; 5122 5049 error_vertices[v3]+=error_elements[i]; 5123 } 5050 } 5124 5051 5125 5052 /*Fill hmaxvertices with the criteria*/ … … 5135 5062 } 5136 5063 } 5137 /*Now, fill the hmaxvertices if requested*/ 5064 /*Now, fill the hmaxvertices if requested*/ 5138 5065 if(refine){ 5139 5066 for(int j=0;j<elementswidth;j++){ … … 5165 5092 /*Output*/ 5166 5093 IssmDouble* verticedistance; 5167 5094 5168 5095 /*Intermediaries*/ 5169 5096 int numberofvertices = this->vertices->NumberOfVertices(); … … 5177 5104 /*Get vertices coordinates*/ 5178 5105 VertexCoordinatesx(&x,&y,&z,this->vertices,false) ; 5179 5180 /*Get points which level set is zero (center of elements with zero level set)*/ 5106 5107 /*Get points which level set is zero (center of elements with zero level set)*/ 5181 5108 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5182 5109 … … 5187 5114 for(int j=0;j<numberofpoints;j++){ 5188 5115 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])); 5189 verticedistance[i]=min(distance,verticedistance[i]); 5190 } 5191 } 5116 verticedistance[i]=min(distance,verticedistance[i]); 5117 } 5118 } 5192 5119 5193 5120 /*Assign the pointer*/ … … 5223 5150 if(this->amr->groundingline_distance>0) this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskGroundediceLevelsetEnum); 5224 5151 if(this->amr->icefront_distance>0) this->GetElementDistanceToZeroLevelSet(&if_distance,MaskIceLevelsetEnum); 5225 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5226 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5227 5152 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5153 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5154 5228 5155 if(my_rank==0){ 5229 5156 this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror, 5230 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5157 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5231 5158 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 5232 5159 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the ReMeshNeopz."); … … 5242 5169 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 5243 5170 } 5244 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5245 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5246 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5247 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5248 5249 /*Assign the pointers*/ 5171 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5172 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5173 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5174 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5175 5176 /*Assign the pointers*/ 5250 5177 (*pnewelementslist) = newelementslist; //Matlab indexing 5251 5178 (*pnewx) = newx; … … 5263 5190 /*}}}*/ 5264 5191 void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/ 5265 5192 5266 5193 /*Define variables*/ 5267 5194 int my_rank = IssmComm::GetRank(); … … 5272 5199 IssmDouble* z = NULL; 5273 5200 int* elements = NULL; 5274 5201 5275 5202 /*Initialize field as NULL for now*/ 5276 5203 this->amr = NULL; … … 5280 5207 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements); 5281 5208 5282 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5209 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5283 5210 /*Just CPU #0 should keep AMR object*/ 5284 5211 /*Initialize refinement pattern*/ 5285 5212 this->SetRefPatterns(); 5286 5213 this->amr = new AdaptiveMeshRefinement(); 5287 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5214 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5288 5215 /*Get amr parameters*/ 5289 5216 this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum); … … 5298 5225 this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum); 5299 5226 this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum); 5300 if(my_rank==0){ 5227 if(my_rank==0){ 5301 5228 this->amr->CreateInitialMesh(numberofvertices,numberofelements,x,y,elements); 5302 5229 } … … 5319 5246 /*Output*/ 5320 5247 IssmDouble* elementdistance; 5321 5248 5322 5249 /*Intermediaries*/ 5323 5250 int numberofelements = this->elements->NumberOfElements(); … … 5328 5255 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 5329 5256 int numberofpoints; 5330 5331 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5257 5258 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5332 5259 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5333 5260 … … 5335 5262 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 5336 5263 int sid = element->Sid(); 5337 element->GetVerticesCoordinates(&xyz_list); 5264 element->GetVerticesCoordinates(&xyz_list); 5338 5265 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 5339 5266 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 5345 5272 for(int j=0;j<numberofpoints;j++){ 5346 5273 distance =sqrt((xc-levelset_points[2*j])*(xc-levelset_points[2*j])+(yc-levelset_points[2*j+1])*(yc-levelset_points[2*j+1])); 5347 mindistance=min(distance,mindistance); 5274 mindistance=min(distance,mindistance); 5348 5275 } 5349 5276 velementdistance->SetValue(sid,mindistance,INS_VAL); 5350 5277 xDelete<IssmDouble>(xyz_list); 5351 } 5278 } 5352 5279 5353 5280 /*Assemble*/
Note:
See TracChangeset
for help on using the changeset viewer.