Changeset 21402


Ignore:
Timestamp:
11/18/16 13:56:00 (8 years ago)
Author:
youngmc3
Message:

CHG: calving 3D

Location:
issm/trunk-jpl/src/c/classes
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/Elements/Penta.cpp

    r21393 r21402  
    174174void       Penta::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){/*{{{*/
    175175        _error_("Not supported yet!");
     176}
     177/*}}}*/
     178void       Penta::CalvingRateDev(){/*{{{*/
     179
     180        if(!this->IsOnBase()) return;
     181
     182        IssmDouble  xyz_list[NUMVERTICES][3];
     183        IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
     184        IssmDouble  calvingratex[NUMVERTICES];
     185        IssmDouble  calvingratey[NUMVERTICES];
     186        IssmDouble  calvingrate[NUMVERTICES];
     187        IssmDouble  lambda1,lambda2,ex,ey,vx,vy,vel;
     188        IssmDouble  sigma_vm,sigma_max,epse_2,groundedice;
     189
     190        /* Get node coordinates and dof list: */
     191        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     192
     193        /*Depth average B for stress calculation*/
     194        this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum);
     195        this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
     196        this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
     197
     198        /*Retrieve all inputs and parameters we will need*/
     199        Input* vx_input = inputs->GetInput(VxAverageEnum); _assert_(vx_input);
     200        Input* vy_input = inputs->GetInput(VyAverageEnum); _assert_(vy_input);
     201        Input* gr_input = inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(gr_input);
     202        IssmDouble  B   = this->GetMaterialParameter(MaterialsRheologyBbarEnum);
     203        IssmDouble  n   = this->GetMaterialParameter(MaterialsRheologyNEnum);
     204
     205        /* Start looping on the number of vertices: */
     206        GaussPenta* gauss=new GaussPenta();
     207        for(int iv=0;iv<3;iv++){
     208                gauss->GaussVertex(iv);
     209
     210                /*Get velocity components and thickness*/
     211                vx_input->GetInputValue(&vx,gauss);
     212                vy_input->GetInputValue(&vy,gauss);
     213                gr_input->GetInputValue(&groundedice,gauss);
     214                vel=sqrt(vx*vx+vy*vy)+1.e-14;
     215
     216                /*Compute strain rate and viscosity: */
     217                this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
     218
     219                /*Get Eigen values*/
     220                Matrix2x2Eigen(&lambda1,&lambda2,&ex,&ey,epsilon[0],epsilon[2],epsilon[1]);
     221                _assert_(!xIsNan<IssmDouble>(lambda1));
     222                _assert_(!xIsNan<IssmDouble>(lambda2));
     223
     224                /*Process Eigen values (only account for extension)*/
     225                lambda1 = max(lambda1,0.);
     226                lambda2 = max(lambda2,0.);
     227
     228                /*Calculate sigma_vm*/
     229                epse_2    = 1./2. *(lambda1*lambda1 + lambda2*lambda2);
     230                sigma_vm  = sqrt(3.) * B * pow(epse_2,1./(2.*n));
     231                sigma_max = 1000.e+3;
     232
     233                if(groundedice<0) sigma_max=200.e+3;
     234
     235                /*Assign values*/
     236                calvingratex[iv]=vx*sigma_vm/sigma_max;
     237                calvingratey[iv]=vy*sigma_vm/sigma_max;
     238                calvingrate[iv]=sqrt(calvingratex[iv]*calvingratex[iv] + calvingratey[iv]*calvingratey[iv]);
     239        }
     240
     241        /*Add input*/
     242        this->inputs->AddInput(new PentaInput(CalvingratexEnum,&calvingratex[0],P1Enum));
     243        this->inputs->AddInput(new PentaInput(CalvingrateyEnum,&calvingratey[0],P1Enum));
     244        this->inputs->AddInput(new PentaInput(CalvingCalvingrateEnum,&calvingrate[0],P1Enum));
     245
     246        this->InputExtrude(CalvingratexEnum,-1);
     247        this->InputExtrude(CalvingrateyEnum,-1);
     248        this->InputExtrude(CalvingCalvingrateEnum,-1);
     249
     250        /*Clean up and return*/
     251        delete gauss;
    176252}
    177253/*}}}*/
     
    641717
    642718                /*Create gauss point in the middle of the basal edge*/
    643                 Gauss* gauss=NewGaussBase(1);
     719                Gauss* gauss=NewGauss();
    644720                gauss->GaussPoint(0);
    645721
     
    22132289}
    22142290/*}}}*/
     2291void       Penta::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
     2292
     2293        /*Intermediaries*/
     2294        IssmDouble d,xn,yn;
     2295
     2296        /*Get current levelset and vertex coordinates*/
     2297        IssmDouble ls[NUMVERTICES];
     2298        IssmDouble  xyz_list[NUMVERTICES][3];
     2299        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     2300        GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
     2301        InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
     2302
     2303        /*Get distance from list of segments and reset ls*/
     2304        for(int j=0;j<NUMVERTICES;j++){
     2305                IssmDouble dmin = 1.e+50;
     2306                for(int i=0;i<numsegments;i++){
     2307                        IssmDouble x = xyz_list[j][0];
     2308                        IssmDouble y = xyz_list[j][1];
     2309                        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]);
     2310
     2311                        /*Segment has a length of 0*/
     2312                        if(l2==0.){
     2313                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     2314                                if(d<dmin) dmin = d;
     2315                                continue;
     2316                        }
     2317
     2318                        /*Consider the line extending the segment, parameterized as v + t (w - v).
     2319                         *We find projection of point p onto the line.
     2320                         *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
     2321                        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;
     2322                        if(t < 0.0){
     2323                                // Beyond the 'v' end of the segment
     2324                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     2325                        }
     2326                        else if (t > 1.0){
     2327                                // Beyond the 'w' end of the segment
     2328                                d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
     2329                        }
     2330                        else{
     2331                                // Projection falls on the segment
     2332                                xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
     2333                                yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
     2334                                d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
     2335                        }
     2336
     2337                        if(d<dmin) dmin = d;
     2338                }
     2339
     2340                /*Update signed distance*/
     2341                dmin = sqrt(dmin);
     2342                if(dmin>10000) dmin=10000;
     2343                if(ls[j]>0){
     2344                        ls[j] = dmin;
     2345                }
     2346                else{
     2347                        ls[j] = - dmin;
     2348                }
     2349        }
     2350
     2351        /*Update Levelset*/
     2352        this->inputs->AddInput(new PentaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
     2353}
     2354/*}}}*/
    22152355void       Penta::SetClone(int* minranks){/*{{{*/
    22162356
    22172357        _error_("not implemented yet");
    22182358}
     2359
    22192360/*}}}*/
    22202361void       Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){/*{{{*/
  • issm/trunk-jpl/src/c/classes/Elements/Penta.h

    r21344 r21402  
    4848                void           AddInput(int input_enum, IssmDouble* values, int interpolation_enum);
    4949                void           AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
     50                void           CalvingRateDev();
    5051                void           CalvingRateLevermann();
    5152                IssmDouble     CharacteristicLength(void){_error_("not implemented yet");};
     
    146147                void           ResetFSBasalBoundaryCondition(void);
    147148                void           ResetHooks();
     149                void           ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);
    148150                void             SetClone(int* minranks);
    149151                void           SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index);
  • issm/trunk-jpl/src/c/classes/FemModel.cpp

    r21391 r21402  
    17341734        int num_procs = IssmComm::GetSize();
    17351735
     1736        /*Get domain type (2d or 3d)*/
     1737        int domaintype;
     1738        this->parameters->FindParam(&domaintype,DomainTypeEnum);
     1739       
    17361740        /*1: go throug all elements of this partition and figure out how many
    17371741         * segments we have (corresopnding to levelset = 0)*/
     
    17391743        for(int i=0;i<elements->Size();i++){
    17401744                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    1741                 element->WriteLevelsetSegment(segments);
     1745                if(!element->IsOnBase()) continue;
     1746                Element* basalelement = element->SpawnBasalElement();
     1747                basalelement->WriteLevelsetSegment(segments);
     1748                if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
    17421749        }
    17431750
     
    17711778        for(int i=0;i<elements->Size();i++){
    17721779                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1780                if(!element->IsOnBase()) continue;
    17731781                element->ResetLevelsetFromSegmentlist(allsegmentlist,numseg);
     1782        }
     1783
     1784
     1785        /*Extrude if necessary*/
     1786        int elementtype;
     1787        this->parameters->FindParam(&elementtype,MeshElementtypeEnum);
     1788        if(elementtype==PentaEnum){
     1789                InputExtrudex(this,MaskIceLevelsetEnum,-1);
     1790        }
     1791        else if(elementtype==TriaEnum){
     1792                /*no need to extrude*/
     1793        }
     1794        else{
     1795                _error_("not implemented yet");
    17741796        }
    17751797
Note: See TracChangeset for help on using the changeset viewer.