static inline unsigned long int ranlux_get (void *vstate) { ranlux_state_t *state = (ranlux_state_t *) vstate; const unsigned int skip = state->skip; unsigned long int r = increment_state (state); state->n++; if (state->n == 24) { unsigned int i; state->n = 0; for (i = 0; i < skip; i++) increment_state (state); } return r; }
static inline double ranlxs_get_double (void *vstate) { ranlxs_state_t *state = (ranlxs_state_t *) vstate; const unsigned int is = snext[state->is]; state->is = is; if (is == state->is_old) increment_state (state); return state->xflt[state->is]; }
static double ranlxd_get_double (void *vstate) { ranlxd_state_t *state = (ranlxd_state_t *) vstate; int ir = state->ir; state->ir = next[ir]; if (state->ir == state->ir_old) increment_state (state); return state->xdbl[state->ir]; }
void calc_jacobian_old(MeshCTX* meshctx, PropCTX* propctx) { int myid, numprocs; MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); HashTable* El_Table = meshctx->el_table; HashTable* NodeTable = meshctx->nd_table; TimeProps* timeprops_ptr = propctx->timeprops; MapNames* mapname_ptr = propctx->mapnames; MatProps* matprops_ptr = propctx->matprops; int neigh_flag; HashEntryPtr* buck = El_Table->getbucketptr(); HashEntryPtr currentPtr; DualElem* Curr_El = NULL; int iter = timeprops_ptr->iter; double tiny = GEOFLOW_TINY; //this array holds ResFlag for element itself and its neighbors ResFlag resflag[EFF_ELL]; reset_resflag(resflag); #ifdef DEBUGFILE ofstream myfile; myfile.open("debug.txt",ios::app); #endif for (int i = 0; i < El_Table->get_no_of_buckets(); i++) { if (*(buck + i)) { currentPtr = *(buck + i); while (currentPtr) { Curr_El = (DualElem*) (currentPtr->value); if (Curr_El->get_adapted_flag() > 0 && (Curr_El->get_ithelem() == 722 || Curr_El->get_ithelem() == 730 || Curr_El->get_ithelem() == 723 || Curr_El->get_ithelem() == 725 || Curr_El->get_ithelem() == 724 || Curr_El->get_ithelem() == 726 || Curr_El->get_ithelem() == 749 || Curr_El->get_ithelem() == 880 || Curr_El->get_ithelem() == 884 || Curr_El->get_ithelem() == 1329 || Curr_El->get_ithelem() == 1333)) { int boundary = 0; //this part handles if the Curr_El is a boundary element //cout<<"I am running do not worry"<<endl; for (int neighnum = 0; neighnum < 4; neighnum++) if (*(Curr_El->get_neigh_proc() + neighnum) == INIT) { boundary = 1; // this for the element that are on the boundary Curr_El->set_jacobian(); break; } if (!boundary) { double state_vars[NUM_STATE_VARS], gravity[NUM_STATE_VARS]; double d_gravity[DIMENSION], curvature[DIMENSION]; double d_state_vars_old[NUM_STATE_VARS * DIMENSION]; double prev_state_vars_old[NUM_STATE_VARS * DIMENSION]; double *prev_state_vars = Curr_El->get_prev_state_vars(); Curr_El->calc_stop_crit(matprops_ptr); //this function updates bedfric properties double bedfrict = Curr_El->get_effect_bedfrict(); double dx[DIMENSION] = { *(Curr_El->get_dx()), *(Curr_El->get_dx() + 1) }; double kactxy[DIMENSION]; double orgSrcSgn[DIMENSION]; int check_stop[DIMENSION] = { 0, 0 }; for (int ind = 0; ind < NUM_STATE_VARS; ++ind) gravity[ind] = *(Curr_El->get_gravity() + ind); for (int ind = 0; ind < DIMENSION; ++ind) { d_gravity[ind] = *(Curr_El->get_d_gravity() + ind); curvature[ind] = *(Curr_El->get_curvature() + ind); } for (int ind = 0; ind < NUM_STATE_VARS * DIMENSION; ++ind) d_state_vars_old[ind] = *(Curr_El->get_d_state_vars() + ind); for (int ind = 0; ind < NUM_STATE_VARS * DIMENSION; ++ind) prev_state_vars_old[ind] = *(Curr_El->get_prev_state_vars() + ind); if (timeprops_ptr->iter < 51) matprops_ptr->frict_tiny = 0.1; else matprops_ptr->frict_tiny = 0.000000001; orgSourceSgn(Curr_El, matprops_ptr->frict_tiny, orgSrcSgn); double fluxold[4][NUM_STATE_VARS]; record_flux(El_Table, NodeTable, Curr_El->pass_key(), matprops_ptr, myid, fluxold); double dt = timeprops_ptr->dt.at(iter - 1); //at final time step we do not need the computation of adjoint and we always compute it for the previouse time so we need iter. double dtdx = dt / dx[0]; double dtdy = dt / dx[1]; double org_res[NUM_STATE_VARS]; int gggflag = 0; if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1 && iter == ITER) gggflag = 1; residual(org_res, Curr_El->get_state_vars(), prev_state_vars, fluxold[0], //4 fluxold[1], fluxold[2], fluxold[3], dtdx, dtdy, dt, d_state_vars_old, //7 (d_state_vars_old + NUM_STATE_VARS), curvature, //2 matprops_ptr->intfrict, //1 bedfrict, gravity, d_gravity, *(Curr_El->get_kactxy()), //4 matprops_ptr->frict_tiny, orgSrcSgn, 0./*=increment*/, //3 matprops_ptr->epsilon, check_stop); //2 for (int side = 0; side < 4; side++) if (*(Curr_El->get_neigh_proc() + side) == INIT) // this is a boundary! for (int ind = 0; ind < NUM_STATE_VARS; ind++) *(Curr_El->get_state_vars() + ind) = 0; for (int ind = 0; ind < NUM_STATE_VARS; ++ind) state_vars[ind] = *(Curr_El->get_state_vars() + ind); for (int effelement = 0; effelement < EFF_ELL; effelement++) { //0 for the element itself, and the rest id for neighbour elements #ifdef DEBUG int gggflag = 0; if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1 && iter == ITER && effelement == EFFELL) gggflag = 1; #endif if (effelement == 0 && prev_state_vars[0] == 0.) //this is a void element so the residual vector does not change by changing it's values Curr_El->set_jacobianMat_zero(effelement); else if (effelement > 4 && compare_key((Curr_El->get_neighbors() + (effelement - 1) * KEYLENGTH), (Curr_El->get_neighbors() + (effelement - 5) * KEYLENGTH))) Curr_El->set_jacobianMat_zero(effelement); else if (effelement != 0 && void_neigh_elem(El_Table, Curr_El, effelement)) //this is a void neighbor element so the residual of the curr_el does not depend on this neighbor Curr_El->set_jacobianMat_zero(effelement); else if (effelement > 0 && *(Curr_El->get_neigh_proc() + (effelement - 1)) == INIT) Curr_El->set_jacobianMat_zero(effelement); else { for (int j = 0; j < NUM_STATE_VARS; j++) { //there is a problem here: I do not need to compute for first the component of adjoint double vec_res[NUM_STATE_VARS]; double total_res[NUM_STATE_VARS] = { 0., 0., 0. }; int scheme = 0; for (; scheme < 1; scheme++) { //this flag shows that the pileheight before adding the increment is below or above the GEOFLOW_TINY. //if it is below GEOFLOW_TINY then there is no need to update fluxes and kactxy int updateflux, srcflag; reset_resflag(resflag); // here we modify increment to one time compute forward and one time compute backward difference if it is necessary double signe = pow(-1., scheme); double incr = signe * INCREMENT; increment_state(El_Table, Curr_El, incr, effelement, j, &updateflux, &srcflag, resflag); calc_flux_slope_kact(El_Table, NodeTable, Curr_El, matprops_ptr, myid, effelement, updateflux, srcflag, resflag); //Attention make sure that NUM_STATE_VARS are selected correctly //Actually we just need 3, but there is an excessive for first adjoint //const int state_num=NUM_STATE_VARS-2; double flux[4][NUM_STATE_VARS]; record_flux(El_Table, NodeTable, Curr_El->pass_key(), matprops_ptr, myid, flux); #ifdef DEBUG // if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1 // && effelement == EFFELL && iter == ITER && j == J) flux_debug(Curr_El, fluxold[0], fluxold[2], fluxold[1], fluxold[3], flux[0], flux[2], flux[1], flux[3], effelement, j, iter, dt); #endif double *d_state_vars = Curr_El->get_d_state_vars(); //here we compute the residuals residual(vec_res, state_vars, prev_state_vars, flux[0], //4 flux[1], flux[2], flux[3], dtdx, dtdy, dt, d_state_vars, //7 (d_state_vars + NUM_STATE_VARS), curvature, //2 matprops_ptr->intfrict, //1 bedfrict, gravity, d_gravity, *(Curr_El->get_kactxy()), //4 matprops_ptr->frict_tiny, orgSrcSgn, incr, //3 matprops_ptr->epsilon, check_stop, srcflag, 0); //2 #ifdef DEBUGFILE myfile << "Elem Key[0]= " << *(Curr_El->pass_key()) << " Key[1]= " << *(Curr_El->pass_key()) << " iter= " << iter << " eff_el= " << effelement << " j= " << j << " residual[0]= " << vec_res[0] << " residual[1]= " << vec_res[1] << " residual[2]= " << vec_res[2] << endl; #endif //we have to return everything back // restore(El_Table, NodeTable, Curr_El, effelement, j, incr, fluxold, // d_state_vars_old); restore(El_Table, NodeTable, Curr_El, matprops_ptr, effelement, j, myid, incr, d_state_vars_old); // if (check_restore(prev_state_vars, d_state_vars, prev_state_vars_old, // d_state_vars_old, flux, fluxold)) // cout << "this would cause incorrect result" << endl; for (int ind = 0; ind < NUM_STATE_VARS; ind++) total_res[ind] += signe * vec_res[ind]; // if (scheme == 0 && fabs(vec_res[0] / incr) < 5. // && fabs(vec_res[1] / incr) < 5. // && fabs(vec_res[2] / incr) < 5.) // //this means that forward difference is enough, and we do not need to compute central difference break; } double jacincr = INCREMENT; //= scheme == 0 ? increment : 2. * increment; Curr_El->set_jacobian(effelement, total_res, j, // following term is necessary to consider the scheme that whether it is forward difference or central difference jacincr); //sets the propper components of the Jacobian for this element } } } } } currentPtr = currentPtr->next; } } } #ifdef DEBUGFILE myfile.close(); #endif }