Beispiel #1
0
void solve(int u) {
	rt = 0;
	ff[0] = size;
	find_center(u, -1);
	u = rt;
	tot = sum = 0;
	get_order(u, -1);
	for(int i = 0; i <= tot; ++i)
		for(int j = 0; j <= sum; ++j)
			f[i][j] = 0;
	f[0][0] = 1;
	sum = 0;
	for(int i = 0; i < tot; ++i) {
		DB pr = (DB)p[seq[i]] / 100;
		for(int j = 0; j <= sum; ++j) {
			if(i)
				f[nxt[i]][j] += f[i][j];
			f[i + 1][j] += f[i][j] * (1 - pr);
			f[i + 1][j + w[seq[i]]] += f[i][j] * pr;
		}
		sum += w[seq[i]];
	}
	for(int i = 0; i <= sum; ++i)
		s[i] += f[tot][i];
	vis[u] = 1;
	for(std::vector<int>::iterator it = e[u].begin(); it != e[u].end(); ++it) {
		int v = *it;
		if(!vis[v]) {
			size = sz[v];
			solve(v);
		}
	}
}
// 当数据量太大的时候,递归会导致栈溢出,最好用非递归的形式实现快排
void quick_sort(int a[], int left,  int right)
{
	if( left < right)
	{
		int center = find_center(a, left, right);
		quick_sort(a, left, center);
		quick_sort(a, center+1, right);
		
	}
}
Beispiel #3
0
void find_center(int u, int fa) {
	sz[u] = 1;
	ff[u] = 0;
	for(std::vector<int>::iterator it = e[u].begin(); it != e[u].end(); ++it) {
		int v = *it;
		if(!vis[v] && v != fa) {
			find_center(v, u);
			sz[u] += sz[v];
			ff[u] = std::max(ff[u], sz[v]);
		}
	}
	ff[u] = std::max(ff[u], size - sz[u]);
	if(ff[u] < ff[rt])
		rt = u;
}
Beispiel #4
0
long double minimum_enclosing_circle(polygon_t &convex_hull)
{
    if (convex_hull.size() <= 1) return 0;
    if (convex_hull.size() == 2) return distance_square(convex_hull[0], convex_hull[1]) / 4.0;

    point_t s_a = convex_hull[0];
    point_t s_b = convex_hull[1];

    while (1) {
        long double alpha = 100;
        point_t v;
        for (polygon_t::iterator p = convex_hull.begin(); p != convex_hull.end(); p++) {
            if (*p == s_a || *p == s_b) continue;
            long double a = angle(*p, s_a, s_b);
            if (a < alpha) {
                alpha = a;
                v = *p;
            }
        }

        if (alpha >= M_PI / 2) return distance_square(s_a, s_b) / 4.0;

        // printf("s_a:(%ld, %ld) s_b:(%ld, %ld) v:(%ld, %ld)\n", s_a.first, s_a.second, s_b.first, s_b.second, v.first, v.second);
        // printf("angle v-s_a-s_b: %Lf\n", angle(s_a, v, s_b));

        if (angle(s_a, v, s_b) >= M_PI / 2) {
            s_a = v;
            continue;
        }

        // printf("angle v-s_b-s_a: %Lf\n", angle(s_b, v, s_a));
        if (angle(s_b, v, s_a) >= M_PI / 2) {
            s_b = v;
            continue;
        }

        /* v, s_a, s_b */
        fpoint_t center = find_center(v, s_a, s_b);
        // printf("center: %Lf, %Lf\n", center.first, center.second);
        // printf("%Lf = %Lf, %Lf\n", distance_square(center, v), distance_square(center, s_a), distance_square(center, s_b));
        return distance_square(center, v);
    }
}
Beispiel #5
0
bool featureextraction::findMarker02(cv::Mat &img, std::vector<cv::Point> &points, bool constraintTime, double maxprocessingtime){
    std::chrono::high_resolution_clock::time_point start;
    start = std::chrono::high_resolution_clock::now();

    cv::Mat imghsv = img.clone();
    cv::Mat white;
    cv::cvtColor(img, imghsv, CV_BGR2HSV);
    cv::inRange(imghsv, cv::Scalar(0, 0, 127), cv::Scalar(180,50,255), white);

    std::vector<std::vector<cv::Point> > contours;
    std::vector<std::vector<cv::Point> > good_contours;

    points.clear();

    std::vector<cv::Point> center = find_blobs(white, contours, good_contours);

    if(constraintTime){
        std::chrono::high_resolution_clock::time_point now;
        now = std::chrono::high_resolution_clock::now();
        double runTime = std::chrono::duration_cast<std::chrono::duration<double>>(now - start).count();
        if(runTime > maxprocessingtime){
            return false;
        }
    }

    cv::Point midpoint = find_center(img, center, good_contours);

    if(midpoint.x == 0 && midpoint.y == 0){
        return false;
    } else {
        midpoint.x -= img.cols / 2;
        midpoint.y = img.rows / 2 - midpoint.y;
        points.push_back(midpoint);
        return true;
    }
}
Beispiel #6
0
// Uses a variant of the bounded harmonic mean approximation to determine the evidence.
// Essentially, the regulator chosen is an ellipsoid with radius nsigma standard deviations
// along each principal axis. The regulator is then 1/V inside the ellipsoid and 0 without,
// where V is the volume of the ellipsoid. In this form, the harmonic mean approximation
// has finite variance. See Gelfand & Dey (1994) and Robert & Wraith (2009) for details.
double TChain::get_ln_Z_harmonic(bool use_peak, double nsigma_max, double nsigma_peak, double chain_frac) const {
	// Get the covariance and determinant of the chain
	gsl_matrix* Sigma = gsl_matrix_alloc(N, N);
	gsl_matrix* invSigma = gsl_matrix_alloc(N, N);
	double detSigma;
	stats.get_cov_matrix(Sigma, invSigma, &detSigma);
	
	// Determine the center of the prior volume to use
	double* mu = new double[N];
	if(use_peak) {	// Use the peak density as the center
		find_center(mu, Sigma, invSigma, &detSigma, nsigma_peak, 5);
		//density_peak(mu, nsigma_peak);
	} else {	// Get the mean from the stats class
		for(unsigned int i=0; i<N; i++) { mu[i] = stats.mean(i); }
	}
	
	// Sort elements in chain by distance from center, filtering out values of L which are not finite
	std::vector<TChainSort> sorted_indices;
	sorted_indices.reserve(length);
	unsigned int filt_length = 0;
	for(unsigned int i=0; i<length; i++) {
		if(!(isnan(L[i]) || is_inf_replacement(L[i]))) {
			TChainSort tmp_el;
			tmp_el.index = i;
			tmp_el.dist2 = metric_dist2(invSigma, get_element(i), mu, N);
			sorted_indices.push_back(tmp_el);
			filt_length++;
		}
	}
	unsigned int npoints = (unsigned int)(chain_frac * (double)filt_length);
	std::partial_sort(sorted_indices.begin(), sorted_indices.begin() + npoints, sorted_indices.end());
	
	// Determine <1/L> inside the prior volume
	double sum_invL = 0.;
	double tmp_invL;
	double nsigma = sqrt(sorted_indices[npoints-1].dist2);
	unsigned int tmp_index = sorted_indices[0].index;;
	double L_0 = L[tmp_index];
	//std::cout << "index_0 = " << sorted_indices[0].index << std::endl;
	for(unsigned int i=0; i<npoints; i++) {
		if(sorted_indices[i].dist2 > nsigma_max * nsigma_max) {
			nsigma = nsigma_max;
			break;
		}
		tmp_index = sorted_indices[i].index;
		tmp_invL = w[tmp_index] / exp(L[tmp_index] - L_0);
		//std::cout << w[tmp_index] << ", " << L[tmp_index] << std::endl;
		//if(isnan(tmp_invL)) {
		//	std::cout << "\t\tL, L_0 = " << L[tmp_index] << ", " << L_0 << std::endl;
		//}
		if((tmp_invL + sum_invL > 1.e100) && (i != 0)) {
			nsigma = sqrt(sorted_indices[i-1].dist2);
			break;
		}
		sum_invL += tmp_invL;
	}
	
	// Determine the volume normalization (the prior volume)
	double V = sqrt(detSigma) * 2. * pow(SQRTPI * nsigma, (double)N) / (double)(N) / gsl_sf_gamma((double)(N)/2.);
	
	// Return an estimate of ln(Z)
	double lnZ = log(V) - log(sum_invL) + log(total_weight) + L_0;
	
	if(isnan(lnZ)) {
		std::cout << std::endl;
		std::cout << "NaN Error! lnZ = " << lnZ << std::endl;
		std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl;
		std::cout << "\tV = " << V << std::endl;
		std::cout << "\ttotal_weight = " << total_weight << std::endl;
		std::cout << std::endl;
	} else if(is_inf_replacement(lnZ)) {
		std::cout << std::endl;
		std::cout << "inf Error! lnZ = " << lnZ << std::endl;
		std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl;
		std::cout << "\tV = " << V << std::endl;
		std::cout << "\ttotal_weight = " << total_weight << std::endl;
		std::cout << "\tnsigma = " << nsigma << std::endl;
		std::cout << "\tIndex\tDist^2:" << std::endl;
		for(unsigned int i=0; i<10; i++) {
			std::cout << sorted_indices[i].index << "\t\t" << sorted_indices[i].dist2 << std::endl;
			std::cout << "  ";
			const double *tmp_x = get_element(sorted_indices[i].index);
			for(unsigned int k=0; k<N; k++) { std::cout << " " << tmp_x[k]; }
			std::cout << std::endl;
		}
		std::cout << "mu =";
		for(unsigned int i=0; i<N; i++) { std::cout << " " << mu[i]; }
		std::cout << std::endl;
	}
	
	// Cleanup
	gsl_matrix_free(Sigma);
	gsl_matrix_free(invSigma);
	delete[] mu;
	
	return lnZ;
}
//
// Add ghost cells
//
void MeshAddGhostCells(const string& GridType, cart2d& cart2dinfo,
		       int& numpts, int& numtri, int& numghost, int& num_ext_node,
		       point*& p, triangle*& t, double*& area, double*& cdual, 
		       int*& ghost_link, int*& proper_ghostcell,
		       int*& ext_node_link,
		       double (*SignedDistance)(point))
{
  int i,j;
  int k = 0;
  int mfound = 0;
  int jstore[4];
  double x,y;
  int tmp[4];
  point ptmp;
  point A,B,C,nvec,Anew,v12,v23,v31;
  double BCnorm,nvec_norm;
  int tmps,temp,kcheck;
  point alpha,beta;
  double alpha_norm,beta_norm,theta_alpha,theta_beta;
  int jopp;
  
  point pnew[2*numpts];
  triangle tnew[2*numtri];
  double area_new[2*numtri];
  double cdual_new[2*numpts];
  int ghost_link_new[2*numtri];
  int numghost_new = 0;
  int numpts_new = numpts;
  int numtri_new = numtri;
  int ext_new[2*numtri];
  int num_ext = 0;

  // for periodic boundary conditions
  int* centers_index_tmp = new int[2*numtri];
  double* centers_xy_tmp = new double[2*numtri];
  int num_centers = 0;
  const double olx = 1.0/(cart2dinfo.xhigh-cart2dinfo.xlow);
  const double oly = 1.0/(cart2dinfo.yhigh-cart2dinfo.ylow);

  // Compute the minimal distance parameter hmin
  double min_parea = 1.0e10;
  for (i=0; i<numtri; i++)
    {
      if (min_parea > area[i])
	{ min_parea = area[i]; }
    }
  double hmin = sqrt(2.0*min_parea)/5.0e0;

  // Store old t,area,p,cdual in new versions of each
  for (i=0; i<numtri; i++)
    {
      tnew[i].n1 = t[i].n1;
      tnew[i].n2 = t[i].n2;
      tnew[i].n3 = t[i].n3;
      
      area_new[i] = area[i];
    }

  for (i=0; i<numpts; i++)
    {
      pnew[i].x = p[i].x;
      pnew[i].y = p[i].y;

      cdual_new[i] = cdual[i];
    }

  // Loop over every element in order to determine
  // if a ghost cell should be created
  for (i=0; i<numtri; i++)
    {
      mfound = 0;
      jstore[1] = 0;
      jstore[2] = 0;
      jstore[3] = 0;

      // Look at ith element
      tmp[1] = t[i].n1;
      tmp[2] = t[i].n2;
      tmp[3] = t[i].n3;

      // Check how many nodes of ith element lie on the boundary (either 0, 1, 2, or 3)
      // If there are 0 or 1 nodes on the bnd, then do nothing and proceed to next element
      for (j=1; j<=3; j++)
	{
	  ptmp.x = p[tmp[j]].x;
	  ptmp.y = p[tmp[j]].y;
	  
	  if (fabs(SignedDistance(ptmp))<=hmin)
	    {
	      mfound = mfound + 1;
	      jstore[mfound] = j;
	    }
	  else
	    {
	      A.x = ptmp.x;
	      A.y = ptmp.y;
	      jopp = tmp[j];
	    }
	}    

      // Exactly three nodes of a triangle are on the boundary
      // NOTE: 3 nodes on boundary <==> exactly two edges are boundary edges
      //   (assuming the mesh has more than 1 element and these elements are connected)
      if (mfound==3)
	{
	  kcheck = 0;

	  // check if edge 12 is on the boundary
	  ptmp.x = 0.5*( p[tmp[1]].x + p[tmp[2]].x );
	  ptmp.y = 0.5*( p[tmp[1]].y + p[tmp[2]].y );

	  if (fabs(SignedDistance(ptmp))<=hmin)
	    {
	      kcheck=kcheck+1;
	      
	      jstore[1] = 1;
	      jstore[2] = 2;
	      jstore[3] = 3;

	      A.x = p[tmp[jstore[3]]].x;
	      A.y = p[tmp[jstore[3]]].y;
	      
	      B.x = p[tmp[jstore[1]]].x;
	      B.y = p[tmp[jstore[1]]].y;
	      
	      C.x = p[tmp[jstore[2]]].x;
	      C.y = p[tmp[jstore[2]]].y;

	      Anew.x = B.x + C.x - A.x;
	      Anew.y = B.y + C.y - A.y;
  
	      // Add new node and corresponding new element
	      numtri_new = numtri_new+1;
	      numpts_new = numpts_new+1;
	      
	      pnew[numpts_new-1].x = Anew.x;
	      pnew[numpts_new-1].y = Anew.y;
	      
	      tnew[numtri_new-1].n1 = tmp[jstore[1]];
	      tnew[numtri_new-1].n2 = tmp[jstore[2]];
	      tnew[numtri_new-1].n3 = numpts_new-1;

	      // New node link to old node
	      num_ext = num_ext+1;
	      ext_new[num_ext-1] = tmp[jstore[3]];
	      
	      // Add ghost index;
	      numghost_new = numghost_new+1;
	      ghost_link_new[numghost_new-1] = i;

	      // Center information - to be used for periodic BCs
	      num_centers = num_centers + 1;
	      centers_index_tmp[num_centers-1] = i;
	      double x1 = A.x;
	      double x2 = B.x;
	      double x3 = C.x;
	      double y1 = A.y;
	      double y2 = B.y;
	      double y3 = C.y;
	      centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow)
		+ 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow);	      
	      
	      // Compute signed element area, change orientation if necessary
	      v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x;
	      v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y;
	      v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x;
	      v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y;
	      v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x;
	      v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y;
	      
	      area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * 
					   (pnew[tnew[numtri_new-1].n2].y
					    -pnew[tnew[numtri_new-1].n3].y) + 
					   pnew[tnew[numtri_new-1].n2].x * 
					   (pnew[tnew[numtri_new-1].n3].y
					    -pnew[tnew[numtri_new-1].n1].y) +
					   pnew[tnew[numtri_new-1].n3].x * 
					   (pnew[tnew[numtri_new-1].n1].y
					    -pnew[tnew[numtri_new-1].n2].y));

	      if (area_new[numtri_new-1] < 0.0)
		{
		  temp = tnew[numtri_new-1].n2;
		  tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3;
		  tnew[numtri_new-1].n3 = temp;
		  area_new[numtri_new-1] = fabs(area_new[numtri_new-1]);
		}

	      // Add element area to the appropriate dual cell area
	      cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0);
	    }

	  // check if edge 13 is on the boundary
	  ptmp.x = 0.5*( p[tmp[1]].x + p[tmp[3]].x );
	  ptmp.y = 0.5*( p[tmp[1]].y + p[tmp[3]].y );

	  if (fabs(SignedDistance(ptmp))<=hmin)
	    {
	      kcheck=kcheck+1;
	      
	      jstore[1] = 3;
	      jstore[2] = 1;
	      jstore[3] = 2;

	      A.x = p[tmp[jstore[3]]].x;
	      A.y = p[tmp[jstore[3]]].y;
	      
	      B.x = p[tmp[jstore[1]]].x;
	      B.y = p[tmp[jstore[1]]].y;
	      
	      C.x = p[tmp[jstore[2]]].x;
	      C.y = p[tmp[jstore[2]]].y;

	      Anew.x = B.x + C.x - A.x;
	      Anew.y = B.y + C.y - A.y;
  
	      // Add new node and corresponding new element
	      numtri_new = numtri_new+1;
	      numpts_new = numpts_new+1;
	      
	      pnew[numpts_new-1].x = Anew.x;
	      pnew[numpts_new-1].y = Anew.y;
	      
	      tnew[numtri_new-1].n1 = tmp[jstore[1]];
	      tnew[numtri_new-1].n2 = tmp[jstore[2]];
	      tnew[numtri_new-1].n3 = numpts_new-1;

	      // New node link to old node
	      num_ext = num_ext+1;
	      ext_new[num_ext-1] = tmp[jstore[3]];
	      
	      // Add ghost index;
	      numghost_new = numghost_new+1;
	      ghost_link_new[numghost_new-1] = i;

	      // Center information - to be used for periodic BCs
	      num_centers = num_centers + 1;
	      centers_index_tmp[num_centers-1] = i;
	      double x1 = A.x;
	      double x2 = B.x;
	      double x3 = C.x;
	      double y1 = A.y;
	      double y2 = B.y;
	      double y3 = C.y;
	      centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow)
		+ 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow);
	      
	      // Compute signed element area, change orientation if necessary
	      v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x;
	      v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y;
	      v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x;
	      v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y;
	      v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x;
	      v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y;
	      
	      area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * 
					   (pnew[tnew[numtri_new-1].n2].y
					    -pnew[tnew[numtri_new-1].n3].y) + 
					   pnew[tnew[numtri_new-1].n2].x * 
					   (pnew[tnew[numtri_new-1].n3].y
					    -pnew[tnew[numtri_new-1].n1].y) +
					   pnew[tnew[numtri_new-1].n3].x * 
					   (pnew[tnew[numtri_new-1].n1].y
					    -pnew[tnew[numtri_new-1].n2].y));

	      if (area_new[numtri_new-1] < 0.0)
		{
		  temp = tnew[numtri_new-1].n2;
		  tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3;
		  tnew[numtri_new-1].n3 = temp;
		  area_new[numtri_new-1] = fabs(area_new[numtri_new-1]);
		}

	      // Add element area to the appropriate dual cell area
	      cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0);
	    }

	  // check if edge 23 is on the boundary
	  ptmp.x = 0.5*( p[tmp[2]].x + p[tmp[3]].x );
	  ptmp.y = 0.5*( p[tmp[2]].y + p[tmp[3]].y );

	  if (fabs(SignedDistance(ptmp))<=hmin)
	    {
	      kcheck=kcheck+1;

	      jstore[1] = 2;
	      jstore[2] = 3;
	      jstore[3] = 1;

	      A.x = p[tmp[jstore[3]]].x;
	      A.y = p[tmp[jstore[3]]].y;
	      
	      B.x = p[tmp[jstore[1]]].x;
	      B.y = p[tmp[jstore[1]]].y;
	      
	      C.x = p[tmp[jstore[2]]].x;
	      C.y = p[tmp[jstore[2]]].y;

	      Anew.x = B.x + C.x - A.x;
	      Anew.y = B.y + C.y - A.y;
  
	      // Add new node and corresponding new element
	      numtri_new = numtri_new+1;
	      numpts_new = numpts_new+1;
	      
	      pnew[numpts_new-1].x = Anew.x;
	      pnew[numpts_new-1].y = Anew.y;
	      
	      tnew[numtri_new-1].n1 = tmp[jstore[1]];
	      tnew[numtri_new-1].n2 = tmp[jstore[2]];
	      tnew[numtri_new-1].n3 = numpts_new-1;

	      // New node link to old node
	      num_ext = num_ext+1;
	      ext_new[num_ext-1] = tmp[jstore[3]];
	      
	      // Add ghost index;
	      numghost_new = numghost_new+1;
	      ghost_link_new[numghost_new-1] = i;

	      // Center information - to be used for periodic BCs
	      num_centers = num_centers + 1;
	      centers_index_tmp[num_centers-1] = i;
	      double x1 = A.x;
	      double x2 = B.x;
	      double x3 = C.x;
	      double y1 = A.y;
	      double y2 = B.y;
	      double y3 = C.y;
	      centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow)
		+ 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow);
	      
	      // Compute signed element area, change orientation if necessary
	      v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x;
	      v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y;
	      v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x;
	      v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y;
	      v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x;
	      v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y;
	      
	      area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * 
					   (pnew[tnew[numtri_new-1].n2].y
					    -pnew[tnew[numtri_new-1].n3].y) + 
					   pnew[tnew[numtri_new-1].n2].x * 
					   (pnew[tnew[numtri_new-1].n3].y
					    -pnew[tnew[numtri_new-1].n1].y) +
					   pnew[tnew[numtri_new-1].n3].x * 
					   (pnew[tnew[numtri_new-1].n1].y
					    -pnew[tnew[numtri_new-1].n2].y));

	      if (area_new[numtri_new-1] < 0.0)
		{
		  temp = tnew[numtri_new-1].n2;
		  tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3;
		  tnew[numtri_new-1].n3 = temp;
		  area_new[numtri_new-1] = fabs(area_new[numtri_new-1]);
		}

	      // Add element area to the appropriate dual cell area
	      cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0);
	    }

	  if (kcheck!=2)
	    {
	      cout << endl;
	      cout << " ERROR in MeshAddGhostCells.cpp: " << endl; 
	      cout << "       Found a triangle with 3 nodes on the boundary." << endl;
	      cout << "       This triangle should have exactly 2 edges on the boundary," << endl;
	      cout << "         but in fact it has " << kcheck << endl;
	      cout << endl;
	      exit(1);
	    }
	}
      // Exactly two nodes of a triangle are on the boundary
      // NOTE: 2 nodes on boundary  <==> either exactly one edge is a boundary edge  -or-
      //                                 near a corner and exactly zero edges are a bnd edge
      else if (mfound==2)
	{

	  // Compute edge midpoint
	  ptmp.x = 0.5*( p[tmp[jstore[1]]].x + p[tmp[jstore[2]]].x );
	  ptmp.y = 0.5*( p[tmp[jstore[1]]].y + p[tmp[jstore[2]]].y );

	  // Proceed if edge midpoint is also on the bnd <==> exactly one edge is a bnd edge
	  if (fabs(SignedDistance(ptmp))<=hmin)
	    {
	      if (jstore[1]>jstore[2])
		{
		  tmps = jstore[2];
		  jstore[2] = jstore[1];
		  jstore[1] = tmps;
		}
	      
	      B.x = p[tmp[jstore[1]]].x;
	      B.y = p[tmp[jstore[1]]].y;
	      
	      C.x = p[tmp[jstore[2]]].x;
	      C.y = p[tmp[jstore[2]]].y;

	      Anew.x = B.x + C.x - A.x;
	      Anew.y = B.y + C.y - A.y;
  
	      // Add new node and corresponding new element
	      numtri_new = numtri_new+1;
	      numpts_new = numpts_new+1;
	      
	      pnew[numpts_new-1].x = Anew.x;
	      pnew[numpts_new-1].y = Anew.y;
	      
	      tnew[numtri_new-1].n1 = tmp[jstore[1]];
	      tnew[numtri_new-1].n2 = tmp[jstore[2]];
	      tnew[numtri_new-1].n3 = numpts_new-1;
	      
	      // New node link to old node
	      num_ext = num_ext+1;
	      ext_new[num_ext-1] = jopp;// tmp[jstore[3]];

	      // Add ghost index;
	      numghost_new = numghost_new+1;
	      ghost_link_new[numghost_new-1] = i;

	      // Center information - to be used for periodic BCs
	      num_centers = num_centers + 1;
	      centers_index_tmp[num_centers-1] = i;
	      double x1 = A.x;
	      double x2 = B.x;
	      double x3 = C.x;
	      double y1 = A.y;
	      double y2 = B.y;
	      double y3 = C.y;
	      centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow)
		+ 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow);
	      
	      // Compute signed element area, change orientation if necessary
	      v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x;
	      v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y;
	      v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x;
	      v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y;
	      v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x;
	      v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y;
	      
	      area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * 
					   (pnew[tnew[numtri_new-1].n2].y
					    -pnew[tnew[numtri_new-1].n3].y) + 
					   pnew[tnew[numtri_new-1].n2].x * 
					   (pnew[tnew[numtri_new-1].n3].y
					    -pnew[tnew[numtri_new-1].n1].y) +
					   pnew[tnew[numtri_new-1].n3].x * 
					   (pnew[tnew[numtri_new-1].n1].y
					    -pnew[tnew[numtri_new-1].n2].y));

	      if (area_new[numtri_new-1] < 0.0)
		{
		  temp = tnew[numtri_new-1].n2;
		  tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3;
		  tnew[numtri_new-1].n3 = temp;
		  area_new[numtri_new-1] = fabs(area_new[numtri_new-1]);
		}

	      // Add element area to the appropriate dual cell area
	      cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0);
	      cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0);
	    }
	}
    }

  // Resize all appropriate vectors
  delete[] p;
  delete[] t;
  delete[] area;
  delete[] cdual;

  numpts = numpts_new;
  numtri = numtri_new;
  numghost = numghost_new;
  num_ext_node = num_ext;

  p = new point[numpts];
  t = new triangle[numtri];
  area = new double[numtri];
  cdual = new double[numpts];
  ghost_link = new int[numghost];
  proper_ghostcell = new int[numghost];
  ext_node_link = new int[num_ext];

  for (i=0; i<numtri; i++)
    {
      t[i].n1 = tnew[i].n1;
      t[i].n2 = tnew[i].n2;
      t[i].n3 = tnew[i].n3;

      area[i] = area_new[i];
    }

  for (i=0; i<numpts; i++)
    {
      p[i].x = pnew[i].x;
      p[i].y = pnew[i].y;

      cdual[i] = cdual_new[i];
    }

  for (i=0; i<numghost; i++)
    {
      ghost_link[i] = ghost_link_new[i];
    }

  for (i=0; i<numghost; i++)
    {
      proper_ghostcell[i] = 1;
    }

  for (i=0; i<num_ext; i++)
    {
      ext_node_link[i] = ext_new[i];
    }

  // Apply periodic boundary conditions
  int*  centers_index = new int[num_centers];
  double*  centers_xy = new double[num_centers];
  bool* centers_found = new bool[num_centers];
 
  for (i=0; i<num_centers; i++)
    {
      centers_index[i] = centers_index_tmp[i];
      centers_xy[i]    = centers_xy_tmp[i];
      centers_found[i] = 0;
    }
  delete[] centers_index_tmp;
  delete[] centers_xy_tmp;

  const double lx = (cart2dinfo.xhigh-cart2dinfo.xlow);
  const double ly = (cart2dinfo.yhigh-cart2dinfo.ylow);

  for (i=0; i<numghost; i++)
    {
      int n1 = t[numtri-numghost+i].n1;
      int n2 = t[numtri-numghost+i].n2;
      int n3 = t[numtri-numghost+i].n3;
      double x1 = p[n1].x;
      double y1 = p[n1].y;
      double x2 = p[n2].x;
      double y2 = p[n2].y;
      double x3 = p[n3].x;
      double y3 = p[n3].y;
      double xc = modxy(onethird*(x1+x2+x3),cart2dinfo.xlow,cart2dinfo.xhigh,lx);
      double yc = modxy(onethird*(y1+y2+y3),cart2dinfo.ylow,cart2dinfo.yhigh,ly);
      double cent = olx*(xc-cart2dinfo.xlow) + 1000.0*oly*(yc-cart2dinfo.ylow);

      ghost_link[i] = find_center(num_centers,centers_index,centers_xy,cent);
    }

}
Beispiel #8
0
partlist *getParticles(matrix *mat){
	int i,j;
	int id_counter=0;
	int width,height;
	
	partlist *plist;
	if((plist = calloc(1,sizeof(partlist)))==NULL){
		fprintf(stderr, "ident.c: getParticles(): Out of memory error.\n");
		exit(1);
	}

	width=mat->width;
	height=mat->height;
	
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){

			if(mat->vals[i][j] == 0){
				continue;
			}

			particle *part;
			
			part = floodfill(mat,getid(&id_counter),i,j);
			find_center(part);
			find_radius(part);
#ifndef USE_RADIUS_THRESH
			if(part->size > MAX_PART_SIZE){			//This if statement removes any particles that are too large or too small.
				freeParticle(part);
				continue;
			}else if(part->size < MIN_PART_SIZE){
				freeParticle(part);
				continue;
			}
#endif
			
			
			
			
#ifdef	USE_RADIUS_THRESH
			
			if(part->radius > RAD_MAX){
				freeParticle(part);
				continue;
			}else if(part->radius < RAD_MIN){
				freeParticle(part);
				continue;
			}
#endif

			
			
			else if(part->x > mat->width-6){
				freeParticle(part);
				continue;
			}else if(part->x < 5){
				freeParticle(part);
				continue;
			}else if(part->y > mat->height-6){
				freeParticle(part);
				continue;
			}else if(part->y < 5){
				freeParticle(part);
				continue;
			}else{
				pushParticle(plist,part);
			}		
			
			
		}
	}
	return plist;
}