source: issm/oecreview/Archive/25834-26739/ISSM-26481-26482.diff

Last change on this file was 26740, checked in by Mathieu Morlighem, 3 years ago

CHG: added 25834-26739

File size: 16.4 KB
  • ../trunk-jpl/src/c/modules/OceanExchangeDatax/OceanExchangeDatax.cpp

     
    5959                ISSM_MPI_Bcast(&oceantime,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    6060                femmodel->parameters->SetParam(oceangridnxsize,OceanGridNxEnum);
    6161                femmodel->parameters->SetParam(oceangridnysize,OceanGridNyEnum);
     62                oceangridx=xNew<IssmDouble>(ngrids_ocean);
     63                oceangridy=xNew<IssmDouble>(ngrids_ocean);
    6264                if(my_rank==0){
    63                         oceangridx = xNew<IssmDouble>(ngrids_ocean);
    6465                        ISSM_MPI_Recv(oceangridx,ngrids_ocean,ISSM_MPI_DOUBLE,0,10001005,tomitgcmcomm,&status);
    65                         oceangridy = xNew<IssmDouble>(ngrids_ocean);
    6666                        ISSM_MPI_Recv(oceangridy,ngrids_ocean,ISSM_MPI_DOUBLE,0,10001006,tomitgcmcomm,&status);
    6767
    6868                        /*Exchange varying parameters for the initialization*/
     
    6969                        ISSM_MPI_Send(&time,1,ISSM_MPI_DOUBLE,0,10001001,tomitgcmcomm);
    7070                        ISSM_MPI_Recv(&oceantime,1,ISSM_MPI_DOUBLE,0,10001002,tomitgcmcomm,&status);
    7171                }
    72                 if(my_rank!=0){
    73                         oceangridx=xNew<IssmDouble>(ngrids_ocean);
    74                         oceangridy=xNew<IssmDouble>(ngrids_ocean);
    75                 }
     72               
    7673                ISSM_MPI_Bcast(oceangridx,ngrids_ocean,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    7774                ISSM_MPI_Bcast(oceangridy,ngrids_ocean,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    7875                femmodel->parameters->SetParam(oceangridx,ngrids_ocean,OceanGridXEnum);
  • ../trunk-jpl/src/c/shared/Matrix/MatrixUtils.cpp

     
    678678   Lchol should point to an IssmDouble* of same dimensions as A*/
    679679
    680680        /*ensure zero-initialization*/
    681         for(int ii=0;ii<(ndim*ndim);ii++) Lchol[ii]=0;;
     681        for(int i=0;i<(ndim*ndim);i++) Lchol[i]=0;;
    682682
    683         for(int ii=0;ii<ndim;ii++){
    684                 for(int jj{0};jj<=ii;jj++){
     683        for(int i=0;i<ndim;i++){
     684                for(int j=0;j<=i;j++){
    685685                        IssmDouble sum=0.;
    686                         for(int kk{0};kk<jj;kk++){
    687                                 sum += Lchol[ii*ndim+kk]*Lchol[jj*ndim+kk];
    688                         }
    689                         if(ii==jj){
    690                                 Lchol[ii*ndim+jj] = sqrt(A[ii*ndim+jj]-sum);
    691                         }
    692                         else{
    693                                 Lchol[ii*ndim+jj] = 1./Lchol[jj*ndim+jj] * (A[ii*ndim+jj]-sum);
    694                         }
     686                        for(int k=0;k<j;k++) sum += Lchol[i*ndim+k]*Lchol[j*ndim+k];
     687                       
     688                        if(i==j) Lchol[i*ndim+j] = sqrt(A[i*ndim+j]-sum);
     689                        else Lchol[i*ndim+j]     = 1./Lchol[j*ndim+j] * (A[i*ndim+j]-sum);
    695690                }
    696691        }
    697692} /*}}}*/
  • ../trunk-jpl/src/c/classes/Elements/Element.cpp

     
    36063606
    36073607        const int numvertices = this->GetNumberOfVertices();
    36083608        int         basinid;
    3609         IssmDouble  tspin,beta0_basin,beta1_basin,noisespin_basin; //initialize scalars
     3609        IssmDouble  tspin,beta0_basin,beta1_basin,noisespin_basin;
    36103610        IssmDouble* phi_basin   = xNew<IssmDouble>(arorder);
    36113611   IssmDouble* smbspin     = xNew<IssmDouble>(numvertices*arorder);
    36123612
    3613         /*Get Basin ID*/
     3613        /*Get Basin ID and Basin coefficients*/
    36143614        this->GetInputValue(&basinid,SmbBasinsIdEnum);
    3615 
    3616         for(int ii=0;ii<arorder;ii++) phi_basin[ii] = phi[basinid*arorder+ii];
    3617 
     3615        for(int i=0;i<arorder;i++) phi_basin[i] = phi[basinid*arorder+i];
    36183616        beta0_basin   = beta0[basinid];
    36193617        beta1_basin   = beta1[basinid];
    3620         for(int jj=0;jj<nspin;jj++){   
    3621                 tspin = starttime-((nspin-jj)*tstep_ar); //current time in spin-up loop
    3622       noisespin_basin = noisespin[jj*numbasins+basinid];
     3618
     3619        /*Loop over number of spin-up steps for all vertices*/ 
     3620        for(int j=0;j<nspin;j++){       
     3621                tspin = starttime-((nspin-j)*tstep_ar);
     3622      noisespin_basin = noisespin[j*numbasins+basinid];
    36233623      IssmDouble* oldsmbspin = xNew<IssmDouble>(numvertices*arorder);
    3624       for(int ii=0;ii<numvertices*arorder;ii++) oldsmbspin[ii]=smbspin[ii]; //copy smbspin in oldsmbspin
     3624      for(int i=0;i<numvertices*arorder;i++) oldsmbspin[i]=smbspin[i];
    36253625
    36263626      for(int v=0;v<numvertices;v++){
    36273627         IssmDouble autoregressionterm = 0.;
    3628          for(int ii=0;ii<arorder;ii++) autoregressionterm += phi_basin[ii]*smbspin[v+ii*numvertices];
     3628         for(int i=0;i<arorder;i++) autoregressionterm += phi_basin[i]*smbspin[v+i*numvertices];
    36293629         smbspin[v] = beta0_basin+beta1_basin*(tspin-tinit_ar)+autoregressionterm+noisespin_basin; //compute newest values in smbspin
    36303630      }
    36313631
    3632                 /*correct older values in smbspin*/
    3633       for(int ii=0;ii<(arorder-1)*numvertices;ii++){
    3634                         smbspin[ii+numvertices]=oldsmbspin[ii];
    3635                 }
     3632                /*Correct older values in smbspin*/
     3633      for(int i=0;i<(arorder-1)*numvertices;i++) smbspin[i+numvertices]=oldsmbspin[i];
    36363634
    36373635      xDelete<IssmDouble>(oldsmbspin);
    36383636        }
     
    36433641   xDelete<IssmDouble>(phi_basin);
    36443642}/*}}}*/
    36453643void       Element::Smbautoregression(bool isstepforar,int arorder,IssmDouble telapsed_ar,IssmDouble* beta0,IssmDouble* beta1,IssmDouble* phi,IssmDouble* noiseterms){/*{{{*/
     3644       
    36463645        const int numvertices = this->GetNumberOfVertices();
    36473646        int         basinid,M,N;
    3648         IssmDouble  beta0_basin,beta1_basin,noise_basin; //initialize scalars
     3647        IssmDouble  beta0_basin,beta1_basin,noise_basin;
    36493648        IssmDouble* phi_basin  = xNew<IssmDouble>(arorder);
    36503649   IssmDouble* smblist    = xNew<IssmDouble>(numvertices);
    3651         IssmDouble* smbvaluesautoregression = NULL; //array for past SMB values that we are about to retrieve
     3650        IssmDouble* smbvaluesautoregression = NULL;
    36523651
     3652        /*Get Basin ID and Basin coefficients*/
    36533653        this->GetInputValue(&basinid,SmbBasinsIdEnum);
    3654 
    3655         for(int ii=0;ii<arorder;ii++){phi_basin[ii] = phi[basinid*arorder+ii];}
     3654        for(int ii=0;ii<arorder;ii++) phi_basin[ii] = phi[basinid*arorder+ii];
    36563655        beta0_basin   = beta0[basinid];
    36573656        beta1_basin   = beta1[basinid];
    3658         noise_basin   = noiseterms[basinid]; //note that noiseterms is computed at every timestep
    3659         this->inputs->GetArray(SmbValuesAutoregressionEnum,this->lid,&smbvaluesautoregression,&M); //get array of past SMB values to compute AR model
     3657        noise_basin   = noiseterms[basinid];
     3658        this->inputs->GetArray(SmbValuesAutoregressionEnum,this->lid,&smbvaluesautoregression,&M);
     3659
    36603660        /*If not AR model timestep: take the old SMB values*/
    36613661        if(isstepforar==false){
    3662                 //VV do something with the lapse rate here if needed (12Oct2021)
    3663       for(int ii=0;ii<numvertices;ii++){smblist[ii]=smbvaluesautoregression[ii];}
     3662                /*VV do something with the lapse rate here if needed (12Oct2021)*/
     3663      for(int i=0;i<numvertices;i++) smblist[i]=smbvaluesautoregression[i];
    36643664        }
    36653665        /*If AR model timestep: compute SMB values on vertices from AR*/
    36663666        else{
    36673667                for(int v=0;v<numvertices;v++){
    36683668
    3669                         /*compute autoregressive term*/
     3669                        /*Compute autoregressive term*/
    36703670                        IssmDouble autoregressionterm=0.;
    3671                         for(int ii=0;ii<arorder;ii++){
    3672                                 autoregressionterm += phi_basin[ii]*smbvaluesautoregression[v+ii*numvertices];
    3673                         }
     3671                        for(int ii=0;ii<arorder;ii++) autoregressionterm += phi_basin[ii]*smbvaluesautoregression[v+ii*numvertices];
    36743672
    3675                         /*stochastic SMB value*/
     3673                        /*Stochastic SMB value*/
    36763674                        smblist[v] = beta0_basin+beta1_basin*telapsed_ar+autoregressionterm+noise_basin;
    36773675                }
    36783676                /*Update autoregression smb values*/
    36793677                IssmDouble* temparray = xNew<IssmDouble>(numvertices*arorder);
    3680                 for(int ii=0;ii<numvertices;ii++) temparray[ii] = smblist[ii]; //first store newly computed smb values
    3681                 for(int ii=0;ii<(arorder-1)*numvertices;ii++){
    3682                         temparray[ii+numvertices] = smbvaluesautoregression[ii];
    3683                 } //second shift older smb values
    3684                 this->inputs->SetArrayInput(SmbValuesAutoregressionEnum,this->lid,temparray,numvertices*arorder); //save updated autoregression values
    3685                 xDelete<IssmDouble>(temparray); //cleanup
     3678                /*Assign newest values and shift older values*/
     3679                for(int i=0;i<numvertices;i++) temparray[i] = smblist[i];
     3680                for(int i=0;i<(arorder-1)*numvertices;i++) temparray[i+numvertices] = smbvaluesautoregression[i];
     3681                this->inputs->SetArrayInput(SmbValuesAutoregressionEnum,this->lid,temparray,numvertices*arorder);
     3682                xDelete<IssmDouble>(temparray);
    36863683        }
    36873684        /*Add input to element*/
    36883685        this->AddInput(SmbMassBalanceEnum,smblist,P1Enum);
  • ../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp

     
    147147
    148148}/*}}}*/
    149149void SmbautoregressionInitx(FemModel* femmodel){/*{{{*/
     150       
    150151        /*Initialization step of Smbautoregressionx*/
    151         int M,N,Nphi,arorder,numbasins;
     152        int M,N,Nphi,arorder,numbasins,my_rank;
    152153        IssmDouble starttime,tstep_ar,tinit_ar;
     154        femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum);
     155        femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum);
    153156        IssmDouble* beta0    = xNew<IssmDouble>(numbasins);
    154157        IssmDouble* beta1    = xNew<IssmDouble>(numbasins);
    155158        IssmDouble* phi      = xNew<IssmDouble>(numbasins*arorder);
     
    157160        femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
    158161   femmodel->parameters->FindParam(&tstep_ar,SmbAutoregressionTimestepEnum);
    159162        femmodel->parameters->FindParam(&tinit_ar,SmbAutoregressionInitialTimeEnum);
    160         femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum);
    161         femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum);
    162163        femmodel->parameters->FindParam(&beta0,&M,SmbBeta0Enum);    _assert_(M==numbasins);
    163164        femmodel->parameters->FindParam(&beta1,&M,SmbBeta1Enum);    _assert_(M==numbasins);
    164165        femmodel->parameters->FindParam(&phi,&M,&Nphi,SmbPhiEnum);  _assert_(M==numbasins); _assert_(Nphi==arorder);
    165166        femmodel->parameters->FindParam(&covmat,&M,&N,SmbCovmatEnum); _assert_(M==numbasins); _assert_(N==numbasins);
     167       
    166168        /*AR model spin-up*/
    167         int nspin{2*arorder+5}; //number of spin-up steps to be executed
    168         IssmDouble* noisespin = xNewZeroInit<IssmDouble>(numbasins*nspin); //sample of basin-specific noise at each spinup step
    169         for(int ii{0};ii<nspin;ii++){
    170                 IssmDouble* temparray = xNew<IssmDouble>(numbasins);
    171                 multivariateNormal(&temparray,numbasins,0.0,covmat);
    172                 for(int jj{0};jj<numbasins;jj++){noisespin[ii*numbasins+jj]=temparray[jj];}
    173                 xDelete<IssmDouble>(temparray);
     169        int nspin{2*arorder+5};
     170        IssmDouble* noisespin = xNewZeroInit<IssmDouble>(numbasins*nspin);
     171        my_rank=IssmComm::GetRank();
     172        if(my_rank==0){
     173                for(int i=0;i<nspin;i++){
     174                        IssmDouble* temparray = xNew<IssmDouble>(numbasins);
     175                        multivariateNormal(&temparray,numbasins,0.0,covmat);
     176                        for(int j=0;j<numbasins;j++){noisespin[i*numbasins+j]=temparray[j];}
     177                        xDelete<IssmDouble>(temparray);
     178                }
    174179        }
     180        ISSM_MPI_Bcast(noisespin,numbasins*nspin,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     181       
    175182        /*Initialize SmbValuesAutoregressionEnum*/
    176183        for(Object* &object:femmodel->elements->objects){
    177184      Element* element      = xDynamicCast<Element*>(object); //generate element object
    178185                element->SmbautoregressionInit(numbasins,arorder,nspin,starttime,tstep_ar,tinit_ar,beta0,beta1,phi,noisespin);
    179186        }
     187       
    180188        /*Cleanup*/
    181189        xDelete<IssmDouble>(beta0);
    182190        xDelete<IssmDouble>(beta1);
     
    191199        femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
    192200        femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
    193201   femmodel->parameters->FindParam(&tstep_ar,SmbAutoregressionTimestepEnum);
     202
    194203        /*Initialize module at first time step*/
    195204        if(time<=starttime+dt){SmbautoregressionInitx(femmodel);}
    196205        /*Determine if this is a time step for the AR model*/
    197         bool isstepforar{false};
     206        bool isstepforar = false;
    198207
    199208        #ifndef _HAVE_AD_
    200    if((fmod(time,tstep_ar)<fmod((time-dt),tstep_ar)) || (time<=starttime+dt) || tstep_ar==dt){isstepforar = true;}
     209   if((fmod(time,tstep_ar)<fmod((time-dt),tstep_ar)) || (time<=starttime+dt) || tstep_ar==dt) isstepforar = true;
    201210        #else
    202211        _error_("not implemented yet");
    203212        #endif
    204213
    205214        /*Load parameters*/
    206         int M,N,Nphi,arorder,numbasins;
     215        int M,N,Nphi,arorder,numbasins,my_rank;
    207216        femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum);
    208217        femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum);
    209218        IssmDouble tinit_ar;
     
    218227        femmodel->parameters->FindParam(&phi,&M,&Nphi,SmbPhiEnum);  _assert_(M==numbasins); _assert_(Nphi==arorder);
    219228        femmodel->parameters->FindParam(&covmat,&M,&N,SmbCovmatEnum); _assert_(M==numbasins); _assert_(N==numbasins);
    220229
    221         /*time elapsed with respect to AR model initial time*/
     230        /*Time elapsed with respect to AR model initial time*/
    222231        IssmDouble telapsed_ar = time-tinit_ar;
    223232
    224233        /*Before looping through elements: compute noise term specific to each basin from covmat*/
    225         multivariateNormal(&noiseterms,numbasins,0.0,covmat);
     234        my_rank=IssmComm::GetRank();
     235        if(my_rank==0){
     236                multivariateNormal(&noiseterms,numbasins,0.0,covmat);
     237        }
     238        ISSM_MPI_Bcast(noiseterms,numbasins,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    226239
    227240        /*Loop over each element to compute SMB at vertices*/
    228241        for(Object* &object:femmodel->elements->objects){
  • ../trunk-jpl/src/c/shared/Random/random.cpp

     
    2020/*}}}*/
    2121
    2222void univariateNormal(IssmPDouble* prand, IssmPDouble mean, IssmPDouble sdev) { /*{{{*/
    23         /*univariateNormal      generates a random value follwoing Normal distribution*/
    24         unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count(); //random seed using time_since_epoch
    25    std::default_random_engine generator(seed); //generator of random numbers
    26    std::normal_distribution<IssmPDouble> normdistri(mean,sdev); //Normal probability distribution
     23
     24        /*Random seed using time_since_epoch*/
     25        unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count();
     26   std::default_random_engine generator(seed);
     27        /*Normal Probability Distribution*/
     28   std::normal_distribution<IssmPDouble> normdistri(mean,sdev);
    2729        *prand = normdistri(generator);
    2830} /*}}}*/
    2931void multivariateNormal(IssmDouble** prand, int dim, IssmDouble mean, IssmDouble* covariancematrix) { /*{{{*/
    30    IssmPDouble* sampleStandardNormal     = xNew<IssmPDouble>(dim);
     32   
     33        IssmPDouble* sampleStandardNormal    = xNew<IssmPDouble>(dim);
    3134   IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim);
    3235   IssmDouble* Lchol                    = xNewZeroInit<IssmDouble>(dim*dim);
    3336
    34    for(int ii=0;ii<dim;ii++){univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0);}
     37   for(int i=0;i<dim;i++) univariateNormal(&(sampleStandardNormal[i]),0.0,1.0);
    3538   CholeskyRealPositiveDefinite(Lchol,covariancematrix,dim);
    36    for(int ii=0;ii<dim;ii++){ //matrix by vector multiplication
    37       /*entry-by-entry multiplication along matrix row*/
     39   
     40        /*Matrix by vector multiplication*/
     41        for(int i=0;i<dim;i++){
     42      /*Entry-by-entry multiplication along matrix row*/
    3843      IssmDouble sum=0.;
    39       for(int jj{0};jj<dim;jj++){
    40          sum += sampleStandardNormal[jj]*Lchol[ii*dim+jj];
    41       }
    42       sampleMultivariateNormal[ii] = mean+sum;
     44      for(int j=0;j<dim;j++) sum += sampleStandardNormal[j]*Lchol[i*dim+j];
     45      sampleMultivariateNormal[i] = mean+sum;
    4346   }
    4447
    4548   /*Assign output pointer and cleanup*/
     
    4851   xDelete<IssmDouble>(Lchol);
    4952} /*}}}*/
    5053void multivariateNormal(IssmDouble** prand, int dim, IssmDouble* mean, IssmDouble* covariancematrix) { /*{{{*/
    51         IssmPDouble* sampleStandardNormal     = xNew<IssmPDouble>(dim);
     54       
     55        IssmPDouble* sampleStandardNormal    = xNew<IssmPDouble>(dim);
    5256        IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim);
    5357        IssmDouble* Lchol                    = xNewZeroInit<IssmDouble>(dim*dim);
    54         for(int ii=0;ii<dim;ii++) univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0);
     58        for(int i=0;i<dim;i++) univariateNormal(&(sampleStandardNormal[i]),0.0,1.0);
    5559
    5660        CholeskyRealPositiveDefinite(Lchol,covariancematrix,dim);
    5761
    58         for(int ii=0;ii<dim;ii++){ //matrix by vector multiplication
     62        /*Matrix by vector multiplication*/
     63        for(int i=0;i<dim;i++){
    5964                IssmDouble sum = 0.;
    60       for(int jj=0.;jj<dim;jj++){
    61                         sum += sampleStandardNormal[jj]*Lchol[ii*dim+jj];
    62                 }
    63       sampleMultivariateNormal[ii] = mean[ii]+sum; //assign value
     65      for(int j=0;j<dim;j++) sum += sampleStandardNormal[j]*Lchol[i*dim+j];
     66      sampleMultivariateNormal[i] = mean[i]+sum;
    6467        }
     68   
     69        /*Assign output pointer and cleanup*/
    6570        *prand = sampleMultivariateNormal;
    6671        xDelete<IssmPDouble>(sampleStandardNormal);
    6772        xDelete<IssmDouble>(Lchol);
Note: See TracBrowser for help on using the repository browser.