void FEXYZ<Dim>::reinit(const Elem * elem, const unsigned int s, const Real, const std::vector<Point> * const pts, const std::vector<Real> * const weights) { libmesh_assert(elem); libmesh_assert (this->qrule != libmesh_nullptr || pts != libmesh_nullptr); // We don't do this for 1D elements! libmesh_assert_not_equal_to (Dim, 1); // Build the side of interest const UniquePtr<const Elem> side(elem->build_side_ptr(s)); // Initialize the shape functions at the user-specified // points if (pts != libmesh_nullptr) { // We can't get away without recomputing shape functions next // time this->shapes_on_quadrature = false; // Set the element type this->elem_type = elem->type(); // Initialize the face shape functions this->_fe_map->template init_face_shape_functions<Dim>(*pts, side.get()); if (weights != libmesh_nullptr) { this->compute_face_values (elem, side.get(), *weights); } else { std::vector<Real> dummy_weights (pts->size(), 1.); // Compute data on the face for integration this->compute_face_values (elem, side.get(), dummy_weights); } } else { // initialize quadrature rule this->qrule->init(side->type(), elem->p_level()); { // Set the element type this->elem_type = elem->type(); // Initialize the face shape functions this->_fe_map->template init_face_shape_functions<Dim>(this->qrule->get_points(), side.get()); } // We can't get away without recomputing shape functions next // time this->shapes_on_quadrature = false; // Compute data on the face for integration this->compute_face_values (elem, side.get(), this->qrule->get_weights()); } }
void FE<Dim,T>::reinit(const Elem* elem, const std::vector<Point>* const pts, const std::vector<Real>* const weights) { libmesh_assert(elem); // Try to avoid calling init_shape_functions // even when shapes_need_reinit bool cached_nodes_still_fit = false; // Initialize the shape functions at the user-specified // points if (pts != NULL) { // Set the type and p level for this element this->elem_type = elem->type(); this->_p_level = elem->p_level(); // Initialize the shape functions this->_fe_map->template init_reference_to_physical_map<Dim>(*pts, elem); this->init_shape_functions (*pts, elem); // The shape functions do not correspond to the qrule this->shapes_on_quadrature = false; } // If there are no user specified points, we use the // quadrature rule // update the type in accordance to the current cell // and reinit if the cell type has changed or (as in // the case of the hierarchics) the shape functions need // reinit, since they depend on the particular element shape else { libmesh_assert(this->qrule); this->qrule->init(elem->type(), elem->p_level()); if(this->qrule->shapes_need_reinit()) this->shapes_on_quadrature = false; if (this->elem_type != elem->type() || this->_p_level != elem->p_level() || !this->shapes_on_quadrature) { // Set the type and p level for this element this->elem_type = elem->type(); this->_p_level = elem->p_level(); // Initialize the shape functions this->_fe_map->template init_reference_to_physical_map<Dim>(this->qrule->get_points(), elem); this->init_shape_functions (this->qrule->get_points(), elem); if (this->shapes_need_reinit()) { cached_nodes.resize(elem->n_nodes()); for (unsigned int n = 0; n != elem->n_nodes(); ++n) { cached_nodes[n] = elem->point(n); } } } else { // libmesh_assert_greater (elem->n_nodes(), 1); cached_nodes_still_fit = true; if (cached_nodes.size() != elem->n_nodes()) cached_nodes_still_fit = false; else for (unsigned int n = 1; n < elem->n_nodes(); ++n) { if (!(elem->point(n) - elem->point(0)).relative_fuzzy_equals( (cached_nodes[n] - cached_nodes[0]), 1e-13)) { cached_nodes_still_fit = false; break; } } if (this->shapes_need_reinit() && !cached_nodes_still_fit) { this->_fe_map->template init_reference_to_physical_map<Dim>(this->qrule->get_points(), elem); this->init_shape_functions (this->qrule->get_points(), elem); cached_nodes.resize(elem->n_nodes()); for (unsigned int n = 0; n != elem->n_nodes(); ++n) cached_nodes[n] = elem->point(n); } } // The shape functions correspond to the qrule this->shapes_on_quadrature = true; } // Compute the map for this element. In the future we can specify // different types of maps if (pts != NULL) { if (weights != NULL) { this->_fe_map->compute_map (this->dim,*weights, elem); } else { std::vector<Real> dummy_weights (pts->size(), 1.); this->_fe_map->compute_map (this->dim,dummy_weights, elem); } } else { this->_fe_map->compute_map (this->dim,this->qrule->get_weights(), elem); } // Compute the shape functions and the derivatives at all of the // quadrature points. if (!cached_nodes_still_fit) { if (pts != NULL) this->compute_shape_functions (elem,*pts); else this->compute_shape_functions(elem,this->qrule->get_points()); } }
void FE<Dim,T>::edge_reinit(const Elem* elem, const unsigned int e, const Real tolerance, const std::vector<Point>* const pts, const std::vector<Real>* const weights) { libmesh_assert(elem); libmesh_assert (this->qrule != NULL || pts != NULL); // We don't do this for 1D elements! libmesh_assert_not_equal_to (Dim, 1); // Build the side of interest const UniquePtr<Elem> edge(elem->build_edge(e)); // Initialize the shape functions at the user-specified // points if (pts != NULL) { // The shape functions do not correspond to the qrule this->shapes_on_quadrature = false; // Initialize the edge shape functions this->_fe_map->template init_edge_shape_functions<Dim> (*pts, edge.get()); // Compute the Jacobian*Weight on the face for integration if (weights != NULL) { this->_fe_map->compute_edge_map (Dim, *weights, edge.get()); } else { std::vector<Real> dummy_weights (pts->size(), 1.); this->_fe_map->compute_edge_map (Dim, dummy_weights, edge.get()); } } // If there are no user specified points, we use the // quadrature rule else { // initialize quadrature rule this->qrule->init(edge->type(), elem->p_level()); if(this->qrule->shapes_need_reinit()) this->shapes_on_quadrature = false; // We might not need to reinitialize the shape functions if ((this->get_type() != elem->type()) || (edge->type() != static_cast<int>(last_edge)) || // Comparison between enum and unsigned, cast the unsigned to int this->shapes_need_reinit() || !this->shapes_on_quadrature) { // Set the element type this->elem_type = elem->type(); // Set the last_edge last_edge = edge->type(); // Initialize the edge shape functions this->_fe_map->template init_edge_shape_functions<Dim> (this->qrule->get_points(), edge.get()); } // Compute the Jacobian*Weight on the face for integration this->_fe_map->compute_edge_map (Dim, this->qrule->get_weights(), edge.get()); // The shape functions correspond to the qrule this->shapes_on_quadrature = true; } // make a copy of the Jacobian for integration const std::vector<Real> JxW_int(this->_fe_map->get_JxW()); // Find where the integration points are located on the // full element. std::vector<Point> qp; this->inverse_map (elem, this->_fe_map->get_xyz(), qp, tolerance); // compute the shape function and derivative values // at the points qp this->reinit (elem, &qp); // copy back old data this->_fe_map->get_JxW() = JxW_int; }
void FE<Dim,T>::reinit(const Elem* elem, const unsigned int s, const Real /* tolerance */, const std::vector<Point>* const pts, const std::vector<Real>* const weights) { libmesh_assert(elem); libmesh_assert (this->qrule != NULL || pts != NULL); // We now do this for 1D elements! // libmesh_assert_not_equal_to (Dim, 1); // Build the side of interest const UniquePtr<Elem> side(elem->build_side(s)); // Find the max p_level to select // the right quadrature rule for side integration unsigned int side_p_level = elem->p_level(); if (elem->neighbor(s) != NULL) side_p_level = std::max(side_p_level, elem->neighbor(s)->p_level()); // Initialize the shape functions at the user-specified // points if (pts != NULL) { // The shape functions do not correspond to the qrule this->shapes_on_quadrature = false; // Initialize the face shape functions this->_fe_map->template init_face_shape_functions<Dim>(*pts, side.get()); // Compute the Jacobian*Weight on the face for integration if (weights != NULL) { this->_fe_map->compute_face_map (Dim, *weights, side.get()); } else { std::vector<Real> dummy_weights (pts->size(), 1.); this->_fe_map->compute_face_map (Dim, dummy_weights, side.get()); } } // If there are no user specified points, we use the // quadrature rule else { // initialize quadrature rule this->qrule->init(side->type(), side_p_level); if(this->qrule->shapes_need_reinit()) this->shapes_on_quadrature = false; // FIXME - could this break if the same FE object was used // for both volume and face integrals? - RHS // We might not need to reinitialize the shape functions if ((this->get_type() != elem->type()) || (side->type() != last_side) || (this->get_p_level() != side_p_level) || this->shapes_need_reinit() || !this->shapes_on_quadrature) { // Set the element type and p_level this->elem_type = elem->type(); // Set the last_side last_side = side->type(); // Set the last p level this->_p_level = side_p_level; // Initialize the face shape functions this->_fe_map->template init_face_shape_functions<Dim>(this->qrule->get_points(), side.get()); } // Compute the Jacobian*Weight on the face for integration this->_fe_map->compute_face_map (Dim, this->qrule->get_weights(), side.get()); // The shape functions correspond to the qrule this->shapes_on_quadrature = true; } // make a copy of the Jacobian for integration const std::vector<Real> JxW_int(this->_fe_map->get_JxW()); // make a copy of shape on quadrature info bool shapes_on_quadrature_side = this->shapes_on_quadrature; // Find where the integration points are located on the // full element. const std::vector<Point>* ref_qp; if (pts != NULL) ref_qp = pts; else ref_qp = &this->qrule->get_points(); std::vector<Point> qp; this->side_map(elem, side.get(), s, *ref_qp, qp); // compute the shape function and derivative values // at the points qp this->reinit (elem, &qp); this->shapes_on_quadrature = shapes_on_quadrature_side; // copy back old data this->_fe_map->get_JxW() = JxW_int; }
void InfFE<Dim,T_radial,T_map>::reinit(const Elem * inf_elem, const std::vector<Point> * const pts, const std::vector<Real> * const weights) { libmesh_assert(base_fe); libmesh_assert(base_fe->qrule); libmesh_assert_equal_to (base_fe->qrule, base_qrule); libmesh_assert(radial_qrule); libmesh_assert(inf_elem); if (pts == libmesh_nullptr) { bool init_shape_functions_required = false; // ----------------------------------------------------------------- // init the radial data fields only when the radial order changes if (current_fe_type.radial_order != fe_type.radial_order) { current_fe_type.radial_order = fe_type.radial_order; // Watch out: this call to QBase->init() only works for // current_fe_type = const! To allow variable Order, // the init() of QBase has to be modified... radial_qrule->init(EDGE2); // initialize the radial shape functions this->init_radial_shape_functions(inf_elem); init_shape_functions_required=true; } bool update_base_elem_required=true; // ----------------------------------------------------------------- // update the type in accordance to the current cell // and reinit if the cell type has changed or (as in // the case of the hierarchics) the shape functions // depend on the particular element and need a reinit if ( ( Dim != 1) && ( (this->get_type() != inf_elem->type()) || (base_fe->shapes_need_reinit()) ) ) { // store the new element type, update base_elem // here. Through \p update_base_elem_required, // remember whether it has to be updated (see below). elem_type = inf_elem->type(); this->update_base_elem(inf_elem); update_base_elem_required=false; // initialize the base quadrature rule for the new element base_qrule->init(base_elem->type()); // initialize the shape functions in the base base_fe->init_base_shape_functions(base_fe->qrule->get_points(), base_elem); init_shape_functions_required=true; } // when either the radial or base part change, // we have to init the whole fields if (init_shape_functions_required) this->init_shape_functions (inf_elem); // computing the distance only works when we have the current // base_elem stored. This happens when fe_type is const, // the inf_elem->type remains the same. Then we have to // update the base elem _here_. if (update_base_elem_required) this->update_base_elem(inf_elem); // compute dist (depends on geometry, therefore has to be updated for // each and every new element), throw radial and base part together this->combine_base_radial (inf_elem); this->_fe_map->compute_map (this->dim, _total_qrule_weights, inf_elem, this->calculate_d2phi); // Compute the shape functions and the derivatives // at all quadrature points. this->compute_shape_functions (inf_elem,base_fe->qrule->get_points()); } else // if pts != libmesh_nullptr { // update the elem_type elem_type = inf_elem->type(); // init radial shapes this->init_radial_shape_functions(inf_elem); // update the base this->update_base_elem(inf_elem); // the finite element on the ifem base { UniquePtr<FEBase> ap_fb(FEBase::build(Dim-1, this->fe_type)); if (base_fe != libmesh_nullptr) delete base_fe; base_fe = ap_fb.release(); } // inite base shapes base_fe->init_base_shape_functions(*pts, base_elem); this->init_shape_functions (inf_elem); // combine the base and radial shapes this->combine_base_radial (inf_elem); // weights if (weights != libmesh_nullptr) { this->_fe_map->compute_map (this->dim, *weights, inf_elem, this->calculate_d2phi); } else { std::vector<Real> dummy_weights (pts->size(), 1.); this->_fe_map->compute_map (this->dim, dummy_weights, inf_elem, this->calculate_d2phi); } // finally compute the ifem shapes this->compute_shape_functions (inf_elem,*pts); } }
void FE<Dim,T>::reinit(const Elem* elem, const std::vector<Point>* const pts, const std::vector<Real>* const weights) { // We can be called with no element. If we're evaluating SCALAR // dofs we'll still have work to do. // libmesh_assert(elem); // Try to avoid calling init_shape_functions // even when shapes_need_reinit bool cached_nodes_still_fit = false; // Most of the hard work happens when we have an actual element if (elem) { // Initialize the shape functions at the user-specified // points if (pts != NULL) { // Set the type and p level for this element this->elem_type = elem->type(); this->_p_level = elem->p_level(); // Initialize the shape functions this->_fe_map->template init_reference_to_physical_map<Dim> (*pts, elem); this->init_shape_functions (*pts, elem); // The shape functions do not correspond to the qrule this->shapes_on_quadrature = false; } // If there are no user specified points, we use the // quadrature rule // update the type in accordance to the current cell // and reinit if the cell type has changed or (as in // the case of the hierarchics) the shape functions need // reinit, since they depend on the particular element shape else { libmesh_assert(this->qrule); this->qrule->init(elem->type(), elem->p_level()); if(this->qrule->shapes_need_reinit()) this->shapes_on_quadrature = false; if (this->elem_type != elem->type() || this->_p_level != elem->p_level() || !this->shapes_on_quadrature) { // Set the type and p level for this element this->elem_type = elem->type(); this->_p_level = elem->p_level(); // Initialize the shape functions this->_fe_map->template init_reference_to_physical_map<Dim> (this->qrule->get_points(), elem); this->init_shape_functions (this->qrule->get_points(), elem); if (this->shapes_need_reinit()) { cached_nodes.resize(elem->n_nodes()); for (unsigned int n = 0; n != elem->n_nodes(); ++n) { cached_nodes[n] = elem->point(n); } } } else { // libmesh_assert_greater (elem->n_nodes(), 1); cached_nodes_still_fit = true; if (cached_nodes.size() != elem->n_nodes()) cached_nodes_still_fit = false; else for (unsigned int n = 1; n < elem->n_nodes(); ++n) { if (!(elem->point(n) - elem->point(0)).relative_fuzzy_equals ((cached_nodes[n] - cached_nodes[0]), 1e-13)) { cached_nodes_still_fit = false; break; } } if (this->shapes_need_reinit() && !cached_nodes_still_fit) { this->_fe_map->template init_reference_to_physical_map<Dim> (this->qrule->get_points(), elem); this->init_shape_functions (this->qrule->get_points(), elem); cached_nodes.resize(elem->n_nodes()); for (unsigned int n = 0; n != elem->n_nodes(); ++n) cached_nodes[n] = elem->point(n); } } // The shape functions correspond to the qrule this->shapes_on_quadrature = true; } } else // With no defined elem, so mapping or caching to // be done, and our "quadrature rule" is one point for nonlocal // (SCALAR) variables and zero points for local variables. { this->elem_type = INVALID_ELEM; this->_p_level = 0; if (!pts) { if (T == SCALAR) { this->qrule->get_points() = std::vector<Point>(1,Point(0)); this->qrule->get_weights() = std::vector<Real>(1,1); } else { this->qrule->get_points().clear(); this->qrule->get_weights().clear(); } this->init_shape_functions (this->qrule->get_points(), elem); } else this->init_shape_functions (*pts, elem); } // Compute the map for this element. if (pts != NULL) { if (weights != NULL) { this->_fe_map->compute_map (this->dim,*weights, elem); } else { std::vector<Real> dummy_weights (pts->size(), 1.); this->_fe_map->compute_map (this->dim,dummy_weights, elem); } } else { this->_fe_map->compute_map (this->dim,this->qrule->get_weights(), elem); } // Compute the shape functions and the derivatives at all of the // quadrature points. if (!cached_nodes_still_fit) { if (pts != NULL) this->compute_shape_functions (elem,*pts); else this->compute_shape_functions(elem,this->qrule->get_points()); } }