示例#1
0
int test_quadrature_3d() {
	int ret = ERR_SUCCESS;

	// Hexs.
	if (get_quadrature(HERMES_MODE_HEX) != NULL) {
		info("- Testing 3D quadrature (hex) -----");

		TC3D fn_hex[] = {
			TC3D(fn_3d_1, 16.0, 2, 2, 2, "x^2 + y^2 + z^2 + x*y*z + x + y + z + 1"),
			TC3D(fn_3d_2, 184.0/15.0, 2, 3, 4, "x^2 + y^3 + z^4 + x*y*z + x + y + z + 1"),
			TC3D(fn_3d_3, 184.0/15.0, 3, 4, 2, "x^3 + y^4 + z^2 + x*y*z + x + y + z + 1"),
			TC3D(fn_3d_4, 184.0/15.0, 4, 2, 3, "x^4 + y^2 + z^3 + x*y*z + x + y + z + 1")
		};

		for (unsigned int i = 0; i < countof(fn_hex); i++) {
			if ((ret = test_quadrature_3d_hex(fn_hex[i].fn, fn_hex[i].exact, fn_hex[i].min_h_order, fn_hex[i].min_v_order, fn_hex[i].min_u_order, fn_hex[i].fn_name)) != ERR_SUCCESS)
				return ret;
		}

		info("- Testing 3D quadrature (hex) - surf -----");

		TC3D fn_hex_surf[] = {
			TC3D(fn_3d_1, 64.0, 2, 2, 2, "x^2 + y^2 + z^2 + x*y*z + x + y + z + 1")
		};

		for (unsigned int i = 0; i < countof(fn_hex_surf); i++) {
			if ((ret = test_quadrature_3d_hex_surf(fn_hex_surf[i].fn, fn_hex_surf[i].exact, fn_hex_surf[i].min_h_order, fn_hex_surf[i].min_v_order, fn_hex_surf[i].min_u_order, fn_hex_surf[i].fn_name)) != ERR_SUCCESS)
				return ret;
		}
	}

	// Tetras.
	if (get_quadrature(HERMES_MODE_TET) != NULL) {
		info("- Testing 3D quadrature (tetra) -----");

		TC3D Funcetra[] = {
			TC3D(fn_3d_1, 8.0/9.0, 3, 0, 0, "x^2 + y^2 + z^2 + x*y*z + x + y + z + 1")
		};

		for (unsigned int i = 0; i < countof(Funcetra); i++) {
			if ((ret = test_quadrature_3d_tetra(Funcetra[i].fn, Funcetra[i].exact, Funcetra[i].min_h_order, Funcetra[i].fn_name)) != ERR_SUCCESS)
				return ret;
		}
	}

	// TODO: Prisms.

	return ERR_SUCCESS;
}
示例#2
0
// l2 product
double l2_product(RealFunction *fu, RealFunction *fv) {
	_F_
	Quad3D *quad = get_quadrature(MODE);

	// integrate with maximum order
	order3_t o = fu->get_fn_order() + fv->get_fn_order() + order3_t(2, 2, 2);
	o.limit();

	int np = quad->get_num_points(o);
	QuadPt3D *pt = quad->get_points(o);
	fu->precalculate(np, pt, FN_DEFAULT);
	fv->precalculate(np, pt, FN_DEFAULT);

	scalar *u0, *u1, *u2;
	u0 = fu->get_fn_values(0);
	u1 = fu->get_fn_values(1);
	u2 = fu->get_fn_values(2);

	scalar *v0, *v1, *v2;
	v0 = fv->get_fn_values(0);
	v1 = fv->get_fn_values(1);
	v2 = fv->get_fn_values(2);

	// integrating over reference brick -> jacobian is 1.0 (we do not have to bother with refmap)
	double result = 0.0;
	for (int i = 0; i < np; i++)
		result += pt[i].w * (REAL(sqr(u0[i] - v0[i]) + sqr(u1[i] - v1[i]) + sqr(u2[i] - v2[i])));

	return result;
}
示例#3
0
/// Calculates the absolute error between sln1 and sln2 using function fn
double calc_error(double (*fn)(MeshFunction*, MeshFunction*, int, QuadPt3D*), MeshFunction *sln1, MeshFunction *sln2) {
	_F_
	Mesh *meshes[2] = { sln1->get_mesh(), sln2->get_mesh() };
	Transformable *tr[2] = { sln1, sln2 };
	Traverse trav;
	trav.begin(2, meshes, tr);

	double error = 0.0;
	Element **ee;
	while ((ee = trav.get_next_state(NULL, NULL)) != NULL) {
		ElementMode3D mode = ee[0]->get_mode();

		RefMap *ru = sln1->get_refmap();
		Ord3 order = max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order();
		order.limit();

		Quad3D *quad = get_quadrature(mode);
		int np = quad->get_num_points(order);
		QuadPt3D *pt = quad->get_points(order);

		error += fn(sln1, sln2, np, pt);
	}
	trav.finish();

	return error > H3D_TINY ? sqrt(error) : error;		// do not ruin the precision by taking the sqrt
}
示例#4
0
// check bubble functions
bool test_zero_values_of_bubble_fns(Shapeset *shapeset) {
	_F_
	Quad3D *quad = get_quadrature(MODE);

	order3_t order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER);

	int n_fns = shapeset->get_num_bubble_fns(order);
	int *bubble_fn = shapeset->get_bubble_indices(order);

	for (int fn = 0; fn < n_fns; fn++) {
		printf("  * Bubble fn #%d ", bubble_fn[fn]);

		// vertices
		const Point3D *vtx_pt = REF_DOMAIN::get_vertices();
		for (int i = 0; i < Hex::NUM_VERTICES; i++) {
			if (shapeset->get_fn_value(bubble_fn[fn], vtx_pt[i].x, vtx_pt[i].y, vtx_pt[i].z, 0) > EPS) {
				warning("Bubble fn #%d is not zero at (% lf, %lf, %lf), vertex #%d.", bubble_fn[fn], vtx_pt[i].x, vtx_pt[i].y, vtx_pt[i].z, i);
				return false;
			}
		}

		// edges
		for (int iedge = 0; iedge < Hex::NUM_EDGES; iedge++) {
			order1_t max_order = quad->get_edge_max_order(iedge);
			int np = quad->get_edge_num_points(iedge, max_order);
			QuadPt3D *pts = quad->get_edge_points(iedge, max_order);
			double vals[np];
			shapeset->get_fn_values(bubble_fn[fn], np, pts, 0, vals);
			for (int j = 0; j < np; j++) {
				if (vals[j] > EPS) {
					warning("Bubble fn #%d is not zero at (% lf, %lf, %lf), edge %d.", bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, iedge);
					return false;
				}
			}
		}

		// faces
		for (int iface = 0; iface < Hex::NUM_FACES; iface++) {
			order2_t max_order = quad->get_face_max_order(iface);
			int np = quad->get_face_num_points(iface, max_order);
			QuadPt3D *pts = quad->get_face_points(iface, max_order);
			double vals[np];
			shapeset->get_fn_values(bubble_fn[fn], np, pts, 0, vals);
			for (int j = 0; j < np; j++) {
				if (vals[j] > EPS) {
					warning("Bubble fn #%d is not zero at (% lf, %lf, %lf), face %d.", bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, iface);
					return false;
				}
			}
		}

		printf("... ok\n");
	}

	return true;
}
示例#5
0
void SortMassVecs(struct StateData * state)
{
	const QUAD * surfQuad = nil;
	const QUAD * volQuad = nil;
	if (!volQuad)
	{
		if (state->volume_mesh->parametric && !state->volume_mesh->parametric->not_all)
		{
			volQuad = get_quadrature(state->volume_mesh->dim, 2*state->fe_space_volume->bas_fcts->degree + 2);
		}
		else
		{
			volQuad = get_quadrature(state->volume_mesh->dim, 2*state->fe_space_volume->bas_fcts->degree - 2);
		}
	}
	if (!surfQuad)
	{
		if (state->surface_mesh->parametric && !state->surface_mesh->parametric->not_all)
		{
			surfQuad = get_quadrature(state->surface_mesh->dim, 2*state->fe_space_surface->bas_fcts->degree + 2);
		}
		else
		{
			surfQuad = get_quadrature(state->surface_mesh->dim, 2*state->fe_space_surface->bas_fcts->degree - 2);
		}
	}

	dof_set(0.0,state->massM_volume);
	L2scp_fct_bas(one_function, volQuad, state->massM_volume);

	dof_set(0.0,state->massM_surface);
	L2scp_fct_bas(one_function, surfQuad, state->massM_surface);

	FOR_ALL_DOFS(state->massM_surface_on_vol->fe_space->admin,
	             int surfDOF = state->VolumeToSurfaceMap->vec[dof];
	             if(surfDOF != -1)
	             state->massM_surface_on_vol->vec[dof] = state->massM_surface->vec[surfDOF];
	             else
		             state->massM_surface_on_vol->vec[dof] = 0;
		            );
示例#6
0
void buildVolume(struct StateData * state)
{
    FUNCNAME("buildVolume");
    MSG("Building volume P: %d\n", state->solveCount);

    static struct op_info *op_info = nil;
    static const REAL     **(*fill_a)(const EL_INFO *, void *) = nil;
    static void           *a_info = nil;

    static const DOF_ADMIN *admin = nil;
    static int             n;
    static const DOF    *(*get_dof)(const EL *, const DOF_ADMIN *, DOF *);
    static const S_CHAR *(*get_bound)(const EL_INFO *, S_CHAR *);
    static const QUAD     *quad = nil;

    TRAVERSE_STACK        *stack = get_traverse_stack();
    const EL_INFO         *el_info;
    FLAGS                  fill_flag;
    const REAL           **a_mat;

    if (!quad)
        quad = get_quadrature(state->fe_space_volume->bas_fcts->dim, 2*state->fe_space_volume->bas_fcts->degree);

    SortMassVecs(state);
    if (admin != state->fe_space_volume->admin)
    {
        OPERATOR_INFO          o_info2 = {nil};
        const EL_MATRIX_INFO  *matrix_info;
        const BAS_FCTS         *bas_fcts = state->fe_space_volume->bas_fcts;

        admin      = state->fe_space_volume->admin;

        n = bas_fcts->n_bas_fcts;
        get_dof    = bas_fcts->get_dof_indices;
        get_bound  = bas_fcts->get_bound;

        if (!op_info)
            op_info = MEM_ALLOC(1, struct op_info);

        o_info2.row_fe_space = o_info2.col_fe_space = state->fe_space_volume;

        o_info2.quad[2]        = quad;
        o_info2.init_element   = init_element;
        o_info2.LALt      = LALt;
        o_info2.LALt_symmetric = true;
        o_info2.user_data      = op_info;

        matrix_info = fill_matrix_info(&o_info2, nil);
        fill_a = matrix_info->el_matrix_fct;
        a_info = matrix_info->fill_info;
    }
示例#7
0
void HcurlSpace::calc_edge_boundary_projection(Element *elem, int iedge) {
	_F_
  Edge::Key edge = mesh->get_edge_id(elem, iedge);
	EdgeData *enode = en_data[edge];
	if (enode->bc_type != H3D_BC_ESSENTIAL) return;			// process only Dirichlet BC
	if (enode->bc_proj != NULL) return;					// projection already calculated

	int num_fns;
	if (enode->ced) {
		assert(enode->edge_ncomponents > 0);
    Edge::Key edge_id = enode->edge_baselist[0].edge_id;
		num_fns = en_data[edge_id]->n;
	}
	else
		num_fns = enode->n;
	if (num_fns <= 0) return;

	scalar *proj_rhs = new scalar[num_fns];
	MEM_CHECK(proj_rhs);
	for (int i = 0; i < num_fns; i++) proj_rhs[i] = 0.0;

	RefMap ref_map(mesh);
	ref_map.set_active_element(elem);

	Quad3D *quad = get_quadrature(elem->get_mode());
	Ord1 order_rhs = quad->get_edge_max_order(iedge);
	int np = quad->get_edge_num_points(iedge, order_rhs);
	QuadPt3D *pt = quad->get_edge_points(iedge, order_rhs);

	double *edge_phys_x = ref_map.get_phys_x(np, pt);
	double *edge_phys_y = ref_map.get_phys_y(np, pt);
	double *edge_phys_z = ref_map.get_phys_z(np, pt);

	for (int k = 0; k < np; k++) {
		// FIXME: use bc_vec_value_callback_by_coord
		if (bc_value_callback_by_coord(enode->marker, edge_phys_x[k], edge_phys_y[k], edge_phys_z[k]) != 0.)
			EXIT(HERMES_ERR_NOT_IMPLEMENTED);  // projection of nonzero BC not implemented, see comment in .h
	}

	delete [] edge_phys_x;
	delete [] edge_phys_y;
	delete [] edge_phys_z;

	// save vector of zeros as a projection
	enode->bc_proj = proj_rhs;
}
示例#8
0
文件: zero.cpp 项目: MathPhys/hermes
// check bubble functions
bool test_zero_values_of_bubble_fns(Shapeset *shapeset) {
	_F_
	Quad3D *quad = get_quadrature(MODE);

	order3_t order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER);

	int n_fns = shapeset->get_num_bubble_fns(order);
	int *bubble_fn = shapeset->get_bubble_indices(order);

	for (int fn = 0; fn < n_fns; fn++) {
		printf("  * Bubble fn #%d ", bubble_fn[fn]);

		// edges
		for (int i = 0; i < Hex::NUM_EDGES; i++) {
			int max_order = quad->get_edge_max_order(i);
			QuadPt3D *pts = quad->get_edge_points(i, max_order);
			for (int j = 0; j < quad->get_edge_num_points(i, max_order); j++) {
				int comp = RefHex::get_edge_tangent_direction(i);
				if (shapeset->get_fn_value(bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, comp) > EPS) {
					warning("Bubble fn #%d is not zero at (% lf, %lf, %lf), edge %d.", bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, i);
					return false;
				}
			}
		}

		// faces
		for (int i = 0; i < Hex::NUM_FACES; i++) {
			order2_t max_order = quad->get_face_max_order(i);
			QuadPt3D *pts = quad->get_face_points(i, max_order);
			for (int j = 0; j < quad->get_face_num_points(i, max_order); j++) {
				for(int i_comp = 0; i_comp < 2; i_comp++){
					int comp = RefHex::get_face_tangent_direction(i, i_comp);
					if (shapeset->get_fn_value(bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, comp) > EPS) {
						warning("Bubble fn #%d is not zero at (% lf, %lf, %lf), face %d.", bubble_fn[fn], pts[j].x, pts[j].y, pts[j].z, i);
						return false;
					}
				}
			}
		}

		printf("... ok\n");
	}

	return true;
}
示例#9
0
文件: norm.cpp 项目: MathPhys/hermes
/// Calculates the norm of sln using function fn
double calc_norm(double (*fn)(MeshFunction*, int, QuadPt3D*), MeshFunction *sln) {
	_F_
	double norm = 0.0;
	Mesh *mesh = sln->get_mesh();

	FOR_ALL_ACTIVE_ELEMENTS(eid, mesh) {
		Element *e = mesh->elements[eid];
		sln->set_active_element(e);

		RefMap *ru = sln->get_refmap();
		order3_t o = sln->get_fn_order() + ru->get_inv_ref_order();
		o.limit();

		Quad3D *quad = get_quadrature(e->get_mode());
		int np = quad->get_num_points(o);
		QuadPt3D *pt = quad->get_points(o);

		norm += fn(sln, np, pt);
	}
示例#10
0
// l2 product
double l2_product(ShapeFunction *fu, ShapeFunction *fv) {
	_F_
	Quad3D *quad = get_quadrature(MODE_HEXAHEDRON);

	Ord3 o = fu->get_fn_order() + fv->get_fn_order() + Ord3(1, 1, 1);

	QuadPt3D *pt = quad->get_points(o);
	int np = quad->get_num_points(o);

	fu->precalculate(np, pt, FN_VAL);
	fv->precalculate(np, pt, FN_VAL);

	double *uval = fu->get_fn_values();
	double *vval = fv->get_fn_values();

	// integrating over reference brick -> jacobian is 1.0 (we do not have to bother with refmap)
	double result = 0.0;
	for (int i = 0; i < np; i++)
		result += pt[i].w * (uval[i] * vval[i]);

	return result;
}
示例#11
0
void HcurlSpace::calc_face_boundary_projection(Element *elem, int iface) {
	_F_
	Facet::Key facet_idx = mesh->get_facet_id(elem, iface);
	FaceData *fnode = fn_data[facet_idx];

	if (fnode->bc_type != H3D_BC_ESSENTIAL) return;
	if (fnode->bc_proj != NULL) return;
	if (fnode->n <= 0) return;

	scalar *proj_rhs = new scalar[fnode->n];
	MEM_CHECK(proj_rhs);
	for (int i = 0; i < fnode->n; i++) proj_rhs[i] = 0.0;

	RefMap ref_map(mesh);
	ref_map.set_active_element(elem);

	Quad3D *quad = get_quadrature(elem->get_mode());
	Ord2 order_rhs = quad->get_face_max_order(iface);
	int np = quad->get_face_num_points(iface, order_rhs);
	QuadPt3D *pt = quad->get_face_points(iface, order_rhs);

	double *face_phys_x = ref_map.get_phys_x(np, pt);
	double *face_phys_y = ref_map.get_phys_y(np, pt);
	double *face_phys_z = ref_map.get_phys_z(np, pt);

	for (int k = 0; k < quad->get_face_num_points(iface, order_rhs); k++) {
		// FIXME: use bc_vec_value_callback_by_coord
		if (bc_value_callback_by_coord(fnode->marker, face_phys_x[k], face_phys_y[k], face_phys_z[k]) != 0.)
			EXIT(HERMES_ERR_NOT_IMPLEMENTED);  // projection of nonzero BC not implemented, see comment in .h
	}

	delete [] face_phys_x;
	delete [] face_phys_y;
	delete [] face_phys_z;

	// save vector of zeros as a projection
	fnode->bc_proj = proj_rhs;
}
示例#12
0
/// Calculates the norm of sln using function fn
double calc_norm(double (*fn)(MeshFunction*, int, QuadPt3D*), MeshFunction *sln) {
	_F_
	double norm = 0.0;
	Mesh *mesh = sln->get_mesh();

	for(std::map<unsigned int, Element*>::iterator it = mesh->elements.begin(); it != mesh->elements.end(); it++)
		if (it->second->used && it->second->active) {
      Element *e = mesh->elements[it->first];
		  sln->set_active_element(e);

		  RefMap *ru = sln->get_refmap();
		  Ord3 o = sln->get_fn_order() + ru->get_inv_ref_order();
		  o.limit();

		  Quad3D *quad = get_quadrature(e->get_mode());
		  int np = quad->get_num_points(o);
		  QuadPt3D *pt = quad->get_points(o);

		  norm += fn(sln, np, pt);
	  }

	return norm > H3D_TINY ? sqrt(norm) : norm;			// do not ruin the precision by taking the sqrt
}
示例#13
0
文件: proj.cpp 项目: MathPhys/hermes
Projection::Projection(Solution *afn, Element *e, Shapeset *ss)
{
	_F_
	this->sln = afn;
	this->ss = ss;

	mesh = sln->get_mesh();
	// TODO: check that the element 'e' is not active and has 8 sons
	base_elem = mesh->elements[e->id];

	quad = get_quadrature(e->get_mode());

	fu = new ShapeFunction(ss);
	fv = new ShapeFunction(ss);

	fu->set_active_element(base_elem);
	fv->set_active_element(base_elem);

	// null
	n_fns = 0;
	fn_idx = NULL;
	proj_coef = NULL;
}
示例#14
0
bool test_cont_values_of_vertex_fns(Mesh *mesh, unsigned int fid, int pos0, int pos1, Shapeset *shapeset) {
	_F_
	Facet *facet = mesh->facets[fid];
	Quad3D *quad = get_quadrature(MODE);

	Element *h[2] = {
		mesh->elements[facet->left],
		mesh->elements[facet->right]
	};

	// face vertices
	const int *face_vtx[] = {
		h[0]->get_face_vertices(facet->left_face_num),
		h[1]->get_face_vertices(facet->right_face_num)
	};

	RefMap rm(mesh);
	Pts vpts[2];

	// get coordinates of vertices on the face
	int vnp = Quad::NUM_VERTICES;
	for (int i = 0; i < 2; i++) {
		QuadPt3D *rd_vtx_pt = quad->get_vertex_points();

		QuadPt3D *pt = new QuadPt3D[Quad::NUM_VERTICES];
		for (int j = 0; j < vnp; j++)
			pt[j] = rd_vtx_pt[face_vtx[i][j]];

		rm.set_active_element(h[i]);

		vpts[i].ref_pt = pt;
		vpts[i].phys_x = rm.get_phys_x(vnp, pt);
		vpts[i].phys_y = rm.get_phys_y(vnp, pt);
		vpts[i].phys_z = rm.get_phys_z(vnp, pt);

		// sort points by physical coordinates
		vpts[i].sort = new int [vnp];
		for (int j = 0; j < vnp; j++)
			vpts[i].sort[j] = j;
		sort_pts = vpts + i;
		qsort(vpts[i].sort, vnp, sizeof(int), compare);
	}

	// we know which vertices correspond to each other, since we sorted them by their phys. coordinates
	// we use it for comparing matching vertex functions

	// obtain coordinates where vertex functions are going to be evaluated
	Pts fpts[2];
	Ord2 face_ord = quad->get_face_max_order(facet->left_face_num);
	int np = quad->get_face_num_points(facet->left_face_num, face_ord);

	QuadPt3D *pt[2] = {
		quad->get_face_points(facet->left_face_num, face_ord),
		quad->get_face_points(facet->right_face_num, face_ord)
	};

	// transform the coorinates so we can compare them
	for (int i = 0; i < 2; i++) {
		rm.set_active_element(h[i]);

		fpts[i].ref_pt = pt[i];
		fpts[i].phys_x = rm.get_phys_x(np, pt[i]);
		fpts[i].phys_y = rm.get_phys_y(np, pt[i]);
		fpts[i].phys_z = rm.get_phys_z(np, pt[i]);

		// sort points by physical coordinates
		fpts[i].sort = new int [np];
		for (int j = 0; j < np; j++)
			fpts[i].sort[j] = j;
		sort_pts = fpts + i;
		qsort(fpts[i].sort, np, sizeof(int), compare);
	}

	// loop through vertex functions
	for (int k = 0; k < Quad::NUM_VERTICES; k++) {
		int i1 = vpts[0].sort[k];
		int i2 = vpts[1].sort[k];

		// get values of vertex functions
		double uval[np], vval[np];
		shapeset->get_fn_values(shapeset->get_vertex_index(face_vtx[0][i1]), np, pt[0], 0, uval);
		shapeset->get_fn_values(shapeset->get_vertex_index(face_vtx[1][i2]), np, pt[1], 0, vval);

		// compare their values
		for (int i = 0; i < np; i++) {
			int j1 = fpts[0].sort[i];
			int j2 = fpts[1].sort[i];

			if (fabs(uval[j1] - vval[j2]) > EPS) {
				printf("failed\n");
				warning("Vertex fn not continuous @(% lf, % lf, % lf), diff = % e",
					fpts[0].ref_pt[j1].x, fpts[0].ref_pt[j1].y, fpts[0].ref_pt[j1].z,
					fabs(uval[j1] - vval[j2]));
				return false;
			}
		}
	}

	// free memory
	for (int i = 0; i < 2; i++) {
		delete [] vpts[i].ref_pt;
		delete [] vpts[i].phys_x;
		delete [] vpts[i].phys_y;
		delete [] vpts[i].phys_z;
		delete [] vpts[i].sort;

		delete [] fpts[i].phys_x;
		delete [] fpts[i].phys_y;
		delete [] fpts[i].phys_z;
		delete [] fpts[i].sort;
	}

	return true;
}
示例#15
0
文件: zero.cpp 项目: MathPhys/hermes
// check edge functions
bool test_zero_values_of_edge_fns(Shapeset *shapeset) {
	_F_
	const int num_edges = 11;
	// indexing[edge] => { edges to check where the function is zero (local indices) }
	int edges[][num_edges] = {
		{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 10 },
	};
	const int num_faces = 4;
	// indexing[edge] => { faces to check where the function is zero (local indices) }
	int faces[][num_faces] = {
		{ 0, 1, 3, 5 },
		{ 0, 2, 3, 5 },
		{ 0, 1, 2, 5 },
		{ 1, 2, 3, 5 },
		{ 1, 3, 4, 5 },
		{ 0, 3, 4, 5 },
		{ 0, 2, 4, 5 },
		{ 1, 2, 4, 5 },
		{ 0, 1, 3, 4 },
		{ 0, 2, 3, 4 },
		{ 0, 1, 2, 4 },
		{ 1, 2, 3, 4 },
	};

	Quad3D *quad = get_quadrature(MODE);
	for (int iedge = 0; iedge < Hex::NUM_EDGES; iedge++) {
		for (int ori = 0; ori < 2; ori++) {
			order1_t order = H3D_MAX_ELEMENT_ORDER;
			int n_fns = shapeset->get_num_edge_fns(order);
			int *edge_fn = shapeset->get_edge_indices(iedge, ori, order);

			for (int fn = 0; fn < n_fns; fn++) {
				printf("  * Edge fn #%d (edge = %d, ori = %d)", edge_fn[fn], iedge, ori);

				// edges
				for (int i = 0; i < num_edges; i++) {
					int max_order = quad->get_edge_max_order(edges[iedge][i]);
					QuadPt3D *pts = quad->get_edge_points(edges[iedge][i], max_order);
					for (int j = 0; j < quad->get_edge_num_points(iedge, max_order); j++) {
						int comp = RefHex::get_edge_tangent_direction(edges[iedge][i]);
						if (shapeset->get_fn_value(edge_fn[fn], pts[j].x, pts[j].y, pts[j].z, comp) > EPS) {
							warning("Edge fn #%d is not zero at (% lf, %lf, %lf), edge %d, component %d.\n", edge_fn[fn], pts[j].x, pts[j].y, pts[j].z, edges[iedge][i], comp);
							return false;
						}
					}
				}

				// faces
				for (int i = 0; i < num_faces; i++) {
					order2_t max_order = quad->get_face_max_order(faces[iedge][i]);
					QuadPt3D *pts = quad->get_face_points(faces[iedge][i], max_order);
					for (int j = 0; j < quad->get_face_num_points(faces[iedge][i], max_order); j++) {
						for (int icomp = 0; icomp < 2; icomp++) {
							int comp = RefHex::get_face_tangent_direction(faces[iedge][i], icomp);
							if (shapeset->get_fn_value(edge_fn[fn], pts[j].x, pts[j].y, pts[j].z, comp) > EPS) {
								warning("Edge fn #%d is not zero at (% lf, %lf, %lf), face %d.", edge_fn[fn], pts[j].x, pts[j].y, pts[j].z, faces[iedge][i]);
								return false;
							}
						}
					}
				}

				printf("... ok\n");
			}
		}
	}

	return true;
}
示例#16
0
// check face functions
bool test_zero_values_of_face_fns(Shapeset *shapeset) {
	_F_
	const int num_vertices = 8;
	// indexing[face] => { vertices to check where the function is zero (local indices) }
	int vertices[][num_vertices] = {
		{ 0, 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 }
	};
	const int num_edges = 12;
	// indexing[face] => { edges to check where the function is zero (local indices) }
	int edges[][num_edges] = {
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
	};
	const int num_faces = 5;
	// indexing[face] => { faces to check where the function is zero (local indices) }
	int faces[][num_faces] = {
		{ 1, 2, 3, 4, 5 },
		{ 0, 2, 3, 4, 5 },
		{ 0, 1, 3, 4, 5 },
		{ 0, 1, 2, 4, 5 },
		{ 0, 1, 2, 3, 5 },
		{ 0, 1, 2, 3, 4 }
	};

	Quad3D *quad = get_quadrature(MODE);
	for (int face = 0; face < Hex::NUM_FACES; face++) {
		for (int ori = 0; ori < 8; ori++) {
			order2_t order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER);

			int n_fns = shapeset->get_num_face_fns(order);
			int *face_fn = shapeset->get_face_indices(face, ori, order);

			for (int fn = 0; fn < n_fns; fn++) {
				printf("  * Face fn #%d (face = %d, ori = %d) ", face_fn[fn], face, ori);

				// vertices
				const Point3D *vtx_pt = REF_DOMAIN::get_vertices();
				int *idx = vertices[face];
				for (int i = 0; i < num_vertices; i++) {
					if (shapeset->get_fn_value(face_fn[fn], vtx_pt[idx[i]].x, vtx_pt[idx[i]].y, vtx_pt[idx[i]].z, 0) > EPS) {
						warning("Face fn #%d is not zero at (% lf, %lf, %lf), vertex #%d.", face_fn[fn], vtx_pt[idx[i]].x, vtx_pt[idx[i]].y, vtx_pt[idx[i]].z, idx[i]);
						return false;
					}
				}

				// edges
				for (int i = 0; i < num_edges; i++) {
					order1_t max_order = quad->get_edge_max_order(edges[face][i]);
					int np = quad->get_edge_num_points(edges[face][i], max_order);
					QuadPt3D *pts = quad->get_edge_points(edges[face][i], max_order);
					double vals[np];
					shapeset->get_fn_values(face_fn[fn], np, pts, 0, vals);
					for (int j = 0; j < np; j++) {
						if (vals[j] > EPS) {
							warning("Face fn #%d is not zero at (% lf, %lf, %lf), edge %d.", face_fn[fn], pts[j].x, pts[j].y, pts[j].z, edges[face][i]);
							return false;
						}
					}
				}

				// faces
				for (int i = 0; i < num_faces; i++) {
					order2_t max_order = quad->get_face_max_order(faces[face][i]);
					int np = quad->get_face_num_points(faces[face][i], max_order);
					QuadPt3D *pts = quad->get_face_points(faces[face][i], max_order);
					double vals[np];
					shapeset->get_fn_values(face_fn[fn], np, pts, 0, vals);
					for (int j = 0; j < np; j++) {
						if (vals[j] > EPS) {
							warning("Face fn #%d is not zero at (% lf, %lf, %lf), face %d.", face_fn[fn], pts[j].x, pts[j].y, pts[j].z, faces[face][i]);
							return false;
						}
					}
				}

				printf("... ok\n");
			}
		}
	}

	return true;
}
示例#17
0
// check vertex functions
bool test_zero_values_of_vertex_fns(Shapeset *shapeset) {
	_F_
	const int num_vertices = 7;
	// indexing[vertex] => { vertices to check where the function is zero (local indices) }
	int vertices[][num_vertices] = {
		{ 1, 2, 3, 4, 5, 6, 7 },
		{ 0, 2, 3, 4, 5, 6, 7 },
		{ 0, 1, 3, 4, 5, 6, 7 },
		{ 0, 1, 2, 4, 5, 6, 7 },
		{ 0, 1, 2, 3, 5, 6, 7 },
		{ 0, 1, 2, 3, 4, 6, 7 },
		{ 0, 1, 2, 3, 4, 5, 7 },
		{ 0, 1, 2, 3, 4, 5, 6 }
	};
	const int num_edges = 9;
	// indexing[vertex] => { edges to check where the function is zero (local indices) }
	int edges[][num_edges] = {
		{ 1, 2, 5, 6, 7, 8, 9, 10, 11 },
		{ 2, 3, 4, 6, 7, 8, 9, 10, 11 },
		{ 0, 3, 4, 5, 7, 8, 9, 10, 11 },
		{ 0, 1, 4, 5, 6, 8, 9, 10, 11 },
		{ 0, 1, 2, 3, 5, 6, 7,  9, 10 },
		{ 0, 1, 2, 3, 4, 6, 7, 10, 11 },
		{ 0, 1, 2, 3, 4, 5, 7,  8, 11 },
		{ 0, 1, 2, 3, 4, 5, 6,  8,  9 },
	};
	const int num_faces = 3;
	// indexing[vertex] => { faces to check where the function is zero (local indices) }
	int faces[][num_faces] = {
		{ 5, 1, 3 },
		{ 5, 3, 0 },
		{ 5, 0, 2 },
		{ 5, 2, 1 },
		{ 4, 1, 3 },
		{ 3, 0, 4 },
		{ 0, 2, 4 },
		{ 1, 4, 2 }
	};

	Quad3D *quad = get_quadrature(MODE);
	for (int vtx = 0; vtx < Hex::NUM_VERTICES; vtx++) {
		int fn_idx = shapeset->get_vertex_index(vtx);
		printf("  * Vertex fn #%d (%d) ", vtx, fn_idx);

		// vertices
		const Point3D *vtx_pt = REF_DOMAIN::get_vertices();
		int *idx = vertices[vtx];
		for (int i = 0; i < num_vertices; i++) {
			if (shapeset->get_fn_value(fn_idx, vtx_pt[idx[i]].x, vtx_pt[idx[i]].y, vtx_pt[idx[i]].z, 0) > EPS) {
				warning("Vertex fn #%d (%d) is not zero at (% lf, %lf, %lf), vertex #%d.", vtx, fn_idx, vtx_pt[idx[i]].x, vtx_pt[idx[i]].y, vtx_pt[idx[i]].z, idx[i]);
				return false;
			}
		}

		// edges
		for (int i = 0; i < num_edges; i++) {
			order1_t max_order = quad->get_edge_max_order(edges[vtx][i]);
			int np = quad->get_edge_num_points(edges[vtx][i], max_order);
			QuadPt3D *pts = quad->get_edge_points(edges[vtx][i], max_order);

			double vals[np];
			shapeset->get_fn_values(fn_idx, np, pts, 0, vals);
			for (int j = 0; j < np; j++) {
				if (vals[j] > EPS) {
					warning("Vertex fn #%d (%d) is not zero at (% lf, %lf, %lf), edge %d.", vtx, fn_idx, pts[j].x, pts[j].y, pts[j].z, edges[vtx][i]);
					return false;
				}
			}
		}

		// faces
		for (int i = 0; i < num_faces; i++) {
			order2_t max_order = quad->get_face_max_order(faces[vtx][i]);
			int np = quad->get_face_num_points(faces[vtx][i], max_order);
			QuadPt3D *pts = quad->get_face_points(faces[vtx][i], max_order);
			double vals[np];
			shapeset->get_fn_values(fn_idx, np, pts, 0, vals);
			for (int j = 0; j < np; j++) {
				if (vals[j] > EPS) {
					warning("Vertex fn #%d (%d) is not zero at (% lf, %lf, %lf), face %d.", vtx, fn_idx, pts[j].x, pts[j].y, pts[j].z, faces[vtx][i]);
					return false;
				}
			}
		}

		printf("... ok\n");
	}

	return true;
}
示例#18
0
bool test_cont_values_of_edge_fns(Mesh *mesh, unsigned int fid, int pos0, int pos1, Shapeset *shapeset) {
	_F_
	Facet *facet = mesh->facets[fid];
	Quad3D *quad = get_quadrature(MODE);

	Element *h[2] = {
		mesh->elements[facet->left],
		mesh->elements[facet->right]
	};

	// local number of edges on the face
	const int *face_edges[] = {
		h[0]->get_face_edges(facet->left_face_num),
		h[1]->get_face_edges(facet->right_face_num)
	};

	// orientations of edges on the face
	int edge_ori[2][4];
	for (int i = 0; i < 4; i++) {
		edge_ori[0][i] = h[0]->get_edge_orientation(face_edges[0][i]);
		edge_ori[1][i] = h[1]->get_edge_orientation(face_edges[1][i]);
	}

	RefMap rm(mesh);
	Pts epts[2];

	// get coordinates of the point in the middle of an edge on the face
	// it is used to find matching edges
	int enp = Quad::NUM_EDGES;
	for (int i = 0; i < 2; i++) {
		QuadPt3D *pt = new QuadPt3D[Quad::NUM_EDGES];
		for (int j = 0; j < enp; j++) {
			const int *edge_vtx = RefHex::get_edge_vertices(face_edges[i][j]);
			QuadPt3D *rd_vtx_pt = quad->get_vertex_points();
			pt[j].x = (rd_vtx_pt[edge_vtx[0]].x + rd_vtx_pt[edge_vtx[1]].x) / 2.0;
			pt[j].y = (rd_vtx_pt[edge_vtx[0]].y + rd_vtx_pt[edge_vtx[1]].y) / 2.0;
			pt[j].z = (rd_vtx_pt[edge_vtx[0]].z + rd_vtx_pt[edge_vtx[1]].z) / 2.0;
		}

		rm.set_active_element(h[i]);

		epts[i].ref_pt = pt;
		epts[i].phys_x = rm.get_phys_x(enp, pt);
		epts[i].phys_y = rm.get_phys_y(enp, pt);
		epts[i].phys_z = rm.get_phys_z(enp, pt);

		// sort points by physical coordinates
		epts[i].sort = new int [enp];
		for (int j = 0; j < enp; j++)
			epts[i].sort[j] = j;
		sort_pts = epts + i;
		qsort(epts[i].sort, enp, sizeof(int), compare);
	}

	// we know which edge correspond to each other, since we sorted them by their phys. coordinates
	// we use it for comparing matching edge functions

	// obtain coordinates where edge functions are going to be evaluated
	Pts fpts[2];
	Ord2 face_ord = quad->get_face_max_order(facet->left_face_num);
	int np = quad->get_face_num_points(facet->left_face_num, face_ord);

	QuadPt3D *pt[2] = {
		quad->get_face_points(facet->left_face_num, face_ord),
		quad->get_face_points(facet->right_face_num, face_ord)
	};

	// transform the coorinates so we can compare them
	for (int i = 0; i < 2; i++) {
		rm.set_active_element(h[i]);

		fpts[i].ref_pt = pt[i];
		fpts[i].phys_x = rm.get_phys_x(np, pt[i]);
		fpts[i].phys_y = rm.get_phys_y(np, pt[i]);
		fpts[i].phys_z = rm.get_phys_z(np, pt[i]);

		// sort points by physical coordinates
		fpts[i].sort = new int [np];
		for (int j = 0; j < np; j++)
			fpts[i].sort[j] = j;
		sort_pts = fpts + i;
		qsort(fpts[i].sort, np, sizeof(int), compare);
	}

	// loop through edges
	for (int k = 0; k < Quad::NUM_EDGES; k++) {
		int i1 = epts[0].sort[k];
		int i2 = epts[1].sort[k];

		// loop through edge functions
		// get all face functions on the face
		Ord1 order(H3D_MAX_ELEMENT_ORDER);
		int *edge_fn[] = {
			shapeset->get_edge_indices(face_edges[0][i1], edge_ori[0][i1], order),
			shapeset->get_edge_indices(face_edges[1][i2], edge_ori[1][i2], order)
		};

		// loop through face functions
		int n_edge_fns = shapeset->get_num_edge_fns(order);
		for (int ifn = 0; ifn < n_edge_fns; ifn++) {
			// get values of edge functions
			double uval[np], vval[np];
			shapeset->get_fn_values(edge_fn[0][ifn], np, pt[0], 0, uval);
			shapeset->get_fn_values(edge_fn[1][ifn], np, pt[1], 0, vval);

			// compare their values
			for (int i = 0; i < np; i++) {
				int j1 = fpts[0].sort[i];
				int j2 = fpts[1].sort[i];

				if (fabs(uval[j1] - vval[j2]) > EPS) {
					printf("failed\n");
					warning("Edge fn not continuous @(% lf, % lf, % lf), diff = % e",
						fpts[0].ref_pt[j1].x, fpts[0].ref_pt[j1].y, fpts[0].ref_pt[j1].z,
						fabs(uval[j1] - vval[j2]));
					return false;
				}
			}
		}
	}

	// free memory
	for (int i = 0; i < 2; i++) {
		delete [] epts[i].ref_pt;
		delete [] epts[i].phys_x;
		delete [] epts[i].phys_y;
		delete [] epts[i].phys_z;
		delete [] epts[i].sort;

		delete [] fpts[i].phys_x;
		delete [] fpts[i].phys_y;
		delete [] fpts[i].phys_z;
		delete [] fpts[i].sort;
	}

	return true;
}
示例#19
0
bool test_cont_values_of_face_fns(Mesh *mesh, unsigned int fid, int pos0, int pos1, Shapeset *shapeset) {
	_F_
	Quad3D *quad = get_quadrature(MODE);
	Facet *facet = mesh->facets[fid];

	Element *h[2] = {
		mesh->elements[facet->left],
		mesh->elements[facet->right]
	};

	int face_ori[2] = {
		h[0]->get_face_orientation(facet->left_face_num),
		h[1]->get_face_orientation(facet->right_face_num)
	};

	RefMap rm(mesh);

	// get points where the functions are going to be evaluated
	Pts fpts[2];
	Ord2 face_ord = quad->get_face_max_order(facet->left_face_num);
	int np = quad->get_face_num_points(facet->left_face_num, face_ord);

	QuadPt3D *pt[2] = {
		quad->get_face_points(facet->left_face_num, face_ord),
		quad->get_face_points(facet->right_face_num, face_ord)
	};

	// transform points and sort them
	for (int i = 0; i < 2; i++) {
		rm.set_active_element(h[i]);

		fpts[i].ref_pt = pt[i];
		fpts[i].phys_x = rm.get_phys_x(np, pt[i]);
		fpts[i].phys_y = rm.get_phys_y(np, pt[i]);
		fpts[i].phys_z = rm.get_phys_z(np, pt[i]);

		// sort points by physical coordinates
		fpts[i].sort = new int [np];
		for (int j = 0; j < np; j++)
			fpts[i].sort[j] = j;
		sort_pts = fpts + i;
		qsort(fpts[i].sort, np, sizeof(int), compare);
	}

	// get all face functions on the face
	Ord2 order(H3D_MAX_ELEMENT_ORDER, H3D_MAX_ELEMENT_ORDER);
	int *face_fn[] = {
		shapeset->get_face_indices(facet->left_face_num, face_ori[0], order),
		shapeset->get_face_indices(facet->right_face_num, face_ori[1], order)
	};

	// loop through face functions
	int n_face_fns = shapeset->get_num_face_fns(order);
	for (int ifn = 0; ifn < n_face_fns; ifn++) {
		// evaluate functions
		double uval[np], vval[np];
		shapeset->get_fn_values(face_fn[0][ifn], np, pt[0], 0, uval);
		shapeset->get_fn_values(face_fn[1][ifn], np, pt[1], 0, vval);

		// compare
		for (int i = 0; i < np; i++) {
			int j1 = fpts[0].sort[i];
			int j2 = fpts[1].sort[i];

			if (fabs(uval[j1] - vval[j2]) > EPS) {
				printf("failed\n");
				warning("Face fn not continuous @(% lf, % lf, % lf), diff = % e",
					fpts[0].ref_pt[j1].x, fpts[0].ref_pt[j1].y, fpts[0].ref_pt[j1].z,
					fabs(uval[j1] - vval[j2]));
				return false;
			}
		}
	}

	for (int i = 0; i < 2; i++) {
		delete [] fpts[i].phys_x;
		delete [] fpts[i].phys_y;
		delete [] fpts[i].phys_z;
		delete [] fpts[i].sort;
	}

	return true;
}