source:
issm/oecreview/Archive/25834-26739/ISSM-26481-26482.diff
Last change on this file was 26740, checked in by , 3 years ago | |
---|---|
File size: 16.4 KB |
-
../trunk-jpl/src/c/modules/OceanExchangeDatax/OceanExchangeDatax.cpp
59 59 ISSM_MPI_Bcast(&oceantime,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 60 60 femmodel->parameters->SetParam(oceangridnxsize,OceanGridNxEnum); 61 61 femmodel->parameters->SetParam(oceangridnysize,OceanGridNyEnum); 62 oceangridx=xNew<IssmDouble>(ngrids_ocean); 63 oceangridy=xNew<IssmDouble>(ngrids_ocean); 62 64 if(my_rank==0){ 63 oceangridx = xNew<IssmDouble>(ngrids_ocean);64 65 ISSM_MPI_Recv(oceangridx,ngrids_ocean,ISSM_MPI_DOUBLE,0,10001005,tomitgcmcomm,&status); 65 oceangridy = xNew<IssmDouble>(ngrids_ocean);66 66 ISSM_MPI_Recv(oceangridy,ngrids_ocean,ISSM_MPI_DOUBLE,0,10001006,tomitgcmcomm,&status); 67 67 68 68 /*Exchange varying parameters for the initialization*/ … … 69 69 ISSM_MPI_Send(&time,1,ISSM_MPI_DOUBLE,0,10001001,tomitgcmcomm); 70 70 ISSM_MPI_Recv(&oceantime,1,ISSM_MPI_DOUBLE,0,10001002,tomitgcmcomm,&status); 71 71 } 72 if(my_rank!=0){ 73 oceangridx=xNew<IssmDouble>(ngrids_ocean); 74 oceangridy=xNew<IssmDouble>(ngrids_ocean); 75 } 72 76 73 ISSM_MPI_Bcast(oceangridx,ngrids_ocean,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 77 74 ISSM_MPI_Bcast(oceangridy,ngrids_ocean,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 78 75 femmodel->parameters->SetParam(oceangridx,ngrids_ocean,OceanGridXEnum); -
../trunk-jpl/src/c/shared/Matrix/MatrixUtils.cpp
678 678 Lchol should point to an IssmDouble* of same dimensions as A*/ 679 679 680 680 /*ensure zero-initialization*/ 681 for(int i i=0;ii<(ndim*ndim);ii++) Lchol[ii]=0;;681 for(int i=0;i<(ndim*ndim);i++) Lchol[i]=0;; 682 682 683 for(int i i=0;ii<ndim;ii++){684 for(int j j{0};jj<=ii;jj++){683 for(int i=0;i<ndim;i++){ 684 for(int j=0;j<=i;j++){ 685 685 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); 695 690 } 696 691 } 697 692 } /*}}}*/ -
../trunk-jpl/src/c/classes/Elements/Element.cpp
3606 3606 3607 3607 const int numvertices = this->GetNumberOfVertices(); 3608 3608 int basinid; 3609 IssmDouble tspin,beta0_basin,beta1_basin,noisespin_basin; //initialize scalars3609 IssmDouble tspin,beta0_basin,beta1_basin,noisespin_basin; 3610 3610 IssmDouble* phi_basin = xNew<IssmDouble>(arorder); 3611 3611 IssmDouble* smbspin = xNew<IssmDouble>(numvertices*arorder); 3612 3612 3613 /*Get Basin ID */3613 /*Get Basin ID and Basin coefficients*/ 3614 3614 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]; 3618 3616 beta0_basin = beta0[basinid]; 3619 3617 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]; 3623 3623 IssmDouble* oldsmbspin = xNew<IssmDouble>(numvertices*arorder); 3624 for(int i i=0;ii<numvertices*arorder;ii++) oldsmbspin[ii]=smbspin[ii]; //copy smbspin in oldsmbspin3624 for(int i=0;i<numvertices*arorder;i++) oldsmbspin[i]=smbspin[i]; 3625 3625 3626 3626 for(int v=0;v<numvertices;v++){ 3627 3627 IssmDouble autoregressionterm = 0.; 3628 for(int i i=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]; 3629 3629 smbspin[v] = beta0_basin+beta1_basin*(tspin-tinit_ar)+autoregressionterm+noisespin_basin; //compute newest values in smbspin 3630 3630 } 3631 3631 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]; 3636 3634 3637 3635 xDelete<IssmDouble>(oldsmbspin); 3638 3636 } … … 3643 3641 xDelete<IssmDouble>(phi_basin); 3644 3642 }/*}}}*/ 3645 3643 void Element::Smbautoregression(bool isstepforar,int arorder,IssmDouble telapsed_ar,IssmDouble* beta0,IssmDouble* beta1,IssmDouble* phi,IssmDouble* noiseterms){/*{{{*/ 3644 3646 3645 const int numvertices = this->GetNumberOfVertices(); 3647 3646 int basinid,M,N; 3648 IssmDouble beta0_basin,beta1_basin,noise_basin; //initialize scalars3647 IssmDouble beta0_basin,beta1_basin,noise_basin; 3649 3648 IssmDouble* phi_basin = xNew<IssmDouble>(arorder); 3650 3649 IssmDouble* smblist = xNew<IssmDouble>(numvertices); 3651 IssmDouble* smbvaluesautoregression = NULL; //array for past SMB values that we are about to retrieve3650 IssmDouble* smbvaluesautoregression = NULL; 3652 3651 3652 /*Get Basin ID and Basin coefficients*/ 3653 3653 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]; 3656 3655 beta0_basin = beta0[basinid]; 3657 3656 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 3660 3660 /*If not AR model timestep: take the old SMB values*/ 3661 3661 if(isstepforar==false){ 3662 / /VV do something with the lapse rate here if needed (12Oct2021)3663 for(int i i=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]; 3664 3664 } 3665 3665 /*If AR model timestep: compute SMB values on vertices from AR*/ 3666 3666 else{ 3667 3667 for(int v=0;v<numvertices;v++){ 3668 3668 3669 /* compute autoregressive term*/3669 /*Compute autoregressive term*/ 3670 3670 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]; 3674 3672 3675 /* stochastic SMB value*/3673 /*Stochastic SMB value*/ 3676 3674 smblist[v] = beta0_basin+beta1_basin*telapsed_ar+autoregressionterm+noise_basin; 3677 3675 } 3678 3676 /*Update autoregression smb values*/ 3679 3677 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); 3686 3683 } 3687 3684 /*Add input to element*/ 3688 3685 this->AddInput(SmbMassBalanceEnum,smblist,P1Enum); -
../trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
147 147 148 148 }/*}}}*/ 149 149 void SmbautoregressionInitx(FemModel* femmodel){/*{{{*/ 150 150 151 /*Initialization step of Smbautoregressionx*/ 151 int M,N,Nphi,arorder,numbasins ;152 int M,N,Nphi,arorder,numbasins,my_rank; 152 153 IssmDouble starttime,tstep_ar,tinit_ar; 154 femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum); 155 femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum); 153 156 IssmDouble* beta0 = xNew<IssmDouble>(numbasins); 154 157 IssmDouble* beta1 = xNew<IssmDouble>(numbasins); 155 158 IssmDouble* phi = xNew<IssmDouble>(numbasins*arorder); … … 157 160 femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum); 158 161 femmodel->parameters->FindParam(&tstep_ar,SmbAutoregressionTimestepEnum); 159 162 femmodel->parameters->FindParam(&tinit_ar,SmbAutoregressionInitialTimeEnum); 160 femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum);161 femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum);162 163 femmodel->parameters->FindParam(&beta0,&M,SmbBeta0Enum); _assert_(M==numbasins); 163 164 femmodel->parameters->FindParam(&beta1,&M,SmbBeta1Enum); _assert_(M==numbasins); 164 165 femmodel->parameters->FindParam(&phi,&M,&Nphi,SmbPhiEnum); _assert_(M==numbasins); _assert_(Nphi==arorder); 165 166 femmodel->parameters->FindParam(&covmat,&M,&N,SmbCovmatEnum); _assert_(M==numbasins); _assert_(N==numbasins); 167 166 168 /*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 } 174 179 } 180 ISSM_MPI_Bcast(noisespin,numbasins*nspin,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 181 175 182 /*Initialize SmbValuesAutoregressionEnum*/ 176 183 for(Object* &object:femmodel->elements->objects){ 177 184 Element* element = xDynamicCast<Element*>(object); //generate element object 178 185 element->SmbautoregressionInit(numbasins,arorder,nspin,starttime,tstep_ar,tinit_ar,beta0,beta1,phi,noisespin); 179 186 } 187 180 188 /*Cleanup*/ 181 189 xDelete<IssmDouble>(beta0); 182 190 xDelete<IssmDouble>(beta1); … … 191 199 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 192 200 femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum); 193 201 femmodel->parameters->FindParam(&tstep_ar,SmbAutoregressionTimestepEnum); 202 194 203 /*Initialize module at first time step*/ 195 204 if(time<=starttime+dt){SmbautoregressionInitx(femmodel);} 196 205 /*Determine if this is a time step for the AR model*/ 197 bool isstepforar {false};206 bool isstepforar = false; 198 207 199 208 #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; 201 210 #else 202 211 _error_("not implemented yet"); 203 212 #endif 204 213 205 214 /*Load parameters*/ 206 int M,N,Nphi,arorder,numbasins ;215 int M,N,Nphi,arorder,numbasins,my_rank; 207 216 femmodel->parameters->FindParam(&numbasins,SmbNumBasinsEnum); 208 217 femmodel->parameters->FindParam(&arorder,SmbAutoregressiveOrderEnum); 209 218 IssmDouble tinit_ar; … … 218 227 femmodel->parameters->FindParam(&phi,&M,&Nphi,SmbPhiEnum); _assert_(M==numbasins); _assert_(Nphi==arorder); 219 228 femmodel->parameters->FindParam(&covmat,&M,&N,SmbCovmatEnum); _assert_(M==numbasins); _assert_(N==numbasins); 220 229 221 /* time elapsed with respect to AR model initial time*/230 /*Time elapsed with respect to AR model initial time*/ 222 231 IssmDouble telapsed_ar = time-tinit_ar; 223 232 224 233 /*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()); 226 239 227 240 /*Loop over each element to compute SMB at vertices*/ 228 241 for(Object* &object:femmodel->elements->objects){ -
../trunk-jpl/src/c/shared/Random/random.cpp
20 20 /*}}}*/ 21 21 22 22 void 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); 27 29 *prand = normdistri(generator); 28 30 } /*}}}*/ 29 31 void multivariateNormal(IssmDouble** prand, int dim, IssmDouble mean, IssmDouble* covariancematrix) { /*{{{*/ 30 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 32 33 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 31 34 IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim); 32 35 IssmDouble* Lchol = xNewZeroInit<IssmDouble>(dim*dim); 33 36 34 for(int i i=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); 35 38 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*/ 38 43 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; 43 46 } 44 47 45 48 /*Assign output pointer and cleanup*/ … … 48 51 xDelete<IssmDouble>(Lchol); 49 52 } /*}}}*/ 50 53 void multivariateNormal(IssmDouble** prand, int dim, IssmDouble* mean, IssmDouble* covariancematrix) { /*{{{*/ 51 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 54 55 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 52 56 IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim); 53 57 IssmDouble* Lchol = xNewZeroInit<IssmDouble>(dim*dim); 54 for(int i i=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); 55 59 56 60 CholeskyRealPositiveDefinite(Lchol,covariancematrix,dim); 57 61 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++){ 59 64 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; 64 67 } 68 69 /*Assign output pointer and cleanup*/ 65 70 *prand = sampleMultivariateNormal; 66 71 xDelete<IssmPDouble>(sampleStandardNormal); 67 72 xDelete<IssmDouble>(Lchol);
Note:
See TracBrowser
for help on using the repository browser.