Changeset 26479
- Timestamp:
- 10/13/21 09:57:34 (3 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/Elements/Element.cpp
r26478 r26479 3604 3604 /*}}}*/ 3605 3605 void Element::SmbautoregressionInit(int numbasins,int arorder,int nspin,IssmDouble starttime,IssmDouble tstep_ar,IssmDouble tinit_ar,IssmDouble* beta0,IssmDouble* beta1,IssmDouble* phi,IssmDouble* noisespin){/*{{{*/ 3606 3606 3607 const int numvertices = this->GetNumberOfVertices(); 3607 3608 int basinid; 3608 3609 IssmDouble tspin,beta0_basin,beta1_basin,noisespin_basin; //initialize scalars 3609 IssmDouble* phi_basin = xNew<IssmDouble>(arorder); 3610 IssmDouble* smbspin = xNew<IssmDouble>(numvertices*arorder); 3610 IssmDouble* phi_basin = xNew<IssmDouble>(arorder); 3611 IssmDouble* smbspin = xNew<IssmDouble>(numvertices*arorder); 3612 3613 /*Get Basin ID*/ 3611 3614 this->GetInputValue(&basinid,SmbBasinsIdEnum); 3612 for(int ii{0};ii<arorder;ii++){phi_basin[ii] = phi[basinid*arorder+ii];} 3615 3616 for(int ii=0;ii<arorder;ii++) phi_basin[ii] = phi[basinid*arorder+ii]; 3617 3613 3618 beta0_basin = beta0[basinid]; 3614 3619 beta1_basin = beta1[basinid]; 3615 for(int jj {0};jj<nspin;jj++){3620 for(int jj=0;jj<nspin;jj++){ 3616 3621 tspin = starttime-((nspin-jj)*tstep_ar); //current time in spin-up loop 3617 3622 noisespin_basin = noisespin[jj*numbasins+basinid]; 3618 IssmDouble* oldsmbspin = xNewZeroInit<IssmDouble>(numvertices*arorder); 3619 for(int ii{0};ii<numvertices*arorder;ii++){oldsmbspin[ii]=smbspin[ii];} //copy smbspin in oldsmbspin 3623 IssmDouble* oldsmbspin = xNew<IssmDouble>(numvertices*arorder); 3624 for(int ii=0;ii<numvertices*arorder;ii++) oldsmbspin[ii]=smbspin[ii]; //copy smbspin in oldsmbspin 3625 3620 3626 for(int v=0;v<numvertices;v++){ 3621 double autoregressionterm{0.0};3622 for(int ii {0};ii<arorder;ii++){autoregressionterm += phi_basin[ii]*smbspin[v+ii*numvertices];}3627 IssmDouble autoregressionterm = 0.; 3628 for(int ii=0;ii<arorder;ii++) autoregressionterm += phi_basin[ii]*smbspin[v+ii*numvertices]; 3623 3629 smbspin[v] = beta0_basin+beta1_basin*(tspin-tinit_ar)+autoregressionterm+noisespin_basin; //compute newest values in smbspin 3624 3630 } 3625 for(int ii{0};ii<(arorder-1)*numvertices;ii++){smbspin[ii+numvertices]=oldsmbspin[ii];} //correct older values in smbspin 3626 xDelete<IssmDouble>(oldsmbspin); //cleanup 3627 } 3628 this->inputs->SetArrayInput(SmbValuesAutoregressionEnum,this->lid,smbspin,numvertices*arorder);//save spin-up autoregression values 3629 xDelete<IssmDouble>(smbspin); //cleanup 3630 xDelete<IssmDouble>(phi_basin); //cleanup 3631 3632 /*correct older values in smbspin*/ 3633 for(int ii=0;ii<(arorder-1)*numvertices;ii++){ 3634 smbspin[ii+numvertices]=oldsmbspin[ii]; 3635 } 3636 3637 xDelete<IssmDouble>(oldsmbspin); 3638 } 3639 this->inputs->SetArrayInput(SmbValuesAutoregressionEnum,this->lid,smbspin,numvertices*arorder); 3640 3641 /*Cleanup and return*/ 3642 xDelete<IssmDouble>(smbspin); 3643 xDelete<IssmDouble>(phi_basin); 3631 3644 }/*}}}*/ 3632 3645 void Element::Smbautoregression(bool isstepforar,int arorder,IssmDouble telapsed_ar,IssmDouble* beta0,IssmDouble* beta1,IssmDouble* phi,IssmDouble* noiseterms){/*{{{*/ … … 3634 3647 int basinid,M,N; 3635 3648 IssmDouble beta0_basin,beta1_basin,noise_basin; //initialize scalars 3636 IssmDouble* phi_basin 3637 IssmDouble* smblist 3649 IssmDouble* phi_basin = xNew<IssmDouble>(arorder); 3650 IssmDouble* smblist = xNew<IssmDouble>(numvertices); 3638 3651 IssmDouble* smbvaluesautoregression = NULL; //array for past SMB values that we are about to retrieve 3652 3639 3653 this->GetInputValue(&basinid,SmbBasinsIdEnum); 3640 for(int ii{0};ii<arorder;ii++){phi_basin[ii] = phi[basinid*arorder+ii];} 3654 3655 for(int ii=0;ii<arorder;ii++){phi_basin[ii] = phi[basinid*arorder+ii];} 3641 3656 beta0_basin = beta0[basinid]; 3642 3657 beta1_basin = beta1[basinid]; … … 3646 3661 if(isstepforar==false){ 3647 3662 //VV do something with the lapse rate here if needed (12Oct2021) 3648 for(int ii {0};ii<numvertices;ii++){smblist[ii]=smbvaluesautoregression[ii];}3663 for(int ii=0;ii<numvertices;ii++){smblist[ii]=smbvaluesautoregression[ii];} 3649 3664 } 3650 3665 /*If AR model timestep: compute SMB values on vertices from AR*/ 3651 3666 else{ 3652 3667 for(int v=0;v<numvertices;v++){ 3653 double autoregressionterm{0.0}; 3654 for(int ii{0};ii<arorder;ii++){autoregressionterm += phi_basin[ii]*smbvaluesautoregression[v+ii*numvertices];} //compute autoregressive term 3655 smblist[v] = beta0_basin+beta1_basin*telapsed_ar+autoregressionterm+noise_basin; //stochastic SMB value 3668 3669 /*compute autoregressive term*/ 3670 IssmDouble autoregressionterm=0.; 3671 for(int ii=0;ii<arorder;ii++){ 3672 autoregressionterm += phi_basin[ii]*smbvaluesautoregression[v+ii*numvertices]; 3673 } 3674 3675 /*stochastic SMB value*/ 3676 smblist[v] = beta0_basin+beta1_basin*telapsed_ar+autoregressionterm+noise_basin; 3656 3677 } 3657 3678 /*Update autoregression smb values*/ 3658 3679 IssmDouble* temparray = xNew<IssmDouble>(numvertices*arorder); 3659 for(int ii{0};ii<numvertices;ii++){temparray[ii] = smblist[ii];} //first store newly computed smb values 3660 for(int ii{0};ii<(arorder-1)*numvertices;ii++){temparray[ii+numvertices] = smbvaluesautoregression[ii];} //second shift older smb values 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 3661 3684 this->inputs->SetArrayInput(SmbValuesAutoregressionEnum,this->lid,temparray,numvertices*arorder); //save updated autoregression values 3662 3685 xDelete<IssmDouble>(temparray); //cleanup … … 3664 3687 /*Add input to element*/ 3665 3688 this->AddInput(SmbMassBalanceEnum,smblist,P1Enum); 3689 3666 3690 /*Cleanup*/ 3667 3691 xDelete<IssmDouble>(phi_basin); -
issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
r26477 r26479 3 3 */ 4 4 5 #include <config.h> 5 6 #include "./SurfaceMassBalancex.h" 6 7 #include "../../shared/shared.h" … … 195 196 /*Determine if this is a time step for the AR model*/ 196 197 bool isstepforar{false}; 197 if((std::fmod(time,tstep_ar)<std::fmod((time-dt),tstep_ar)) || (time<=starttime+dt) || tstep_ar==dt){isstepforar = true;} 198 199 #ifndef _HAVE_AD_ 200 if((fmod(time,tstep_ar)<fmod((time-dt),tstep_ar)) || (time<=starttime+dt) || tstep_ar==dt){isstepforar = true;} 201 #else 202 _error_("not implemented yet"); 203 #endif 204 198 205 /*Load parameters*/ 199 206 int M,N,Nphi,arorder,numbasins; -
issm/trunk-jpl/src/c/shared/Matrix/MatrixUtils.cpp
r26477 r26479 677 677 Follows the Cholesky–Banachiewicz algorithm 678 678 Lchol should point to an IssmDouble* of same dimensions as A*/ 679 for(int ii{0};ii<(ndim*ndim);ii++){Lchol[ii]=0;}; //ensure zero-initialization 680 for(int ii{0};ii<ndim;ii++){ 681 for(int jj{0};jj<=ii;jj++){ 682 double sum{0.0}; 683 for(int kk{0};kk<jj;kk++) { 684 sum += Lchol[ii*ndim+kk]*Lchol[jj*ndim+kk]; 685 } 686 if(ii==jj){Lchol[ii*ndim+jj] = sqrt(A[ii*ndim+jj]-sum);} 687 else{Lchol[ii*ndim+jj] = 1/Lchol[jj*ndim+jj] * (A[ii*ndim+jj]-sum);} 688 } 689 } 679 680 /*ensure zero-initialization*/ 681 for(int ii=0;ii<(ndim*ndim);ii++) Lchol[ii]=0;; 682 683 for(int ii=0;ii<ndim;ii++){ 684 for(int jj{0};jj<=ii;jj++){ 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 } 695 } 696 } 690 697 } /*}}}*/ -
issm/trunk-jpl/src/c/shared/Random/random.cpp
r26477 r26479 20 20 /*}}}*/ 21 21 22 void univariateNormal(Issm Double* prand, IssmDouble mean, IssmDouble sdev) { /*{{{*/22 void univariateNormal(IssmPDouble* prand, IssmPDouble mean, IssmPDouble sdev) { /*{{{*/ 23 23 /*univariateNormal generates a random value follwoing Normal distribution*/ 24 24 unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count(); //random seed using time_since_epoch 25 25 std::default_random_engine generator(seed); //generator of random numbers 26 std::normal_distribution<double> normdistri(mean,sdev); //Normal probability distribution 27 double tfunc; 26 std::normal_distribution<IssmPDouble> normdistri(mean,sdev); //Normal probability distribution 28 27 *prand = normdistri(generator); 29 28 } /*}}}*/ 30 29 void multivariateNormal(IssmDouble** prand, int dim, IssmDouble mean, IssmDouble* covariancematrix) { /*{{{*/ 31 Issm Double* sampleStandardNormal = xNew<IssmDouble>(dim);30 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 32 31 IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim); 33 32 IssmDouble* Lchol = xNewZeroInit<IssmDouble>(dim*dim); 34 for(int ii{0};ii<dim;ii++){univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0);} 33 34 for(int ii=0;ii<dim;ii++){univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0);} 35 35 CholeskyRealPositiveDefinite(Lchol,covariancematrix,dim); 36 for(int ii{0};ii<dim;ii++){ //matrix by vector multiplication 37 double sum{0.0}; 38 for(int jj{0};jj<dim;jj++){sum += sampleStandardNormal[jj]*Lchol[ii*dim+jj];} //entry-by-entry multiplication along matrix row 39 sampleMultivariateNormal[ii] = mean+sum; //assign value 36 for(int ii=0;ii<dim;ii++){ //matrix by vector multiplication 37 /*entry-by-entry multiplication along matrix row*/ 38 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; 40 43 } 44 45 /*Assign output pointer and cleanup*/ 41 46 *prand = sampleMultivariateNormal; 42 xDelete<Issm Double>(sampleStandardNormal);47 xDelete<IssmPDouble>(sampleStandardNormal); 43 48 xDelete<IssmDouble>(Lchol); 44 49 } /*}}}*/ 45 50 void multivariateNormal(IssmDouble** prand, int dim, IssmDouble* mean, IssmDouble* covariancematrix) { /*{{{*/ 46 Issm Double* sampleStandardNormal = xNew<IssmDouble>(dim);51 IssmPDouble* sampleStandardNormal = xNew<IssmPDouble>(dim); 47 52 IssmDouble* sampleMultivariateNormal = xNew<IssmDouble>(dim); 48 53 IssmDouble* Lchol = xNewZeroInit<IssmDouble>(dim*dim); 49 for(int ii{0};ii<dim;ii++){univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0);} 54 for(int ii=0;ii<dim;ii++) univariateNormal(&(sampleStandardNormal[ii]),0.0,1.0); 55 50 56 CholeskyRealPositiveDefinite(Lchol,covariancematrix,dim); 51 for(int ii{0};ii<dim;ii++){ //matrix by vector multiplication 52 double sum{0.0}; 53 for(int jj{0};jj<dim;jj++){sum += sampleStandardNormal[jj]*Lchol[ii*dim+jj];} //entry-by-entry multiplication along matrix row 57 58 for(int ii=0;ii<dim;ii++){ //matrix by vector multiplication 59 IssmDouble sum = 0.; 60 for(int jj=0.;jj<dim;jj++){ 61 sum += sampleStandardNormal[jj]*Lchol[ii*dim+jj]; 62 } 54 63 sampleMultivariateNormal[ii] = mean[ii]+sum; //assign value 55 64 } 56 65 *prand = sampleMultivariateNormal; 57 xDelete<Issm Double>(sampleStandardNormal);66 xDelete<IssmPDouble>(sampleStandardNormal); 58 67 xDelete<IssmDouble>(Lchol); 59 68 } /*}}}*/
Note:
See TracChangeset
for help on using the changeset viewer.