Changeset 22991
- Timestamp:
- 07/20/18 16:35:38 (7 years ago)
- Location:
- issm/trunk-jpl/src/c/classes
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/Elements/Element.h
r22990 r22991 290 290 virtual void ResetFSBasalBoundaryCondition()=0; 291 291 virtual void ResetHooks()=0; 292 virtual void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};293 292 virtual void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset,int N,int M)=0; 294 293 virtual void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0; -
issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
r22990 r22991 2286 2286 if(this->hneighbors) this->hneighbors->reset(); 2287 2287 2288 }2289 /*}}}*/2290 void Penta::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/2291 2292 /*Intermediaries*/2293 IssmDouble d,xn,yn;2294 2295 /*Get current levelset and vertex coordinates*/2296 IssmDouble ls[NUMVERTICES];2297 IssmDouble xyz_list[NUMVERTICES][3];2298 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);2299 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);2300 2301 /*Get distance from list of segments and reset ls*/2302 for(int j=0;j<NUMVERTICES;j++){2303 IssmDouble dmin = 1.e+50;2304 for(int i=0;i<numsegments;i++){2305 IssmDouble x = xyz_list[j][0];2306 IssmDouble y = xyz_list[j][1];2307 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);2308 2309 /*Segment has a length of 0*/2310 if(l2==0.){2311 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);2312 if(d<dmin) dmin = d;2313 continue;2314 }2315 2316 /*Consider the line extending the segment, parameterized as v + t (w - v).2317 *We find projection of point p onto the line.2318 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/2319 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;2320 if(t < 0.0){2321 // Beyond the 'v' end of the segment2322 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);2323 }2324 else if (t > 1.0){2325 // Beyond the 'w' end of the segment2326 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);2327 }2328 else{2329 // Projection falls on the segment2330 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);2331 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);2332 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);2333 }2334 2335 if(d<dmin) dmin = d;2336 }2337 2338 /*Update signed distance*/2339 dmin = sqrt(dmin);2340 if(dmin>10000) dmin=10000;2341 if(ls[j]>0){2342 ls[j] = dmin;2343 }2344 else{2345 ls[j] = - dmin;2346 }2347 }2348 2349 /*Update Levelset*/2350 this->inputs->AddInput(new PentaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));2351 2288 } 2352 2289 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r22990 r22991 149 149 void ResetFSBasalBoundaryCondition(void); 150 150 void ResetHooks(); 151 void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);152 151 void SetClone(int* minranks); 153 152 void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M); -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r22990 r22991 873 873 /*Update signed distance*/ 874 874 dmin = sqrt(dmin); 875 // if(dmin>10000) dmin=10000; 875 /*FIXME: do we really need this?*/ 876 if(distanceenum==MaskIceLevelsetEnum) if(dmin>10000) dmin=10000; 876 877 if(ls[j]>0){ 877 878 ls[j] = dmin; … … 3301 3302 } 3302 3303 /*}}}*/ 3303 void Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/3304 3305 /*Intermediaries*/3306 IssmDouble d,xn,yn;3307 3308 /*Get current levelset and vertex coordinates*/3309 IssmDouble ls[NUMVERTICES];3310 IssmDouble xyz_list[NUMVERTICES][3];3311 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3312 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);3313 3314 /*Get distance from list of segments and reset ls*/3315 for(int j=0;j<NUMVERTICES;j++){3316 IssmDouble dmin = 1.e+50;3317 for(int i=0;i<numsegments;i++){3318 IssmDouble x = xyz_list[j][0];3319 IssmDouble y = xyz_list[j][1];3320 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);3321 3322 /*Segment has a length of 0*/3323 if(l2==0.){3324 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);3325 if(d<dmin) dmin = d;3326 continue;3327 }3328 3329 /*Consider the line extending the segment, parameterized as v + t (w - v).3330 *We find projection of point p onto the line.3331 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/3332 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;3333 if(t < 0.0){3334 // Beyond the 'v' end of the segment3335 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);3336 }3337 else if (t > 1.0){3338 // Beyond the 'w' end of the segment3339 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);3340 }3341 else{3342 // Projection falls on the segment3343 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);3344 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);3345 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);3346 }3347 3348 if(d<dmin) dmin = d;3349 }3350 3351 /*Update signed distance*/3352 dmin = sqrt(dmin);3353 if(dmin>10000) dmin=10000;3354 if(ls[j]>0){3355 ls[j] = dmin;3356 }3357 else{3358 ls[j] = - dmin;3359 }3360 }3361 3362 /*Update Levelset*/3363 this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));3364 }3365 /*}}}*/3366 3304 void Tria::SetClone(int* minranks){/*{{{*/ 3367 3305 -
issm/trunk-jpl/src/c/classes/FemModel.cpp
r22990 r22991 2015 2015 void FemModel::ResetLevelset(void){/*{{{*/ 2016 2016 2017 /*recover my_rank:*/ 2018 int my_rank = IssmComm::GetRank(); 2019 int num_procs = IssmComm::GetSize(); 2020 2021 /*Get domain type (2d or 3d)*/ 2022 int domaintype; 2023 this->parameters->FindParam(&domaintype,DomainTypeEnum); 2024 2025 /*1: go throug all elements of this partition and figure out how many 2026 * segments we have (corresopnding to levelset = 0)*/ 2027 DataSet* segments=new DataSet(); 2028 for(int i=0;i<elements->Size();i++){ 2029 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2030 if(!element->IsOnBase()) continue; 2031 Element* basalelement = element->SpawnBasalElement(); 2032 basalelement->WriteFieldIsovalueSegment(segments,MaskIceLevelsetEnum,0.); 2033 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 2034 } 2035 2036 /*2: now get the segments from all partitions*/ 2037 int segcount=segments->Size(); 2038 int* allsegcount=xNew<int>(num_procs); 2039 ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2040 ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm()); 2041 2042 /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/ 2043 int numseg_offset=0; 2044 int numseg=0; 2045 for(int i=0;i<my_rank; i++) numseg_offset+=allsegcount[i]; 2046 for(int i=0;i<num_procs;i++) numseg+=allsegcount[i]; 2047 IssmDouble* segmentlist = xNewZeroInit<IssmDouble>(4*numseg); 2048 IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg); 2049 for(int i=0;i<segments->Size();i++){ 2050 Contour<IssmDouble>* segment=(Contour<IssmDouble>*)segments->GetObjectByOffset(i); 2051 _assert_(segment->nods == 2); 2052 segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0]; 2053 segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0]; 2054 segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1]; 2055 segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1]; 2056 } 2057 ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 2058 delete segments; 2059 xDelete<IssmDouble>(segmentlist); 2060 xDelete<int>(allsegcount); 2061 2062 /*3: update levelset for all elements*/ 2063 for(int i=0;i<elements->Size();i++){ 2064 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2065 if(!element->IsOnBase()) continue; 2066 element->ResetLevelsetFromSegmentlist(allsegmentlist,numseg); 2067 } 2068 2069 /*Extrude if necessary*/ 2070 int elementtype; 2071 this->parameters->FindParam(&elementtype,MeshElementtypeEnum); 2072 if(elementtype==PentaEnum){ 2073 InputExtrudex(this,MaskIceLevelsetEnum,-1); 2074 } 2075 else if(elementtype==TriaEnum){ 2076 /*no need to extrude*/ 2077 } 2078 else{ 2079 _error_("not implemented yet"); 2080 } 2081 2082 /*Clean up and return*/ 2083 xDelete<IssmDouble>(allsegmentlist); 2017 this->DistanceToFieldValue(MaskIceLevelsetEnum,0.,MaskIceLevelsetEnum); 2084 2018 2085 2019 }
Note:
See TracChangeset
for help on using the changeset viewer.