Пример #1
0
VN * IR_GVN::register_qua_vn(IR_TYPE irt, VN const* v0, VN const* v1,
							 VN const* v2, VN const* v3)
{
	IS_TRUE0(v0 && v1 && v2 && v3);
	IS_TRUE0(is_quad(irt));
	VEC4 * v0_vec = (VEC4*)m_irt_vec.get(irt);
	if (v0_vec == NULL) {
		v0_vec = new VEC4();
		m_vec_lst.append_tail((VEC1*)v0_vec);
		m_irt_vec.set(irt, (VEC2*)v0_vec);
	}

	VEC3 * v1_vec = v0_vec->get(VN_id(v0));
	if (v1_vec == NULL) {
		v1_vec = new VEC3();
		m_vec_lst.append_tail((VEC1*)v1_vec);
		v0_vec->set(VN_id(v0), v1_vec);
	}

	VEC2 * v2_vec = v1_vec->get(VN_id(v1));
	if (v2_vec == NULL) {
		v2_vec = new VEC2();
		m_vec_lst.append_tail((VEC1*)v2_vec);
		v1_vec->set(VN_id(v1), v2_vec);
	}

	VEC1 * v3_vec = v2_vec->get(VN_id(v2));
	if (v3_vec == NULL) {
		v3_vec = new VEC1();
		m_vec_lst.append_tail(v3_vec);
		m_vnvec_lst.append_tail(v3_vec);
		v2_vec->set(VN_id(v2), v3_vec);
	}

	VN * res = v3_vec->get(VN_id(v3));
	if (res == NULL) {
		res = new_vn();
		VN_type(res) = VN_OP;
		VN_op(res) = irt;
		v3_vec->set(VN_id(v3), res);
	}
	return res;
}
Пример #2
0
bool IR_GVN::verify()
{
	for (INT i = 0; i <= m_irt_vec.get_last_idx(); i++) {
		if (is_bin_irt((IR_TYPE)i) || i == IR_LDA) {
			SVECTOR<SVECTOR<VN*>*> * v0_vec = m_irt_vec.get(i);
			if (v0_vec == NULL) { continue; }
			for (INT j = 0; j <= v0_vec->get_last_idx(); j++) {
				SVECTOR<VN*> * v1_vec = v0_vec->get(j);
				if (v1_vec == NULL) { continue; }
				//v1_vec->clean();
			}
		} else if (i == IR_BNOT || i == IR_LNOT ||
				   i == IR_NEG || i == IR_CVT) {
			SVECTOR<VN*> * v0_vec = (SVECTOR<VN*>*)m_irt_vec.get(i);
			if (v0_vec == NULL) { continue; }
			//v0_vec->clean();
		} else if (is_triple((IR_TYPE)i)) {
			VEC3 * v0_vec = (VEC3*)m_irt_vec.get(i);
			if (v0_vec == NULL) { continue; }
			for (INT j = 0; j <= v0_vec->get_last_idx(); j++) {
				VEC2 * v1_vec = v0_vec->get(j);
				if (v1_vec == NULL) { continue; }
				for (INT k = 0; k <= v1_vec->get_last_idx(); k++) {
					VEC1 * v2_vec = v1_vec->get(k);
					if (v1_vec == NULL) { continue; }
					//v2_vec->clean();
				}
			}
		} else if (is_quad((IR_TYPE)i)) {
			//
		} else {
			IS_TRUE0(m_irt_vec.get(i) == NULL);
		}
	}
	return true;
}
Пример #3
0
    void Element::calc_area(bool precise_for_curvature)
    {
      // First some basic arithmetics.
      double ax, ay, bx, by;
      ax = vn[1]->x - vn[0]->x;
      ay = vn[1]->y - vn[0]->y;
      bx = vn[2]->x - vn[0]->x;
      by = vn[2]->y - vn[0]->y;

      this->area = 0.5*(ax*by - ay*bx);
      if (is_quad())
      {
        ax = bx; ay = by;
        bx = vn[3]->x - vn[0]->x;
        by = vn[3]->y - vn[0]->y;

        this->area = area + 0.5*(ax*by - ay*bx);
      }

      // Either the basic approximation is fine.
      if (!this->is_curved() || !precise_for_curvature)
        return;
      // Or we want to capture the curvature precisely.
      else
      {
        // Utility data.
        RefMap refmap_curv;
        RefMap refmap_straight;
        double3* tan;

        double x_center, y_center;
        this->get_center(x_center, y_center);

        for (unsigned char isurf = 0; isurf < this->nvert; isurf++)
        {
          // 0 - prepare data structures.
          int eo = g_quad_2d_std.get_edge_points(isurf, this->get_mode() == HERMES_MODE_TRIANGLE ? g_max_tri : g_max_quad, this->get_mode());
          unsigned char np = g_quad_2d_std.get_num_points(eo, this->get_mode());
          double* x_curv = new double[np];
          double* y_curv = new double[np];
          double* x_straight = new double[np];
          double* y_straight = new double[np];

          // 1 - get the x,y coordinates for the curved element.
          refmap_curv.set_active_element(this);
          GeomSurf<double> geometry;
          init_geom_surf_allocated(geometry, &refmap_curv, isurf, this->en[isurf]->marker, eo, tan);
          memcpy(x_curv, geometry.x, np*sizeof(double));
          memcpy(y_curv, geometry.y, np*sizeof(double));

          // 2. - act if there was no curvature
          CurvMap* cm_temp = this->cm;
          this->cm = nullptr;
          refmap_straight.set_active_element(this);
          init_geom_surf_allocated(geometry, &refmap_straight, isurf, this->en[isurf]->marker, eo, tan);
          memcpy(x_straight, geometry.x, np*sizeof(double));
          memcpy(y_straight, geometry.y, np*sizeof(double));

          // 3. - compare the two, get the updated area.
          double previous_distance;
          for (int i = 0; i < np; i++)
          {
            // Distance between the curved and straight edges.
            double distance_i = std::sqrt(std::pow(x_straight[i] - x_curv[i], 2.0) + std::pow(y_straight[i] - y_curv[i], 2.0));

            // Add to- or Subtract from- the area (depends on the curvature and we shall decide based on distance from the element center).
            double distance_from_center_curved = std::pow(x_center - x_curv[i], 2.0) + std::pow(y_center - y_curv[i], 2.0);
            double distance_from_center_straight = std::pow(x_center - x_straight[i], 2.0) + std::pow(y_center - y_straight[i], 2.0);
            bool add = distance_from_center_curved > distance_from_center_straight;

            // Calculate now the area delta.
            // It depends on the integration point number etc.
            double area_delta;
            if (i == 0)
            {
              double distance_along_edge = std::sqrt(std::pow(x_straight[i] - this->vn[isurf]->x, 2.0) + std::pow(y_straight[i] - this->vn[isurf]->y, 2.0));
              area_delta = distance_i * distance_along_edge * 0.5;
            }
            if (i > 0 && i < np - 1)
            {
              double distance_along_edge = std::sqrt(std::pow(x_straight[i] - x_straight[i - 1], 2.0) + std::pow(y_straight[i] - y_straight[i - 1], 2.0));
              area_delta = 0.5*(distance_i + previous_distance) * distance_along_edge;
            }
            if (i == np - 1)
            {
              double distance_along_edge = std::sqrt(std::pow(x_straight[i] - this->vn[(isurf + 1) % this->nvert]->x, 2.0) + std::pow(y_straight[i] - this->vn[(isurf + 1) % this->nvert]->y, 2.0));
              area_delta = distance_i * distance_along_edge * 0.5;
            }

            if (add)
              area += area_delta;
            else
              area -= area_delta;

            previous_distance = distance_i;
          }

          // 4. - re-add the curvature.
          this->cm = cm_temp;

          // clean up
          delete[] x_curv;
          delete[] y_curv;
          delete[] x_straight;
          delete[] y_straight;
        }
      }
    }