117 const std::string &assembler_name,
121 const int quadrature_order,
122 const int mass_quadrature_order,
123 const std::function<
void(
const Eigen::MatrixXd &,
const Eigen::RowVector2d &, Eigen::MatrixXd &,
const double)> bc,
124 const std::function<
void(
const Eigen::MatrixXd &,
const Eigen::RowVector2d &, Eigen::MatrixXd &,
const double)> bc_prime,
125 std::vector<ElementBases> &bases,
126 std::vector<LocalBoundary> &local_boundary,
127 std::map<int, Eigen::MatrixXd> &mapped_boundary)
131 Eigen::MatrixXd polygon;
135 std::map<int, int> new_nodes;
150 polygon.row(i) = mesh.
point(gid);
153 std::vector<int> local_to_global = compute_nonzero_bases_ids(mesh, e, bases, polygon, local_boundary);
155 for (
int i = 0; i < local_to_global.size(); ++i)
157 if (local_to_global[i] >= 0)
161 const auto other_gid = new_nodes.find(gid);
162 if (other_gid != new_nodes.end())
163 local_to_global[i] = other_gid->second;
166 const int tmp = new_nodes.size() + n_bases;
167 new_nodes[gid] = tmp;
168 local_to_global[i] = tmp;
185 const double tol = 1e-10;
186 b.
set_bases_func([polygon, tol, bc](
const Eigen::MatrixXd &uv, std::vector<AssemblyValues> &
val) {
188 val.resize(polygon.rows());
189 for (
size_t i = 0; i < polygon.rows(); ++i)
191 val[i].val.resize(uv.rows(), 1);
194 for (
int i = 0; i < uv.rows(); ++i)
196 bc(polygon, uv.row(i), tmp, tol);
198 for (
size_t j = 0; j < tmp.size(); ++j)
200 val[j].val(i) = tmp(j);
204 b.
set_grads_func([polygon, tol, bc_prime](
const Eigen::MatrixXd &uv, std::vector<AssemblyValues> &
val) {
206 val.resize(polygon.rows());
207 for (
size_t i = 0; i < polygon.rows(); ++i)
209 val[i].grad.resize(uv.rows(), 2);
212 for (
int i = 0; i < uv.rows(); ++i)
214 bc_prime(polygon, uv.row(i), tmp, tol);
215 assert(tmp.rows() == polygon.rows());
217 for (
size_t j = 0; j < tmp.rows(); ++j)
219 val[j].grad.row(i) = tmp.row(j);
225 const auto &mesh2d =
dynamic_cast<const Mesh2D &
>(mesh);
229 for (le = 0; le < mesh2d.n_face_vertices(e); ++le)
231 if (index.edge == primitive_id)
233 index = mesh2d.next_around_face(index);
235 assert(index.edge == primitive_id);
236 Eigen::VectorXi result(2);
238 result(1) = (le + 1) % mesh2d.n_face_vertices(e);
243 const int n_poly_bases = int(local_to_global.size());
244 b.
bases.resize(n_poly_bases);
245 for (
int i = 0; i < n_poly_bases; ++i)
247 b.
bases[i].init(-1, local_to_global[i], i, polygon.row(i));
251 mapped_boundary[e] = polygon;
254 return new_nodes.size();
static int build_bases(const std::string &assembler_name, const int dim, const mesh::Mesh2D &mesh, const int n_bases, const int quadrature_order, const int mass_quadrature_order, const std::function< void(const Eigen::MatrixXd &, const Eigen::RowVector2d &, Eigen::MatrixXd &, const double)> bc, const std::function< void(const Eigen::MatrixXd &, const Eigen::RowVector2d &, Eigen::MatrixXd &, const double)> bc_prime, std::vector< ElementBases > &bases, std::vector< mesh::LocalBoundary > &local_boundary, std::map< int, Eigen::MatrixXd > &mapped_boundary)