void RefMap::calc_inv_ref_map(int order) { assert(quad_2d != NULL); int i, j, np = quad_2d->get_num_points(order); // construct jacobi matrices of the direct reference map for all integration points AUTOLA_OR(double2x2, m, np); memset(m, 0, m.size); ref_map_pss.force_transform(sub_idx, ctm); for (i = 0; i < nc; i++) { double *dx, *dy; ref_map_pss.set_active_shape(indices[i]); ref_map_pss.set_quad_order(order); ref_map_pss.get_dx_dy_values(dx, dy); for (j = 0; j < np; j++) { m[j][0][0] += coeffs[i][0] * dx[j]; m[j][0][1] += coeffs[i][0] * dy[j]; m[j][1][0] += coeffs[i][1] * dx[j]; m[j][1][1] += coeffs[i][1] * dy[j]; } } // calculate the jacobian and inverted matrix double trj = get_transform_jacobian(); double2x2* irm = cur_node->inv_ref_map[order] = new double2x2[np]; double* jac = cur_node->jacobian[order] = new double[np]; for (i = 0; i < np; i++) { jac[i] = (m[i][0][0] * m[i][1][1] - m[i][0][1] * m[i][1][0]); double ij = 1.0 / jac[i]; error_if(!finite(ij), "1/jac[%d] is infinity when calculating inv. ref. map for order %d (jac=%g)", i, order); assert_msg(ij == ij, "1/jac[%d] is NaN when calculating inv. ref. map for order %d (jac=%g)", i, order); // invert and transpose the matrix irm[i][0][0] = m[i][1][1] * ij; irm[i][0][1] = -m[i][1][0] * ij; irm[i][1][0] = -m[i][0][1] * ij; irm[i][1][1] = m[i][0][0] * ij; jac[i] *= trj; } }
void RefMap::calc_tangent(int edge, int eo) { int i, j; int np = quad_2d->get_num_points(eo); double3* tan = cur_node->tan[edge] = new double3[np]; int a = edge, b = element->next_vert(edge); if (!element->is_curved()) { // straight edges: the tangent at each point is just the edge length tan[0][0] = element->vn[b]->x - element->vn[a]->x; tan[0][1] = element->vn[b]->y - element->vn[a]->y; tan[0][2] = sqrt(sqr(tan[0][0]) + sqr(tan[0][1])); double inorm = 1.0 / tan[0][2]; tan[0][0] *= inorm; tan[0][1] *= inorm; tan[0][2] *= (edge == 0 || edge == 2) ? ctm->m[0] : ctm->m[1]; for (i = 1; i < np; i++) memcpy(tan+i, tan, sizeof(double3)); } else { // construct jacobi matrices of the direct reference map at integration points along the edge static double2x2 m[15]; assert(np <= 15); memset(m, 0, np*sizeof(double2x2)); ref_map_pss.force_transform(sub_idx, ctm); for (i = 0; i < nc; i++) { double *dx, *dy; ref_map_pss.set_active_shape(indices[i]); ref_map_pss.set_quad_order(eo); ref_map_pss.get_dx_dy_values(dx, dy); for (j = 0; j < np; j++) { m[j][0][0] += coeffs[i][0] * dx[j]; m[j][0][1] += coeffs[i][0] * dy[j]; m[j][1][0] += coeffs[i][1] * dx[j]; m[j][1][1] += coeffs[i][1] * dy[j]; } } // multiply them by the vector of the reference edge double2* v1 = ref_map_shapeset.get_ref_vertex(a); double2* v2 = ref_map_shapeset.get_ref_vertex(b); double ex = (*v2)[0] - (*v1)[0]; double ey = (*v2)[1] - (*v1)[1]; for (i = 0; i < np; i++) { double3& t = tan[i]; t[0] = m[i][0][0]*ex + m[i][0][1]*ey; t[1] = m[i][1][0]*ex + m[i][1][1]*ey; t[2] = sqrt(sqr(t[0]) + sqr(t[1])); double inorm = 1.0 / t[2]; t[0] *= inorm; t[1] *= inorm; t[2] *= (edge == 0 || edge == 2) ? ctm->m[0] : ctm->m[1]; } } }