Changeset 19476


Ignore:
Timestamp:
08/03/15 13:03:29 (10 years ago)
Author:
Mathieu Morlighem
Message:

NEW: added ResetLevelset function

Location:
issm/trunk-jpl/src/c
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/analyses/LevelsetAnalysis.cpp

    r19158 r19476  
    143143        basalelement->FindParam(&calvinglaw,CalvingLawEnum);
    144144        basalelement->FindParam(&stabilization,LevelsetStabilizationEnum);
     145        calvinglaw=DefaultCalvingEnum;
    145146        switch(domaintype){
    146147                case Domain2DverticalEnum:   dim = 1; break;
  • issm/trunk-jpl/src/c/classes/Elements/Element.h

    r19395 r19476  
    178178                virtual void       CalvingRatePi(void)=0;
    179179                virtual void       CalvingRateDev(void){_error_("not implemented yet");};
     180                virtual void       WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};
     181                virtual void       ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};
    180182                virtual IssmDouble CharacteristicLength(void)=0;
    181183                virtual void       ComputeBasalStress(Vector<IssmDouble>* sigma_b)=0;
  • issm/trunk-jpl/src/c/classes/Elements/Tria.cpp

    r19395 r19476  
    350350        IssmDouble  calvingrate[NUMVERTICES];
    351351        IssmDouble  lambda1,lambda2,ex,ey,vx,vy,vel;
    352         IssmDouble  sigma_vm,sigma_max;
     352        IssmDouble  sigma_vm,sigma_max,epse_2;
    353353
    354354        /* Get node coordinates and dof list: */
     
    384384
    385385                /*Calculate sigma_vm*/
    386                 sigma_vm  = sqrt(3./2.) * B * pow(lambda1*lambda1 + lambda2*lambda2,1./(2.*n));
     386                epse_2    = 1./2. *(lambda1*lambda1 + lambda2*lambda2);
     387                sigma_vm  = sqrt(3.) * B * pow(epse_2,1./(2.*n));
     388                //sigma_max = 125.e+3;
    387389                sigma_max = 350.e+3;
     390                sigma_max = 450.e+3;
     391                sigma_max = 800.e+3; //too much
     392                sigma_max = 700.e+3;
     393                sigma_max = 670.e+3;
     394                //sigma_max = 550.e+3;
    388395
    389396                /*Assign values*/
     
    400407        /*Clean up and return*/
    401408        delete gauss;
     409}
     410/*}}}*/
     411void       Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/
     412
     413        if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return;
     414
     415        IssmDouble* xyz_list_zero = NULL;
     416        IssmDouble  xyz_list[NUMVERTICES][3];
     417        ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
     418        this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum);
     419        if(xyz_list_zero){
     420                IssmDouble x[2];
     421                IssmDouble y[2];
     422                x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
     423                y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
     424                segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
     425        }
     426        xDelete<IssmDouble>(xyz_list_zero);
     427
     428//      IssmDouble ls[NUMVERTICES];
     429//      IssmDouble  xyz_list[NUMVERTICES][3];
     430//
     431//      if(IsIceInElement()){
     432//
     433//              /*Retrieve all inputs and parameters*/
     434//              GetInputListOnVertices(&ls[0],levelset_enum);
     435//
     436//              /*If the level set is awlays <0, there is no ice front here*/
     437//              bool iszerols= false;
     438//              if(IsIceInElement()){
     439//                      if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){
     440//                              iszerols = true;
     441//                      }
     442//              }
     443//
     444//              if(iszerols){
     445//                      /*OK we have one segment!*/
     446//                      ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     447//                      int count = 0;
     448//                      IssmDouble x[2];
     449//                      IssmDouble y[2];
     450//
     451//                      for(int i=0;i<NUMVERTICES,i++){
     452//                              int index1 = i;
     453//                              int index1 = (i+1)%3;
     454//                              if(ls[index1]<=0 && ls[index2]>=0){
     455//
     456//                              }
     457//
     458//                      }
     459//                      Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false);
     460//              }
     461//
     462//      }
     463//
     464//      _error_("STOP");
     465}
     466/*}}}*/
     467void       Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
     468
     469        /*Intermediaries*/
     470        double d,xn,yn;
     471
     472        /*Get current levelset and vertex coordinates*/
     473        IssmDouble ls[NUMVERTICES];
     474        IssmDouble  xyz_list[NUMVERTICES][3];
     475        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     476        GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
     477        InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
     478
     479        /*Get distance from list of segments and reset ls*/
     480        for(int j=0;j<NUMVERTICES;j++){
     481                double dmin = 1.e+50;
     482                for(int i=0;i<numsegments;i++){
     483                        IssmDouble x = xyz_list[j][0];
     484                        IssmDouble y = xyz_list[j][1];
     485                        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]);
     486
     487                        /*Segment has a length of 0*/
     488                        if(l2==0.){
     489                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     490                                if(d<dmin) dmin = d;
     491                                continue;
     492                        }
     493
     494                        /*Consider the line extending the segment, parameterized as v + t (w - v).
     495                         *We find projection of point p onto the line.
     496                         *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
     497                        double 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;
     498                        if(t < 0.0){
     499                                // Beyond the 'v' end of the segment
     500                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     501                        }
     502                        else if (t > 1.0){
     503                                // Beyond the 'w' end of the segment
     504                                d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
     505                        }
     506                        else{
     507                                // Projection falls on the segment
     508                                xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
     509                                yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
     510                                d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
     511                        }
     512
     513                        if(d<dmin) dmin = d;
     514                }
     515
     516                /*Update signed distance*/
     517                dmin = sqrt(dmin);
     518                if(dmin>10000) dmin=10000;
     519                if(ls[j]>0){
     520                        ls[j] = dmin;
     521                }
     522                else{
     523                        ls[j] = - dmin;
     524                }
     525        }
     526
     527        /*Update Levelset*/
     528        this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
    402529}
    403530/*}}}*/
     
    31443271        IssmDouble* xyz_zero=NULL;
    31453272
    3146         this->GetLevelsetIntersection(&indices, &numiceverts, s, MaskIceLevelsetEnum, 0.);
     3273        this->GetLevelsetIntersection(&indices, &numiceverts, s,levelsetenum,0.);
    31473274       
    31483275        //TODO: check if for 2 iceverts front segment is oriented in CCW way
     
    31653292        else if(numiceverts==NUMVERTICES){ //NUMVERTICES ice vertices: calving front lies on element edge
    31663293                IssmDouble lsf[NUMVERTICES];
    3167                 this->GetInputListOnVertices(&lsf[0],MaskIceLevelsetEnum);
     3294                this->GetInputListOnVertices(&lsf[0],levelsetenum);
    31683295                counter=0;
    31693296                for(i=0;i<NUMVERTICES;i++){
  • issm/trunk-jpl/src/c/classes/Elements/Tria.h

    r19237 r19476  
    5555                void                    CalvingRatePi();
    5656                void                    CalvingRateDev();
     57                void                    WriteLevelsetSegment(DataSet* segments);
     58                void        ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);
    5759                IssmDouble  CharacteristicLength(void);
    5860                void        ComputeBasalStress(Vector<IssmDouble>* sigma_b);
  • issm/trunk-jpl/src/c/classes/FemModel.cpp

    r19282 r19476  
    842842                (element->*function)();
    843843        }
     844
     845}
     846/*}}}*/
     847void FemModel::ResetLevelset(void){/*{{{*/
     848
     849        /*recover my_rank:*/
     850        int my_rank   = IssmComm::GetRank();
     851        int num_procs = IssmComm::GetSize();
     852
     853        /*1: go throug all elements of this partition and figure out how many
     854         * segments we have (corresopnding to levelset = 0)*/
     855        DataSet* segments=new DataSet();
     856        for(int i=0;i<elements->Size();i++){
     857                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     858                element->WriteLevelsetSegment(segments);
     859        }
     860
     861        /*2: now get the segments from all partitions*/
     862        int  segcount=segments->Size();
     863        int* allsegcount=xNew<int>(num_procs);
     864        ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     865        ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm());
     866
     867        /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/
     868        int numseg_offset=0;
     869        int numseg=0;
     870        for(int i=0;i<my_rank;  i++) numseg_offset+=allsegcount[i];
     871        for(int i=0;i<num_procs;i++) numseg+=allsegcount[i];
     872        IssmDouble* segmentlist    = xNewZeroInit<IssmDouble>(4*numseg);
     873        IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg);
     874        for(int i=0;i<segments->Size();i++){
     875                Contour<IssmDouble>* segment=(Contour<IssmDouble>*)segments->GetObjectByOffset(i);
     876                _assert_(segment->nods == 2);
     877                segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0];
     878                segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0];
     879                segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1];
     880                segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1];
     881        }
     882        ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
     883        delete segments;
     884        xDelete<IssmDouble>(segmentlist);
     885        xDelete<int>(allsegcount);
     886
     887        /*3: update levelset for all elements*/
     888        for(int i=0;i<elements->Size();i++){
     889                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     890                element->ResetLevelsetFromSegmentlist(allsegmentlist,numseg);
     891        }
     892
     893        /*Clean up and return*/
     894        xDelete<IssmDouble>(allsegmentlist);
    844895
    845896}
  • issm/trunk-jpl/src/c/classes/FemModel.h

    r19198 r19476  
    9494                void CalvingRatePix();
    9595                void CalvingRateDevx();
     96                void ResetLevelset();
    9697                #ifdef  _HAVE_DAKOTA_
    9798                void DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses);
Note: See TracChangeset for help on using the changeset viewer.