Changeset 22379


Ignore:
Timestamp:
01/29/18 14:16:04 (7 years ago)
Author:
Mathieu Morlighem
Message:

CHG: working on automating distance to GL or IF

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

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/Elements/Element.h

    r22349 r22379  
    200200                virtual void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index)=0;
    201201                virtual void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum)=0;
     202                virtual void       CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){_error_("not implemented yet");};
    202203                virtual void       ElementResponse(IssmDouble* presponse,int response_enum)=0;
    203204                virtual void       ElementSizes(IssmDouble* phx,IssmDouble* phy,IssmDouble* phz)=0;
     
    303304                virtual void       VerticalSegmentIndicesBase(int** pindices,int* pnumseg)=0;
    304305                virtual void       ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0;
     306                virtual void       WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue){_error_("not implemented yet");};
    305307                virtual void       WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};
    306308                virtual void       ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;
  • issm/trunk-jpl/src/c/classes/Elements/Penta.cpp

    r22330 r22379  
    21942194        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    21952195        GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
    2196         InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
    21972196
    21982197        /*Get distance from list of segments and reset ls*/
  • issm/trunk-jpl/src/c/classes/Elements/Tria.cpp

    r22349 r22379  
    525525}
    526526/*}}}*/
    527 void                    Tria::ComputeEsaStrainAndVorticity(){ /*{{{*/
     527void                        Tria::ComputeEsaStrainAndVorticity(){ /*{{{*/
    528528
    529529        IssmDouble  xyz_list[NUMVERTICES][3];
     
    762762
    763763}/*}}}*/
     764void       Tria::CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){/*{{{*/
     765
     766        /*Intermediaries*/
     767        IssmDouble d,xn,yn;
     768
     769        /*Get current field and vertex coordinates*/
     770        IssmDouble ls[NUMVERTICES];
     771        IssmDouble  xyz_list[NUMVERTICES][3];
     772        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     773        GetInputListOnVertices(&ls[0],distanceenum);
     774
     775        /*Get distance from list of segments and reset ls*/
     776        for(int j=0;j<NUMVERTICES;j++){
     777                IssmDouble dmin = 1.e+50;
     778                for(int i=0;i<numsegments;i++){
     779                        IssmDouble x = xyz_list[j][0];
     780                        IssmDouble y = xyz_list[j][1];
     781                        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]);
     782
     783                        /*Segment has a length of 0*/
     784                        if(l2==0.){
     785                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     786                                if(d<dmin) dmin = d;
     787                                continue;
     788                        }
     789
     790                        /*Consider the line extending the segment, parameterized as v + t (w - v).
     791                         *We find projection of point p onto the line.
     792                         *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
     793                        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;
     794                        if(t < 0.0){
     795                                // Beyond the 'v' end of the segment
     796                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     797                        }
     798                        else if (t > 1.0){
     799                                // Beyond the 'w' end of the segment
     800                                d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
     801                        }
     802                        else{
     803                                // Projection falls on the segment
     804                                xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
     805                                yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
     806                                d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
     807                        }
     808
     809                        if(d<dmin) dmin = d;
     810                }
     811
     812                /*Update signed distance*/
     813                dmin = sqrt(dmin);
     814                if(dmin>10000) dmin=10000;
     815                if(ls[j]>0){
     816                        ls[j] = dmin;
     817                }
     818                else{
     819                        ls[j] = - dmin;
     820                }
     821        }
     822
     823        /*Update Levelset*/
     824        this->inputs->AddInput(new TriaInput(distanceenum,&ls[0],P1Enum));
     825}
     826/*}}}*/
    764827int        Tria::EdgeOnBaseIndex(void){/*{{{*/
    765828
     
    14021465
    14031466}/*}}}*/
    1404 void                    Tria::GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/
     1467void       Tria::GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/
    14051468       
    14061469        /* GetLevelsetIntersection computes:
     
    28212884        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    28222885        GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
    2823         InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
    28242886
    28252887        /*Get distance from list of segments and reset ls*/
     
    35153577}
    35163578/*}}}*/
     3579void       Tria::WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue){/*{{{*/
     3580
     3581        _assert_(fieldvalue==0.); //field value != 0 not implemented yet
     3582
     3583        /*1. check that we do cross fieldvalue in this element*/
     3584        Input* input = inputs->GetInput(fieldenum);
     3585        if(!input) _error_("Cannot calculate distance to "<<EnumToStringx(fieldenum)<<", input not found");
     3586        IssmDouble minvalue = input->Min();
     3587        IssmDouble maxvalue = input->Max();
     3588        if(minvalue>fieldvalue || maxvalue<fieldvalue) return;
     3589
     3590
     3591        /*2. Write segments*/
     3592        IssmDouble* xyz_list_zero = NULL;
     3593        IssmDouble  xyz_list[NUMVERTICES][3];
     3594        ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
     3595        this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0],fieldenum);
     3596        if(xyz_list_zero){
     3597                IssmDouble x[2],y[2];
     3598                x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
     3599                y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
     3600                segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
     3601        }
     3602        xDelete<IssmDouble>(xyz_list_zero);
     3603}
     3604/*}}}*/
    35173605void       Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/
    35183606
  • issm/trunk-jpl/src/c/classes/Elements/Tria.h

    r22349 r22379  
    6565                void        ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
    6666                void        ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum);
     67                void        CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum);
    6768                int         EdgeOnBaseIndex();
    6869                void        EdgeOnBaseIndices(int* pindex1,int* pindex);
     
    136137                void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
    137138                void        VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");};
     139                void                    WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue);
    138140                void                    WriteLevelsetSegment(DataSet* segments);
    139141                void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
  • issm/trunk-jpl/src/c/classes/FemModel.cpp

    r22360 r22379  
    992992}
    993993/*}}}*/
     994void FemModel::DistanceToFieldValue(int fieldenum,IssmDouble fieldvalue,int distanceenum){/*{{{*/
     995
     996        /*recover my_rank:*/
     997        int my_rank   = IssmComm::GetRank();
     998        int num_procs = IssmComm::GetSize();
     999
     1000        /*Get domain type (2d or 3d)*/
     1001        int domaintype;
     1002        this->parameters->FindParam(&domaintype,DomainTypeEnum);
     1003
     1004        /*1: go throug all elements of this partition and figure out how many
     1005         * segments we have (corresopnding to field = value)*/
     1006        DataSet* segments=new DataSet();
     1007        for(int i=0;i<elements->Size();i++){
     1008                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1009                if(!element->IsOnBase()) continue;
     1010                Element* basalelement = element->SpawnBasalElement();
     1011                basalelement->WriteFieldIsovalueSegment(segments,fieldenum,fieldvalue);
     1012                if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
     1013        }
     1014
     1015        /*2: now get the segments from all partitions*/
     1016        int  segcount=segments->Size();
     1017        int* allsegcount=xNew<int>(num_procs);
     1018        ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1019        ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm());
     1020
     1021        /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/
     1022        int numseg_offset=0;
     1023        int numseg=0;
     1024        for(int i=0;i<my_rank;  i++) numseg_offset+=allsegcount[i];
     1025        for(int i=0;i<num_procs;i++) numseg+=allsegcount[i];
     1026        IssmDouble* segmentlist    = xNewZeroInit<IssmDouble>(4*numseg);
     1027        IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg);
     1028        for(int i=0;i<segments->Size();i++){
     1029                Contour<IssmDouble>* segment=(Contour<IssmDouble>*)segments->GetObjectByOffset(i);
     1030                _assert_(segment->nods == 2);
     1031                segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0];
     1032                segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0];
     1033                segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1];
     1034                segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1];
     1035        }
     1036        ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
     1037        delete segments;
     1038        xDelete<IssmDouble>(segmentlist);
     1039        xDelete<int>(allsegcount);
     1040
     1041        /*3: Add distance input to all elements*/
     1042        for(int i=0;i<elements->Size();i++){
     1043                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1044                if(!element->IsOnBase()) continue;
     1045                element->CreateDistanceInputFromSegmentlist(allsegmentlist,numseg,distanceenum);
     1046        }
     1047
     1048
     1049        /*Extrude if necessary*/
     1050        int elementtype;
     1051        this->parameters->FindParam(&elementtype,MeshElementtypeEnum);
     1052        if(elementtype==PentaEnum){
     1053                InputExtrudex(this,distanceenum,-1);
     1054        }
     1055        else if(elementtype==TriaEnum){
     1056                /*no need to extrude*/
     1057        }
     1058        else{
     1059                _error_("not implemented yet");
     1060        }
     1061
     1062        /*Clean up and return*/
     1063        xDelete<IssmDouble>(allsegmentlist);
     1064}/*}}}*/
    9941065void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/
    9951066
  • issm/trunk-jpl/src/c/classes/FemModel.h

    r22360 r22379  
    107107                void MinVyx(IssmDouble* presponse);
    108108                void MinVzx(IssmDouble* presponse);
     109                void DistanceToFieldValue(int fieldenum,IssmDouble fieldvalue,int distanceenum);
    109110                void ResetLevelset();
    110111                void StrainRateparallelx();
  • issm/trunk-jpl/src/c/modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryx.cpp

    r20066 r22379  
    2020        /*initialize thread parameters: */
    2121        DistanceToMaskBoundaryxThreadStruct gate;
    22         gate.distance    = distance;
    23         gate.x         = x;
    24         gate.y         = y;
    25         gate.mask         = mask;
    26         gate.nods      = nods;
     22        gate.distance = distance;
     23        gate.x        = x;
     24        gate.y        = y;
     25        gate.mask     = mask;
     26        gate.nods     = nods;
    2727
    2828        /*launch the thread manager with DistanceToMaskBoundaryxt as a core: */
  • issm/trunk-jpl/src/c/modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryxt.cpp

    r20115 r22379  
    3737        for(i=i0;i<i1;i++){
    3838
    39                 IssmDouble d0=pow(10.,10);
    40 
     39                IssmDouble d0=1.e+10;
    4140                IssmDouble xi,yi;
    4241               
Note: See TracChangeset for help on using the changeset viewer.