예제 #1
0
파일: update.hpp 프로젝트: katherlee/CT-HYB
typename MAT::type
det_rat_row_column_up(int flavor_ins, int flavor_rem, double t_ins, double t_rem, int row, int column, const MAT & M,
  const operator_container_t& creation_operators, const operator_container_t& annihilation_operators, const HYB& F, MAT2& sign_Fs, MAT2& Fe_M, double BETA) {

  typedef typename MAT::type SCALAR;
  
  const double sign=((row+column)%2==0 ? 1 : -1);
  
  if (annihilation_operators.size()>0) {
    operator_container_t::iterator it_c=creation_operators.begin();
    operator_container_t::iterator it_a=annihilation_operators.begin();
    Eigen::Matrix<SCALAR,Eigen::Dynamic,Eigen::Dynamic> Fe(1,annihilation_operators.size());
    if (annihilation_operators.size()!=creation_operators.size()) {
      throw std::runtime_error("annihilation_operators.size()!=creation_operators.size() in det_rat_row_column_up");
    }

    for (int i=0; i<(int)creation_operators.size(); i++) {
      Fe(0,i) = interpolate_F(t_rem-it_c->time(), BETA, F[flavor_rem][it_c->flavor()]);
      sign_Fs(i,0) = sign*interpolate_F(it_a->time()-t_ins, BETA, F[(int)(it_a->flavor())][flavor_ins]);
      it_c++;
      it_a++;
    }
    
    Fe_M = Fe*M.block();
  
    return sign*interpolate_F(t_rem-t_ins, BETA, F[flavor_rem][flavor_ins])-(Fe_M*sign_Fs)(0,0);
  } else {
    return sign*interpolate_F(t_rem-t_ins, BETA, F[flavor_rem][flavor_ins]);
  }
}
예제 #2
0
Eigen::MatrixXd Reconstruction3D::computeP(const Eigen::MatrixXd& F, const Eigen::MatrixXd& eMat)
{
	Eigen::MatrixXd Fe(3, 4);
	Fe.block(0, 0, 3, 3) = F;
	Fe(0, 3) = -eMat(1, 2);
	Fe(1, 3) = eMat(0, 2);
	Fe(2, 3) = -eMat(0, 1);

	return eMat * Fe;
}
예제 #3
0
파일: update.hpp 프로젝트: katherlee/CT-HYB
int compute_M_shift_end(double new_t_end, int k, int new_position, int flavor_rem, MAT & M,
 const operator_container_t & creation_operators, const HYB & F,
 double BETA, SCALAR det_rat) {

  std::vector<SCALAR> R(M.size1(), 0), M_k(M.size1(), 0), Fe(M.size1(), 0);

  operator_container_t::const_iterator itc = creation_operators.begin();
  for (int i = 0; i < (int) M_k.size(); i++) {
    M_k[i] = M(i, k);
    Fe[i] = interpolate_F(new_t_end - itc->time(), BETA, F[flavor_rem][itc->flavor()]);
    itc++;
  }
  for (int i = 0; i < (int) R.size(); i++) {
    if (i != k) {
      for (int j = 0; j < (int) R.size(); j++)
        R[i] += Fe[j] * M(j, i);
    }
  }
  for (int m = 0; m < (int) M.size1(); m++) {
    if (m != k) {
      for (int n = 0; n < (int) M.size1(); n++) {
        M(n, m) -= M_k[n] * R[m] / det_rat;
      }
    } else {
      for (int n = 0; n < (int) M.size1(); n++) {
        M(n, m) = M_k[n] / det_rat;
      }
    }
  }

  //swap column
  move_column(M, k, new_position);

  return std::abs(k-new_position);
}  
예제 #4
0
파일: F.c 프로젝트: Og192/CPro
int main(void)
{
	//***************************************************
	struct timeval *_tv = malloc(sizeof(struct timeval));
	struct timeval *_tv1 = malloc(sizeof(struct timeval));
	gettimeofday(_tv, NULL);
	//***************************************************
	int array[54];
	FILE *fin = fopen("result", "r");
	int i;

	for(i = 1; i < 55; i++)
		fscanf(fin, "%d", &array[i]);
	Fe(array, 29, 9);

	//***************************************************
	gettimeofday(_tv1, NULL);
	long _end	= _tv1->tv_sec		* 1000000 + _tv1->tv_usec;
	long _start	= _tv->tv_sec		* 1000000 + _tv->tv_usec;
	long _s 	= (_end - _start)	/ 1000000;
	double _ms	= (_end - _start -   _s * 1000000) / 1000.0;
	printf("Total: %lu s %lf ms\n", _s, _ms);
	//***************************************************

	exit(EXIT_SUCCESS);
}
예제 #5
0
// buf = k = random number
int Fe(int r, int a, int b, int m, int blocks, int bit){
	
	int c = fe(r,a,b,m,bit);
	if(c < blocks) {
		return c;
	}
	else {
		//perform cycle walking
		return Fe(r, a, b,c, blocks, bit);
	}
}
예제 #6
0
Eigen::MatrixXd Reconstruction3D::computeP(const Eigen::MatrixXd& F)
{
	Eigen::JacobiSVD<Eigen::MatrixXd, Eigen::FullPivHouseholderQRPreconditioner> svd(F.transpose(), Eigen::ComputeFullU | Eigen::ComputeFullV);
	//Eigen::JacobiSVD<Eigen::MatrixXd> svd(F.transpose(), Eigen::ComputeFullV);
	Eigen::MatrixXd kernel = svd.matrixV().col(svd.matrixV().cols() - 1);

	Eigen::Matrix3d eMat(3, 3);
	eMat(0, 0) = kernel(0);
	eMat(0, 1) = kernel(1);
	eMat(0, 2) = kernel(2);
	eMat(1, 0) = kernel(3);
	eMat(1, 1) = kernel(4);
	eMat(1, 2) = kernel(5);
	eMat(2, 0) = kernel(6);
	eMat(2, 1) = kernel(7);
	eMat(2, 2) = kernel(8);

	

	Eigen::Vector3d e(-kernel(5), kernel(2), -kernel(1));

	Eigen::MatrixXd Fe(3, 4);
	Fe.block(0, 0, 3, 3) = F;
	Fe.col(3) = e;
	//Fe(0, 3) = -e(1, 2);
	//Fe(1, 3) =  e(0, 2);
	//Fe(2, 3) = -e(0, 1);

	Eigen::MatrixXd P = eMat * Fe;

	std::cout
		<< std::fixed << std::endl
		<< "[Info]  Epipole             : " << std::endl << e.transpose() << std::endl << std::endl
		<< "[Info]  Epipole Skew Matrix : " << std::endl << eMat << std::endl << std::endl
		<< "[Info]  F : " << std::endl << F << std::endl << std::endl
		<< "[Info]  Fe : " << std::endl << Fe << std::endl << std::endl
		<< "[Info]  P'                  : " << std::endl << P << std::endl << std::endl;
		

	return P;
}
예제 #7
0
gen_op Spul_U_axis()
{
  gen_op U1;
  U1 = Fe();
} // { dg-error "" } reaches end of non-void function
예제 #8
0
int main(int argc, char *argv[])
{

	//second argument is the file name to be permuted
	//atoi converted string to integer, we get the file size directly.
	if (argv[1])
    	blocks = atoi(argv[1]);
    else {
    	printf("passing block number as parameter\n");
    	exit(0);
    }
    	//printf("file size: %dG\n",filesize);
	
	//calculate blocklength 30 - 5 = 25 ( 2^30 stands for 1 gb, 2^5 for 32 bytes)
	//int temp = log2(GB) - log2(BLOCK_LENGTH);
	
    	//blocks = filesize * (1<<temp);
    	printf("block num: %d\n",blocks);
    	fflush(stdout);

	//find the bit length  of the each element of array to get number of blocks
	index_bit_length = log2(blocks);
	int bit = ceil(index_bit_length);
	    	printf("bit num: %d\n",bit);
	//declare for block indices table, and permuted indices table
	int * blockindices;
	int * prpblockindices;
	//allocate memory for input and output table
    	blockindices = (int *)malloc(blocks*sizeof(int));
    	prpblockindices = (int *)malloc(blocks*sizeof(int));

	//initialize block array to the block indices
    	int j=0;
	int i;
    	for (i=0;i<blocks;i++) {
		blockindices[i] = i;
    	}
	
	//hardcoding 6 seeds
	unsigned char * seed1 = "jiedai";
	unsigned char * seed2 = "ruchashintre";
	unsigned char * seed3 = "poojadesai";
	unsigned char * seed4 = "CMUMSE";
	unsigned char * seed5 = "BOSCH";
	unsigned char * seed6 = "jorge";
    double startTime, endTime;
    startTime = getCPUTime();
	//Generate 6 functions
	round1table = malloc(blocks*sizeof(unsigned int));
	generateRoundFunctions(seed1,round1table,blocks);
	round2table = malloc(blocks*sizeof(unsigned int));
	generateRoundFunctions(seed2,round2table,blocks);
	round3table = malloc(blocks*sizeof(unsigned int));
	generateRoundFunctions(seed3,round3table,blocks);
	round4table = malloc(blocks*sizeof(unsigned int));	
	generateRoundFunctions(seed4,round4table,blocks);
	round5table = malloc(blocks*sizeof(unsigned int));
	generateRoundFunctions(seed5,round5table,blocks);
	round6table = malloc(blocks*sizeof(unsigned int));
	generateRoundFunctions(seed6,round6table,blocks);
	printf("6 tables generated");
    endTime = getCPUTime();
    fprintf( stderr, "CPU time used for PRNG = %lf\n", (endTime - startTime) );
    
    startTime = getCPUTime();
	//using setting in the paper: change it later, to calculate a and b
	int a = ceil(sqrt(blocks));
	int b = ceil(sqrt(blocks))+1;
	printf("a=%d,b=%d\n",a,b);
	//get the keys for permutation
	
	//unsigned char * keyseed = "anappleadaykeepsadoctoraway";
	//int key = genkey(keyseed);
	
	//do this for six rounds
	for(i=0;i<blocks;i++){
		prpblockindices[i]=Fe(NOOFROUNDS, a, b,i, blocks, bit);
	}
	
	//for(i=0;i<blocks;i++){
		//printf("%d -> %d\n", blockindices[i], prpblockindices[i]);		
	//}
		printf("a=%d,b=%d\n",a,b);
		    endTime = getCPUTime();
    fprintf( stderr, "CPU time used for PRP = %lf\n", (endTime - startTime) );
}
void
AnisotropicViscoplasticModel<EvalT, Traits>::computeState(
    typename Traits::EvalData workset,
    DepFieldMap               dep_fields,
    FieldMap                  eval_fields)
{
  std::string cauchy_string = (*field_name_map_)["Cauchy_Stress"];
  std::string Fp_string     = (*field_name_map_)["Fp"];
  std::string eqps_string   = (*field_name_map_)["eqps"];
  std::string ess_string    = (*field_name_map_)["ess"];
  std::string kappa_string  = (*field_name_map_)["iso_Hardening"];
  std::string source_string = (*field_name_map_)["Mechanical_Source"];
  std::string F_string      = (*field_name_map_)["F"];
  std::string J_string      = (*field_name_map_)["J"];

  // extract dependent MDFields
  auto def_grad          = *dep_fields[F_string];
  auto J                 = *dep_fields[J_string];
  auto poissons_ratio    = *dep_fields["Poissons Ratio"];
  auto elastic_modulus   = *dep_fields["Elastic Modulus"];
  auto yield_strength    = *dep_fields["Yield Strength"];
  auto hardening_modulus = *dep_fields["Hardening Modulus"];
  auto recovery_modulus  = *dep_fields["Recovery Modulus"];
  auto flow_exp          = *dep_fields["Flow Rule Exponent"];
  auto flow_coeff        = *dep_fields["Flow Rule Coefficient"];
  auto delta_time        = *dep_fields["Delta Time"];

  // extract evaluated MDFields
  auto                  stress = *eval_fields[cauchy_string];
  auto                  Fp     = *eval_fields[Fp_string];
  auto                  eqps   = *eval_fields[eqps_string];
  auto                  ess    = *eval_fields[ess_string];
  auto                  kappa  = *eval_fields[kappa_string];
  PHX::MDField<ScalarT> source;
  if (have_temperature_) { source = *eval_fields[source_string]; }

  // get State Variables
  Albany::MDArray Fpold   = (*workset.stateArrayPtr)[Fp_string + "_old"];
  Albany::MDArray eqpsold = (*workset.stateArrayPtr)[eqps_string + "_old"];

  ScalarT bulk, mu, mubar, K, Y;
  ScalarT Jm23, trace, smag2, smag, f, p, dgam;
  ScalarT sq23(std::sqrt(2. / 3.));

  minitensor::Tensor<ScalarT> F(num_dims_), be(num_dims_), s(num_dims_),
      sigma(num_dims_);
  minitensor::Tensor<ScalarT> N(num_dims_), A(num_dims_), expA(num_dims_),
      Fpnew(num_dims_);
  minitensor::Tensor<ScalarT> I(minitensor::eye<ScalarT>(num_dims_));
  minitensor::Tensor<ScalarT> Fpn(num_dims_), Cpinv(num_dims_), Fe(num_dims_);
  minitensor::Tensor<ScalarT> tau(num_dims_), M(num_dims_);

  for (int cell(0); cell < workset.numCells; ++cell) {
    for (int pt(0); pt < num_pts_; ++pt) {
      bulk = elastic_modulus(cell, pt) /
             (3. * (1. - 2. * poissons_ratio(cell, pt)));
      mu   = elastic_modulus(cell, pt) / (2. * (1. + poissons_ratio(cell, pt)));
      K    = hardening_modulus(cell, pt);
      Y    = yield_strength(cell, pt);
      Jm23 = std::pow(J(cell, pt), -2. / 3.);

      // fill local tensors
      F.fill(def_grad, cell, pt, 0, 0);

      // Mechanical deformation gradient
      auto Fm = minitensor::Tensor<ScalarT>(F);
      if (have_temperature_) {
        // Compute the mechanical deformation gradient Fm based on the
        // multiplicative decomposition of the deformation gradient
        //
        //            F = Fm.Ft => Fm = F.inv(Ft)
        //
        // where Ft is the thermal part of F, given as
        //
        //     Ft = Le * I = exp(alpha * dtemp) * I
        //
        // Le is the thermal stretch and alpha the coefficient of thermal
        // expansion.
        ScalarT dtemp           = temperature_(cell, pt) - ref_temperature_;
        ScalarT thermal_stretch = std::exp(expansion_coeff_ * dtemp);
        Fm /= thermal_stretch;
      }

      // Fpn.fill( &Fpold(cell,pt,int(0),int(0)) );
      for (int i(0); i < num_dims_; ++i) {
        for (int j(0); j < num_dims_; ++j) {
          Fpn(i, j) = ScalarT(Fpold(cell, pt, i, j));
        }
      }

      // compute trial state
      // compute the Kirchhoff stress in the current configuration
      //
      Fe    = Fm * minitensor::inverse(Fpn);
      Cpinv = minitensor::inverse(Fpn) *
              minitensor::transpose(minitensor::inverse(Fpn));
      be         = Fm * Cpinv * minitensor::transpose(Fm);
      ScalarT Je = std::sqrt(minitensor::det(be));
      s          = mu * minitensor::dev(be);
      p          = 0.5 * bulk * (Je * Je - 1.);
      tau        = p * I + s;

      // pull back the Kirchhoff stress to the intermediate configuration
      // this is the Mandel stress
      //
      M = minitensor::transpose(Fe) * tau *
          minitensor::inverse(minitensor::transpose(Fe));

      // check yield condition
      smag = minitensor::norm(s);
      f    = smag - sq23 * (Y + K * eqpsold(cell, pt));

      if (f > 1E-12) {
        // return mapping algorithm
        bool    converged = false;
        ScalarT g         = f;
        ScalarT H         = 0.0;
        ScalarT dH        = 0.0;
        ScalarT alpha     = 0.0;
        ScalarT res       = 0.0;
        int     count     = 0;
        dgam              = 0.0;

        LocalNonlinearSolver<EvalT, Traits> solver;

        std::vector<ScalarT> F(1);
        std::vector<ScalarT> dFdX(1);
        std::vector<ScalarT> X(1);

        F[0]    = f;
        X[0]    = 0.0;
        dFdX[0] = (-2. * mubar) * (1. + H / (3. * mubar));
        while (!converged && count <= 30) {
          count++;
          solver.solve(dFdX, X, F);
          alpha   = eqpsold(cell, pt) + sq23 * X[0];
          H       = K * alpha;
          dH      = K;
          F[0]    = smag - (2. * mubar * X[0] + sq23 * (Y + H));
          dFdX[0] = -2. * mubar * (1. + dH / (3. * mubar));

          res = std::abs(F[0]);
          if (res < 1.e-11 || res / f < 1.E-11) converged = true;

          TEUCHOS_TEST_FOR_EXCEPTION(
              count == 30,
              std::runtime_error,
              std::endl
                  << "Error in return mapping, count = " << count
                  << "\nres = " << res << "\nrelres = " << res / f
                  << "\ng = " << F[0] << "\ndg = " << dFdX[0]
                  << "\nalpha = " << alpha << std::endl);
        }
        solver.computeFadInfo(dFdX, X, F);
        dgam = X[0];

        // plastic direction
        N = (1 / smag) * s;

        // update s
        s -= 2 * mubar * dgam * N;

        // update eqps
        eqps(cell, pt) = alpha;

        // mechanical source
        if (have_temperature_ && delta_time(0) > 0) {
          source(cell, pt) =
              (sq23 * dgam / delta_time(0) * (Y + H + temperature_(cell, pt))) /
              (density_ * heat_capacity_);
        }

        // exponential map to get Fpnew
        A     = dgam * N;
        expA  = minitensor::exp(A);
        Fpnew = expA * Fpn;
        for (int i(0); i < num_dims_; ++i) {
          for (int j(0); j < num_dims_; ++j) {
            Fp(cell, pt, i, j) = Fpnew(i, j);
          }
        }
      } else {
        eqps(cell, pt) = eqpsold(cell, pt);
        if (have_temperature_) source(cell, pt) = 0.0;
        for (int i(0); i < num_dims_; ++i) {
          for (int j(0); j < num_dims_; ++j) { Fp(cell, pt, i, j) = Fpn(i, j); }
        }
      }

      // compute pressure
      p = 0.5 * bulk * (J(cell, pt) - 1. / (J(cell, pt)));

      // compute stress
      sigma = p * I + s / J(cell, pt);
      for (int i(0); i < num_dims_; ++i) {
        for (int j(0); j < num_dims_; ++j) {
          stress(cell, pt, i, j) = sigma(i, j);
        }
      }
    }
  }
}
예제 #10
0
void HPCoarsenTest::add_projection(const System & system,
                                   const Elem * elem,
                                   unsigned int var)
{
  // If we have children, we need to add their projections instead
  if (!elem->active())
    {
      libmesh_assert(!elem->subactive());
      for (unsigned int c = 0; c != elem->n_children(); ++c)
        this->add_projection(system, elem->child(c), var);
      return;
    }

  // The DofMap for this system
  const DofMap & dof_map = system.get_dof_map();

  // The type of finite element to use for this variable
  const FEType & fe_type = dof_map.variable_type (var);

  const FEContinuity cont = fe->get_continuity();

  fe->reinit(elem);

  dof_map.dof_indices(elem, dof_indices, var);

  const unsigned int n_dofs =
    cast_int<unsigned int>(dof_indices.size());

  FEInterface::inverse_map (system.get_mesh().mesh_dimension(),
                            fe_type, coarse, *xyz_values, coarse_qpoints);

  fe_coarse->reinit(coarse, &coarse_qpoints);

  const unsigned int n_coarse_dofs =
    cast_int<unsigned int>(phi_coarse->size());

  if (Uc.size() == 0)
    {
      Ke.resize(n_coarse_dofs, n_coarse_dofs);
      Ke.zero();
      Fe.resize(n_coarse_dofs);
      Fe.zero();
      Uc.resize(n_coarse_dofs);
      Uc.zero();
    }
  libmesh_assert_equal_to (Uc.size(), phi_coarse->size());

  // Loop over the quadrature points
  for (unsigned int qp=0; qp<qrule->n_points(); qp++)
    {
      // The solution value at the quadrature point
      Number val = libMesh::zero;
      Gradient grad;
      Tensor hess;

      for (unsigned int i=0; i != n_dofs; i++)
        {
          dof_id_type dof_num = dof_indices[i];
          val += (*phi)[i][qp] *
            system.current_solution(dof_num);
          if (cont == C_ZERO || cont == C_ONE)
            grad.add_scaled((*dphi)[i][qp],system.current_solution(dof_num));
          // grad += (*dphi)[i][qp] *
          //  system.current_solution(dof_num);
          if (cont == C_ONE)
            hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
          // hess += (*d2phi)[i][qp] *
          //  system.current_solution(dof_num);
        }

      // The projection matrix and vector
      for (unsigned int i=0; i != Fe.size(); ++i)
        {
          Fe(i) += (*JxW)[qp] *
            (*phi_coarse)[i][qp]*val;
          if (cont == C_ZERO || cont == C_ONE)
            Fe(i) += (*JxW)[qp] *
              (grad*(*dphi_coarse)[i][qp]);
          if (cont == C_ONE)
            Fe(i) += (*JxW)[qp] *
              hess.contract((*d2phi_coarse)[i][qp]);
          // Fe(i) += (*JxW)[qp] *
          //  (*d2phi_coarse)[i][qp].contract(hess);

          for (unsigned int j=0; j != Fe.size(); ++j)
            {
              Ke(i,j) += (*JxW)[qp] *
                (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
              if (cont == C_ZERO || cont == C_ONE)
                Ke(i,j) += (*JxW)[qp] *
                  (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
              if (cont == C_ONE)
                Ke(i,j) += (*JxW)[qp] *
                  ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
            }
        }
    }
}
예제 #11
0
void HPCoarsenTest::select_refinement (System & system)
{
  START_LOG("select_refinement()", "HPCoarsenTest");

  // The current mesh
  MeshBase & mesh = system.get_mesh();

  // The dimensionality of the mesh
  const unsigned int dim = mesh.mesh_dimension();

  // The number of variables in the system
  const unsigned int n_vars = system.n_vars();

  // The DofMap for this system
  const DofMap & dof_map = system.get_dof_map();

  // The system number (for doing bad hackery)
  const unsigned int sys_num = system.number();

  // Check for a valid component_scale
  if (!component_scale.empty())
    {
      if (component_scale.size() != n_vars)
        libmesh_error_msg("ERROR: component_scale is the wrong size:\n" \
                          << " component_scale.size()=" \
                          << component_scale.size()     \
                          << "\n n_vars=" \
                          << n_vars);
    }
  else
    {
      // No specified scaling.  Scale all variables by one.
      component_scale.resize (n_vars, 1.0);
    }

  // Resize the error_per_cell vectors to handle
  // the number of elements, initialize them to 0.
  std::vector<ErrorVectorReal> h_error_per_cell(mesh.max_elem_id(), 0.);
  std::vector<ErrorVectorReal> p_error_per_cell(mesh.max_elem_id(), 0.);

  // Loop over all the variables in the system
  for (unsigned int var=0; var<n_vars; var++)
    {
      // Possibly skip this variable
      if (!component_scale.empty())
        if (component_scale[var] == 0.0) continue;

      // The type of finite element to use for this variable
      const FEType & fe_type = dof_map.variable_type (var);

      // Finite element objects for a fine (and probably a coarse)
      // element will be needed
      fe = FEBase::build (dim, fe_type);
      fe_coarse = FEBase::build (dim, fe_type);

      // Any cached coarse element results have expired
      coarse = libmesh_nullptr;
      unsigned int cached_coarse_p_level = 0;

      const FEContinuity cont = fe->get_continuity();
      libmesh_assert (cont == DISCONTINUOUS || cont == C_ZERO ||
                      cont == C_ONE);

      // Build an appropriate quadrature rule
      qrule = fe_type.default_quadrature_rule(dim);

      // Tell the refined finite element about the quadrature
      // rule.  The coarse finite element need not know about it
      fe->attach_quadrature_rule (qrule.get());

      // We will always do the integration
      // on the fine elements.  Get their Jacobian values, etc..
      JxW = &(fe->get_JxW());
      xyz_values = &(fe->get_xyz());

      // The shape functions
      phi = &(fe->get_phi());
      phi_coarse = &(fe_coarse->get_phi());

      // The shape function derivatives
      if (cont == C_ZERO || cont == C_ONE)
        {
          dphi = &(fe->get_dphi());
          dphi_coarse = &(fe_coarse->get_dphi());
        }

#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
      // The shape function second derivatives
      if (cont == C_ONE)
        {
          d2phi = &(fe->get_d2phi());
          d2phi_coarse = &(fe_coarse->get_d2phi());
        }
#endif // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)

      // Iterate over all the active elements in the mesh
      // that live on this processor.

      MeshBase::const_element_iterator       elem_it  =
        mesh.active_local_elements_begin();
      const MeshBase::const_element_iterator elem_end =
        mesh.active_local_elements_end();

      for (; elem_it != elem_end; ++elem_it)
        {
          const Elem * elem = *elem_it;

          // We're only checking elements that are already flagged for h
          // refinement
          if (elem->refinement_flag() != Elem::REFINE)
            continue;

          const dof_id_type e_id = elem->id();

          // Find the projection onto the parent element,
          // if necessary
          if (elem->parent() &&
              (coarse != elem->parent() ||
               cached_coarse_p_level != elem->p_level()))
            {
              Uc.resize(0);

              coarse = elem->parent();
              cached_coarse_p_level = elem->p_level();

              unsigned int old_parent_level = coarse->p_level();
              (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());

              this->add_projection(system, coarse, var);

              (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);

              // Solve the h-coarsening projection problem
              Ke.cholesky_solve(Fe, Uc);
            }

          fe->reinit(elem);

          // Get the DOF indices for the fine element
          dof_map.dof_indices (elem, dof_indices, var);

          // The number of quadrature points
          const unsigned int n_qp = qrule->n_points();

          // The number of DOFS on the fine element
          const unsigned int n_dofs =
            cast_int<unsigned int>(dof_indices.size());

          // The number of nodes on the fine element
          const unsigned int n_nodes = elem->n_nodes();

          // The average element value (used as an ugly hack
          // when we have nothing p-coarsened to compare to)
          // Real average_val = 0.;
          Number average_val = 0.;

          // Calculate this variable's contribution to the p
          // refinement error

          if (elem->p_level() == 0)
            {
              unsigned int n_vertices = 0;
              for (unsigned int n = 0; n != n_nodes; ++n)
                if (elem->is_vertex(n))
                  {
                    n_vertices++;
                    const Node * const node = elem->get_node(n);
                    average_val += system.current_solution
                      (node->dof_number(sys_num,var,0));
                  }
              average_val /= n_vertices;
            }
          else
            {
              unsigned int old_elem_level = elem->p_level();
              (const_cast<Elem *>(elem))->hack_p_level(old_elem_level - 1);

              fe_coarse->reinit(elem, &(qrule->get_points()));

              const unsigned int n_coarse_dofs =
                cast_int<unsigned int>(phi_coarse->size());

              (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);

              Ke.resize(n_coarse_dofs, n_coarse_dofs);
              Ke.zero();
              Fe.resize(n_coarse_dofs);
              Fe.zero();

              // Loop over the quadrature points
              for (unsigned int qp=0; qp<qrule->n_points(); qp++)
                {
                  // The solution value at the quadrature point
                  Number val = libMesh::zero;
                  Gradient grad;
                  Tensor hess;

                  for (unsigned int i=0; i != n_dofs; i++)
                    {
                      dof_id_type dof_num = dof_indices[i];
                      val += (*phi)[i][qp] *
                        system.current_solution(dof_num);
                      if (cont == C_ZERO || cont == C_ONE)
                        grad.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
                      // grad += (*dphi)[i][qp] *
                      //  system.current_solution(dof_num);
                      if (cont == C_ONE)
                        hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
                      // hess += (*d2phi)[i][qp] *
                      //  system.current_solution(dof_num);
                    }

                  // The projection matrix and vector
                  for (unsigned int i=0; i != Fe.size(); ++i)
                    {
                      Fe(i) += (*JxW)[qp] *
                        (*phi_coarse)[i][qp]*val;
                      if (cont == C_ZERO || cont == C_ONE)
                        Fe(i) += (*JxW)[qp] *
                          grad * (*dphi_coarse)[i][qp];
                      if (cont == C_ONE)
                        Fe(i) += (*JxW)[qp] *
                          hess.contract((*d2phi_coarse)[i][qp]);

                      for (unsigned int j=0; j != Fe.size(); ++j)
                        {
                          Ke(i,j) += (*JxW)[qp] *
                            (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
                          if (cont == C_ZERO || cont == C_ONE)
                            Ke(i,j) += (*JxW)[qp] *
                              (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
                          if (cont == C_ONE)
                            Ke(i,j) += (*JxW)[qp] *
                              ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
                        }
                    }
                }

              // Solve the p-coarsening projection problem
              Ke.cholesky_solve(Fe, Up);
            }

          // loop over the integration points on the fine element
          for (unsigned int qp=0; qp<n_qp; qp++)
            {
              Number value_error = 0.;
              Gradient grad_error;
              Tensor hessian_error;
              for (unsigned int i=0; i<n_dofs; i++)
                {
                  const dof_id_type dof_num = dof_indices[i];
                  value_error += (*phi)[i][qp] *
                    system.current_solution(dof_num);
                  if (cont == C_ZERO || cont == C_ONE)
                    grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
                  // grad_error += (*dphi)[i][qp] *
                  //  system.current_solution(dof_num);
                  if (cont == C_ONE)
                    hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
                  // hessian_error += (*d2phi)[i][qp] *
                  //    system.current_solution(dof_num);
                }
              if (elem->p_level() == 0)
                {
                  value_error -= average_val;
                }
              else
                {
                  for (unsigned int i=0; i<Up.size(); i++)
                    {
                      value_error -= (*phi_coarse)[i][qp] * Up(i);
                      if (cont == C_ZERO || cont == C_ONE)
                        grad_error.subtract_scaled((*dphi_coarse)[i][qp], Up(i));
                      // grad_error -= (*dphi_coarse)[i][qp] * Up(i);
                      if (cont == C_ONE)
                        hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Up(i));
                      // hessian_error -= (*d2phi_coarse)[i][qp] * Up(i);
                    }
                }

              p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                (component_scale[var] *
                 (*JxW)[qp] * TensorTools::norm_sq(value_error));
              if (cont == C_ZERO || cont == C_ONE)
                p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                  (component_scale[var] *
                   (*JxW)[qp] * grad_error.norm_sq());
              if (cont == C_ONE)
                p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                  (component_scale[var] *
                   (*JxW)[qp] * hessian_error.norm_sq());
            }

          // Calculate this variable's contribution to the h
          // refinement error

          if (!elem->parent())
            {
              // For now, we'll always start with an h refinement
              h_error_per_cell[e_id] =
                std::numeric_limits<ErrorVectorReal>::max() / 2;
            }
          else
            {
              FEInterface::inverse_map (dim, fe_type, coarse,
                                        *xyz_values, coarse_qpoints);

              unsigned int old_parent_level = coarse->p_level();
              (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());

              fe_coarse->reinit(coarse, &coarse_qpoints);

              (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);

              // The number of DOFS on the coarse element
              unsigned int n_coarse_dofs =
                cast_int<unsigned int>(phi_coarse->size());

              // Loop over the quadrature points
              for (unsigned int qp=0; qp<n_qp; qp++)
                {
                  // The solution difference at the quadrature point
                  Number value_error = libMesh::zero;
                  Gradient grad_error;
                  Tensor hessian_error;

                  for (unsigned int i=0; i != n_dofs; ++i)
                    {
                      const dof_id_type dof_num = dof_indices[i];
                      value_error += (*phi)[i][qp] *
                        system.current_solution(dof_num);
                      if (cont == C_ZERO || cont == C_ONE)
                        grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
                      // grad_error += (*dphi)[i][qp] *
                      //  system.current_solution(dof_num);
                      if (cont == C_ONE)
                        hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
                      // hessian_error += (*d2phi)[i][qp] *
                      //  system.current_solution(dof_num);
                    }

                  for (unsigned int i=0; i != n_coarse_dofs; ++i)
                    {
                      value_error -= (*phi_coarse)[i][qp] * Uc(i);
                      if (cont == C_ZERO || cont == C_ONE)
                        // grad_error -= (*dphi_coarse)[i][qp] * Uc(i);
                        grad_error.subtract_scaled((*dphi_coarse)[i][qp], Uc(i));
                      if (cont == C_ONE)
                        hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Uc(i));
                      // hessian_error -= (*d2phi_coarse)[i][qp] * Uc(i);
                    }

                  h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                    (component_scale[var] *
                     (*JxW)[qp] * TensorTools::norm_sq(value_error));
                  if (cont == C_ZERO || cont == C_ONE)
                    h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                      (component_scale[var] *
                       (*JxW)[qp] * grad_error.norm_sq());
                  if (cont == C_ONE)
                    h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
                      (component_scale[var] *
                       (*JxW)[qp] * hessian_error.norm_sq());
                }

            }
        }
    }

  // Now that we've got our approximations for p_error and h_error, let's see
  // if we want to switch any h refinement flags to p refinement

  // Iterate over all the active elements in the mesh
  // that live on this processor.

  MeshBase::element_iterator       elem_it  =
    mesh.active_local_elements_begin();
  const MeshBase::element_iterator elem_end =
    mesh.active_local_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    {
      Elem * elem = *elem_it;

      // We're only checking elements that are already flagged for h
      // refinement
      if (elem->refinement_flag() != Elem::REFINE)
        continue;

      const dof_id_type e_id = elem->id();

      unsigned int dofs_per_elem = 0, dofs_per_p_elem = 0;

      // Loop over all the variables in the system
      for (unsigned int var=0; var<n_vars; var++)
        {
          // The type of finite element to use for this variable
          const FEType & fe_type = dof_map.variable_type (var);

          // FIXME: we're overestimating the number of DOFs added by h
          // refinement
          FEType elem_fe_type = fe_type;
          elem_fe_type.order =
            static_cast<Order>(fe_type.order + elem->p_level());
          dofs_per_elem +=
            FEInterface::n_dofs(dim, elem_fe_type, elem->type());

          elem_fe_type.order =
            static_cast<Order>(fe_type.order + elem->p_level() + 1);
          dofs_per_p_elem +=
            FEInterface::n_dofs(dim, elem_fe_type, elem->type());
        }

      const unsigned int new_h_dofs = dofs_per_elem *
        (elem->n_children() - 1);

      const unsigned int new_p_dofs = dofs_per_p_elem -
        dofs_per_elem;

      /*
        libMesh::err << "Cell " << e_id << ": h = " << elem->hmax()
        << ", p = " << elem->p_level() + 1 << "," << std::endl
        << "     h_error = " << h_error_per_cell[e_id]
        << ", p_error = " << p_error_per_cell[e_id] << std::endl
        << "     new_h_dofs = " << new_h_dofs
        << ", new_p_dofs = " << new_p_dofs << std::endl;
      */
      const Real p_value =
        std::sqrt(p_error_per_cell[e_id]) * p_weight / new_p_dofs;
      const Real h_value =
        std::sqrt(h_error_per_cell[e_id]) /
        static_cast<Real>(new_h_dofs);
      if (p_value > h_value)
        {
          elem->set_p_refinement_flag(Elem::REFINE);
          elem->set_refinement_flag(Elem::DO_NOTHING);
        }
    }

  STOP_LOG("select_refinement()", "HPCoarsenTest");
}