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]); } }
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; }
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); }
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); }
// 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); } }
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; }
gen_op Spul_U_axis() { gen_op U1; U1 = Fe(); } // { dg-error "" } reaches end of non-void function
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); } } } } }
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])); } } } }
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"); }