void InfFE<Dim,T_radial,T_base>::edge_reinit(const Elem *, const unsigned int, const Real, const std::vector<Point> * const pts, const std::vector<Real> * const /*weights*/) { // We don't do this for 1D elements! //libmesh_assert_not_equal_to (Dim, 1); libmesh_not_implemented_msg("ERROR: Edge conditions for infinite elements not implemented!"); if (pts != nullptr) libmesh_not_implemented_msg("ERROR: User-specified points for infinite elements not implemented!"); }
Point FEInterface::ifem_map (const unsigned int dim, const FEType & fe_t, const Elem * elem, const Point & p) { switch (fe_t.inf_map) { case CARTESIAN: { switch (dim) { case 1: return InfFE<1,JACOBI_20_00,CARTESIAN>::map(elem, p); case 2: return InfFE<2,JACOBI_20_00,CARTESIAN>::map(elem, p); case 3: return InfFE<3,JACOBI_20_00,CARTESIAN>::map(elem, p); default: libmesh_error_msg("Invalid dim = " << dim); } } case SPHERICAL: case ELLIPSOIDAL: libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented."); default: libmesh_error_msg("Invalid map = " << fe_t.inf_map); } }
void InfFE<Dim,T_radial,T_base>::reinit(const Elem * inf_elem, const unsigned int s, const Real tolerance, const std::vector<Point> * const pts, const std::vector<Real> * const weights) { if (weights != nullptr) libmesh_not_implemented_msg("ERROR: User-specified weights for infinite elements are not implemented!"); if (pts != nullptr) libmesh_not_implemented_msg("ERROR: User-specified points for infinite elements are not implemented!"); // We don't do this for 1D elements! libmesh_assert_not_equal_to (Dim, 1); libmesh_assert(inf_elem); libmesh_assert(qrule); // We need to allow this as well... // libmesh_assert_not_equal_to (s, 0); // Build the side of interest const std::unique_ptr<const Elem> side(inf_elem->build_side_ptr(s)); // set the element type elem_type = inf_elem->type(); // eventually initialize radial quadrature rule bool radial_qrule_initialized = false; // if we are working on the base-side, the radial function is constant. // With this, we ensure that at least for base elements we reinitialize all quantities // when we enter for the first time. if (s == 0) current_fe_type.radial_order = 0; if (current_fe_type.radial_order != fe_type.radial_order) { if (s > 0) { current_fe_type.radial_order = fe_type.radial_order; radial_qrule->init(EDGE2, inf_elem->p_level()); } else { // build a new 0-dimensional quadrature-rule: radial_qrule.release(); radial_qrule=QBase::build(QGAUSS, 0, fe_type.radial_order); radial_qrule->init(NODEELEM, 0); //the base_qrule is set up with dim-1, but apparently we need dim, so we replace it: base_qrule.release(); base_qrule=QBase::build(qrule->type(), side->dim(), qrule->get_order()); //FIXME: Do I have to care about the order of my neighbours element? //unsigned int side_p_level = elem->p_level(); //if (elem->neighbor_ptr(s) != nullptr) // side_p_level = std::max(side_p_level, elem->neighbor_ptr(s)->p_level()); base_qrule->init(side->type(), side->p_level()); } radial_qrule_initialized = true; } // Initialize the face shape functions if (this->get_type() != inf_elem->type() || base_fe->shapes_need_reinit() || radial_qrule_initialized) this->init_face_shape_functions (qrule->get_points(), side.get()); // compute the face map this->_fe_map->compute_face_map(this->dim, _total_qrule_weights, side.get()); // 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 (inf_elem, this->_fe_map->get_xyz(), qp, tolerance); // just to ensure that we are working on the base and not, for numeric reasons, // somewhere else... if (s==0) { for (unsigned int p=0; p<qp.size(); p++) { qp[p](Dim-1)=-1.; } } // compute the shape function and derivative values // at the points qp this->reinit (inf_elem, &qp); // copy back old data this->_fe_map->get_JxW() = JxW_int; }
Point FEInterface::ifem_inverse_map (const unsigned int dim, const FEType& fe_t, const Elem* elem, const Point& p, const Real tolerance, const bool secure) { switch (dim) { // 1D case 1: { switch (fe_t.inf_map) { case CARTESIAN: return InfFE<1,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure); case SPHERICAL: case ELLIPSOIDAL: libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented."); /* case SPHERICAL: return InfFE<1,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance); case ELLIPSOIDAL: return InfFE<1,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance); */ default: libmesh_error_msg("Invalid map = " << fe_t.inf_map); } } // 2D case 2: { switch (fe_t.inf_map) { case CARTESIAN: return InfFE<2,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure); case SPHERICAL: case ELLIPSOIDAL: libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented."); /* case SPHERICAL: return InfFE<2,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance); case ELLIPSOIDAL: return InfFE<2,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance); */ default: libmesh_error_msg("Invalid map = " << fe_t.inf_map); } } // 3D case 3: { switch (fe_t.inf_map) { case CARTESIAN: return InfFE<3,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure); case SPHERICAL: case ELLIPSOIDAL: libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented."); /* case SPHERICAL: return InfFE<3,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance); case ELLIPSOIDAL: return InfFE<3,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance); */ default: libmesh_error_msg("Invalid map = " << fe_t.inf_map); } } default: libmesh_error_msg("Invalid dim = " << dim); } libmesh_error_msg("We'll never get here!"); Point pt; return pt; }
void InfFE<Dim,T_radial,T_base>::reinit(const Elem * inf_elem, const unsigned int s, const Real tolerance, const std::vector<Point> * const pts, const std::vector<Real> * const weights) { if (weights != nullptr) libmesh_not_implemented_msg("ERROR: User-specified weights for infinite elements are not implemented!"); if (pts != nullptr) libmesh_not_implemented_msg("ERROR: User-specified points for infinite elements are not implemented!"); // We don't do this for 1D elements! libmesh_assert_not_equal_to (Dim, 1); libmesh_assert(inf_elem); libmesh_assert(qrule); // Don't do this for the base libmesh_assert_not_equal_to (s, 0); // Build the side of interest const std::unique_ptr<const Elem> side(inf_elem->build_side_ptr(s)); // set the element type elem_type = inf_elem->type(); // eventually initialize radial quadrature rule bool radial_qrule_initialized = false; if (current_fe_type.radial_order != fe_type.radial_order) { current_fe_type.radial_order = fe_type.radial_order; radial_qrule->init(EDGE2, inf_elem->p_level()); radial_qrule_initialized = true; } // Initialize the face shape functions if (this->get_type() != inf_elem->type() || base_fe->shapes_need_reinit() || radial_qrule_initialized) this->init_face_shape_functions (qrule->get_points(), side.get()); // compute the face map this->_fe_map->compute_face_map(this->dim, _total_qrule_weights, side.get()); // 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 (inf_elem, this->_fe_map->get_xyz(), qp, tolerance); // compute the shape function and derivative values // at the points qp this->reinit (inf_elem, &qp); // copy back old data this->_fe_map->get_JxW() = JxW_int; }
std::unique_ptr<NonlinearSolver<T>> NonlinearSolver<T>::build(sys_type &, const SolverPackage) { libmesh_not_implemented_msg("ERROR: libMesh was compiled without nonlinear solver support"); }