void RefMap::calc_second_ref_map(int order) { assert(quad_2d != NULL); int i, j, np = quad_2d->get_num_points(order); AUTOLA_OR(double3x2, k, np); memset(k, 0, k.size); ref_map_pss.force_transform(sub_idx, ctm); for (i = 0; i < nc; i++) { double *dxy, *dxx, *dyy; ref_map_pss.set_active_shape(indices[i]); ref_map_pss.set_quad_order(order, H2D_FN_ALL); dxx = ref_map_pss.get_dxx_values(); dyy = ref_map_pss.get_dyy_values(); dxy = ref_map_pss.get_dxy_values(); for (j = 0; j < np; j++) { k[j][0][0] += coeffs[i][0] * dxx[j]; k[j][0][1] += coeffs[i][1] * dxx[j]; k[j][1][0] += coeffs[i][0] * dxy[j]; k[j][1][1] += coeffs[i][1] * dxy[j]; k[j][2][0] += coeffs[i][0] * dyy[j]; k[j][2][1] += coeffs[i][1] * dyy[j]; } } double3x2* mm = cur_node->second_ref_map[order] = new double3x2[np]; double2x2* m = get_inv_ref_map(order); for (j = 0; j < np; j++) { double a, b; // coefficients in second derivative with respect to xx a = sqr(m[j][0][0])*k[j][0][0] + 2*m[j][0][0]*m[j][0][1]*k[j][1][0] + sqr(m[j][0][1])*k[j][2][0]; b = sqr(m[j][0][0])*k[j][0][1] + 2*m[j][0][0]*m[j][0][1]*k[j][1][1] + sqr(m[j][0][1])*k[j][2][1]; mm[j][0][0] = -(a * m[j][0][0] + b * m[j][1][0]); // du/dx mm[j][0][1] = -(a * m[j][0][1] + b * m[j][1][1]); // du/dy // coefficients in second derivative with respect to xy a = m[j][0][0]*m[j][1][0]*k[j][0][0] + (m[j][0][1]*m[j][1][0] + m[j][0][0]*m[j][1][1])*k[j][1][0] + m[j][0][1]*m[j][1][1]*k[j][2][0]; b = m[j][0][0]*m[j][1][0]*k[j][0][1] + (m[j][0][1]*m[j][1][0] + m[j][0][0]*m[j][1][1])*k[j][1][1] + m[j][0][1]*m[j][1][1]*k[j][2][1]; mm[j][1][0] = -(a * m[j][0][0] + b * m[j][1][0]); // du/dx mm[j][1][1] = -(a * m[j][0][1] + b * m[j][1][1]); // du/dy // coefficients in second derivative with respect to yy a = sqr(m[j][1][0])*k[j][0][0] + 2*m[j][1][0]*m[j][1][1]*k[j][1][0] + sqr(m[j][1][1])*k[j][2][0]; b = sqr(m[j][1][0])*k[j][0][1] + 2*m[j][1][0]*m[j][1][1]*k[j][1][1] + sqr(m[j][1][1])*k[j][2][1]; mm[j][2][0] = -(a * m[j][0][0] + b * m[j][1][0]); // du/dx mm[j][2][1] = -(a * m[j][0][1] + b * m[j][1][1]); // du/dy } }
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; } }
static void calc_bubble_projection(Element* e, Nurbs** nurbs, int order, double2* proj) { ref_map_pss.set_active_element(e); int i, j, k; int mo2 = quad2d.get_max_order(); int np = quad2d.get_num_points(mo2); int qo = e->is_quad() ? make_quad_order(order, order) : order; int nb = ref_map_shapeset.get_num_bubbles(qo); AUTOLA_OR(double2, fn, np); memset(fn, 0, sizeof(double2) * np); double* rhside[2]; double* old[2]; for (i = 0; i < 2; i++) { rhside[i] = new double[nb]; old[i] = new double[np]; memset(rhside[i], 0, sizeof(double) * nb); memset(old[i], 0, sizeof(double) * np); } // compute known part of projection (vertex and edge part) old_projection(e, order, proj, old); // fn values of both components of nonpolynomial function double3* pt = quad2d.get_points(mo2); for (j = 0; j < np; j++) // over all integration points { double2 a; a[0] = ctm.m[0] * pt[j][0] + ctm.t[0]; a[1] = ctm.m[1] * pt[j][1] + ctm.t[1]; calc_ref_map(e, nurbs, a[0], a[1], fn[j]); } double2* result = proj + e->nvert + e->nvert * (order - 1); for (k = 0; k < 2; k++) { for (i = 0; i < nb; i++) // loop over bubble basis functions { // bubble basis functions in all integration points double *bfn; int index_i = ref_map_shapeset.get_bubble_indices(qo)[i]; ref_map_pss.set_active_shape(index_i); ref_map_pss.set_quad_order(mo2); bfn = ref_map_pss.get_fn_values(); for (j = 0; j < np; j++) // over all integration points rhside[k][i] += pt[j][2] * (bfn[j] * (fn[j][k] - old[k][j])); } // solve if (e->nvert == 3) cholsl(bubble_proj_matrix_tri, nb, bubble_tri_p, rhside[k], rhside[k]); else cholsl(bubble_proj_matrix_quad, nb, bubble_quad_p, rhside[k], rhside[k]); for (i = 0; i < nb; i++) result[i][k] = rhside[k][i]; } for (i = 0; i < 2; i++) { delete [] rhside[i]; delete [] old[i]; } }