Open chrisknewman opened 2 years ago
// 1----3----5--... // | | | // | | | // 0----2----4--...// just assume large number of Gauss points to enable verifications that they are uncorrelated
{ int initial_seed = 12345; // initialize node_seed array with random number between 1 and 10000 std::mt19937 gen(initial_seed); int node_seed[NNODES]; std::uniform_int_distribution<> udist(1,10000); for(int i=0;i<NNODES;i++) { node_seed[i]=udist(gen); //std::cout<<"val = "<<node_seed[i]<<std::endl; } // initialize one seed for each element int element_seed[NELEMENTS]; for(int i=0;i<NELEMENTS;i++) { element_seed[i]=0; // loop over 4 nodes of this element for(int node=0;node<4;node++) { int node_index=2i+node; element_seed[i]+=node_seed[node_index]; } std::cout<<"Element seed = "<<element_seed[i]<<std::endl; } // now set random values at Gauss points double gauss_val[NELEMENTS][NGAUSS]; for(int i=0;i<NELEMENTS;i++) { std::mt19937 mt(element_seed[i]); std::normal_distribution<> normal_dist(0,1); for(int ig=0;ig<NGAUSS;ig++) { gauss_val[i][ig]=normal_dist(mt); } } // verify suite of numbers in each element are uncorrelated double max_dot=0.; for(int i=0;i<NELEMENTS;i++) { for(int j=0;j<i;j++) { double dot=0.; for(int ig=0;ig<NGAUSS;ig++) { dot+=gauss_val[i][ig]gauss_val[j][ig]; } dot/=(double)NGAUSS; std::cout<<"Element "<<i<<","<<j<<": dot="<<dot<<std::endl; max_dot = dot>max_dot ? dot : max_dot; } } std::cout<<"Max. dot product: "<<max_dot<<std::endl; // compute self-correlation for comparison double ref_dot=0.; for(int ig=0;ig<NGAUSS;ig++) { ref_dot+=gauss_val[0][ig]*gauss_val[0][ig]; } ref_dot/=(double)NGAUSS; std::cout<<"Reference dot="<<ref_dot<<std::endl; return 0; }
We could maybe skip the node_seed step and populate element_seed based on global id and timestep, then populate the random numbers at gauss points
@chrisknewman, can we close this? Or is there cleaning-up you'd like to do?
We will use JL's method with the following: