Example #1
0
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;
}
Example #2
0
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];
}
Example #3
0
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

}