void ImmersedBoundaryMethod::InterpolateFluidVelocity()
{
  const auto nx = lm_.GetNumberOfColumns();
  const auto ny = lm_.GetNumberOfRows();
  const auto dx = lm_.GetSpaceStep();
  const auto dt = lm_.GetTimeStep();
  const auto scaling = dx / dt;
  // pointer always editable, do not need &
  for (auto particle : particles) {
    for (auto &node : particle->nodes) {
      node.u = {0.0, 0.0};
      const auto x_particle = node.coord[0];
      const auto y_particle = node.coord[1];
      // fix for truncation error when double is really close to integer value
      // http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1
      // uses "machine epsilon" through std::numeric_limits<double>::epsilon()
      // http://stackoverflow.com/questions/17333/most-effective-way-for-float-
      // and-double-comparison
      const auto x_fluid = static_cast<int>(floor(x_particle + 2 *
          particle->char_length * std::numeric_limits<double>::epsilon()));
      const auto y_fluid = static_cast<int>(floor(y_particle + 2 *
          particle->char_length * std::numeric_limits<double>::epsilon()));
      for (auto y = y_fluid; y < y_fluid + 2; ++y) {
        for (auto x = x_fluid; x < x_fluid + 2; ++x) {
          const auto n = ((y + ny) % ny) * nx + (x + nx) % nx;
          const auto weight = Dirac(stencil_, x_particle - x, y_particle - y);
          // node velocity maybe calculated in dimensionless units (check)
          node.u[0] += lm_.u[n][0] / scaling * weight;
          node.u[1] += lm_.u[n][1] / scaling * weight;
        }  // x
      }  // y
    }  // node
  }  // particle
}
示例#2
0
ImageF drlse_edge(ImageF phi_0,ImageF g,float lambda,float mu,float alfa,float epsilon,int timestep, int iter,string sada,char * potentialFunction)
{
	ImageF phi=phi_0;

	for(int i=0;i<iter;i++)
	{
		phi=NeumannBoundCond(phi);
		ImageF *vx=new ImageF();
		ImageF *vy=new ImageF();
		(*vy)*(vx);
		ImageF *phi_x=new ImageF();
		ImageF *phi_y=new ImageF();
		*vx=gradientx(g);
		*vy=gradienty(g);
		*phi_x=gradientx(g);
		*phi_y=gradienty(g);
		ImageF *s=new ImageF();
		*s=ImageFSqrt( *vx, *vy);
		float smallNumber=1e-10;
		ImageF *Nx,*Ny;
		*Nx=*phi_x/(*s+smallNumber);
		*Ny=*phi_y/(*s+smallNumber);
		ImageF * curvature=new ImageF();
		*curvature=div(*Nx,*Ny);
		ImageF distRegTerm;
		if (strcmp(potentialFunction,"single-well"))
			/*
			compute distance regularization term in equation (13) 
			with the single-well potential p1.
			*/
			distRegTerm= 4*del2(phi)-*curvature;
		//printf("");

		else if (strcmp(potentialFunction,"double-well"))
		{
			distRegTerm=distReg_p2(phi);  // compute the distance regularization term in eqaution (13) with the double-well potential p2.

			printf("asda");

		}
		else printf("EEROR");

		//float eplsion=0.1;
		ImageF diracPhi=Dirac(phi,epsilon);
		ImageF areaTerm=diracPhi*g; 
		ImageF  *edgeTerm=new ImageF();
		*edgeTerm=diracPhi*(*vx**Nx+*vy**Ny) + diracPhi*g*(*curvature);
		//vx*vy;
		 phi=phi + timestep*(mu*distRegTerm + lambda**edgeTerm + alfa*areaTerm);
		return phi_0; 
	}
}
void ImmersedBoundaryMethod::SpreadForce()
{
  // The two-point interpolation stencil (bi-linear interpolation) is used in
  // the present code.
  fluid_force.assign(fluid_force.size(), {0.0, 0.0});
  const auto nx = lm_.GetNumberOfColumns();
  const auto ny = lm_.GetNumberOfRows();
  const auto dx = lm_.GetSpaceStep();
  const auto dt = lm_.GetTimeStep();
  const auto scaling = dx / dt / dt;
  for (auto particle : particles) {
    for (auto &node : particle->nodes) {
      // Identify the lowest fluid lattice node in interpolation range.
      // The other fluid nodes in range have coordinates
      // (x_fluid + 1, y_fluid), (x_fluid, y_fluid + 1), and
      // (x_fluid + 1, y_fluid + 1).
      const auto x_particle = node.coord[0];
      const auto y_particle = node.coord[1];
      const auto x_fluid = static_cast<int>(floor(x_particle + 2 *
          particle->char_length * std::numeric_limits<double>::epsilon()));
      const auto y_fluid = static_cast<int>(floor(y_particle + 2 *
          particle->char_length * std::numeric_limits<double>::epsilon()));
      std::cout << x_particle << " " << x_fluid << std::endl;
      // Consider unrolling these 2 loops
      for (auto y = y_fluid; y < y_fluid + 2; ++y) {
        for (auto x = x_fluid; x < x_fluid + 2; ++x) {
          const auto n = ((y + ny) % ny) * nx + (x + nx) % nx;
          // Compute interpolation weights based on distance using interpolation
          // stencil, still need to implement others
          const auto weight = Dirac(stencil_, x_particle - x, y_particle - y);
          // Compute fluid force
          fluid_force[n][0] += node.force[0] * scaling * weight;
          fluid_force[n][1] += node.force[1] * scaling * weight;
        }  // x
      }  // y
    }  // node
  }  // particle
}
示例#4
0
void Evolution(IplImage *u, IplImage *g, double lambda, double mu, double alf, double epsilon, double delt, int numIter)
{
    if (!u||!g)
        return;
    CvSize size = cvGetSize(u);
    IplImage* vx = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* vy = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* ux = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* uy = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* Nx = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* Ny = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* diracU = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* K = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* laplace = cvCreateImage(size,IPL_DEPTH_32F,1);

    Sobel(g, vx, vy);

    int i,j;
    CvScalar cur1,cur2,cur11,cur22,cur;
    CvScalar Cdirac, Cvx, CNx, Cvy, CNy, Cg, CK, Claplace, Cu;
    for (int k=0;k<numIter;k++)
    {
        cout<<k<<"……"<<endl;
        NeumannBoundCond(u);
        Sobel(u, ux, uy);

        for (i=0; i<size.height; i++)
        {
            for(j=0; j<size.width; j++)
            {
                cur1 = cvGet2D(ux,i,j);
                cur2 = cvGet2D(uy,i,j);
                cur11.val[0] = cur1.val[0]/sqrt(cur1.val[0]*cur1.val[0] + cur2.val[0]*cur2.val[0] + 1e-10);
                cur22.val[0] = cur2.val[0]/sqrt(cur1.val[0]*cur1.val[0] + cur2.val[0]*cur2.val[0] + 1e-10);
                cvSet2D(Nx,i,j,cur11);
                cvSet2D(Ny,i,j,cur22);
            }
        }

        Dirac(u,diracU,epsilon);
        CurvatureCentral2(Nx,Ny,K);
        cvLaplace(u, laplace, 1);

        for (i=0; i<size.height; i++)
        {
            for(j=0; j<size.width; j++)
            {
                Cdirac = cvGet2D(diracU,i,j);
                Cvx = cvGet2D(vx,i,j);
                CNx = cvGet2D(Nx,i,j);
                Cvy = cvGet2D(vy,i,j);
                CNy = cvGet2D(Ny,i,j);
                Cg = cvGet2D(g,i,j);
                CK = cvGet2D(K,i,j);
                Claplace = cvGet2D(laplace,i,j);
                Cu = cvGet2D(u,i,j);

                cur.val[0] = lambda*Cdirac.val[0]*(Cvx.val[0]*CNx.val[0] + Cvy.val[0]*CNy.val[0] + Cg.val[0]*CK.val[0])
                    + mu*(Claplace.val[0]-CK.val[0]) + alf*Cdirac.val[0]*Cg.val[0];
                Cu.val[0] += delt*cur.val[0];
                cvSet2D(u,i,j,Cu);
            }
        }
    }
    cvReleaseImage(&vx);
    cvReleaseImage(&vy);
    cvReleaseImage(&ux);
    cvReleaseImage(&uy);
    cvReleaseImage(&Nx);
    cvReleaseImage(&Ny);
    cvReleaseImage(&diracU);
    cvReleaseImage(&K);
    cvReleaseImage(&laplace);
}
示例#5
0
void Evolution2(IplImage * u, IplImage *g, double lambda, double mu, double alf, double epsilon, double delt, int numIter)
{
    if (!u||!g)
        return;
    CvSize size = cvGetSize(u);
    IplImage* vx = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* vy = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* ux = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* uy = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* Nx = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* Ny = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* diracU = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* K = cvCreateImage(size,IPL_DEPTH_32F,1);
    IplImage* Laplace = cvCreateImage(size,IPL_DEPTH_32F,1);

    Sobel(g,vx,vy);
    CvScalar s1,s2,s11,s22;
    CvScalar Cdirac, Cvx, Cvy, CNx, CNy, Cg, CK, CLaplace, Cu;
    int i,j;
    for(int k=0;k<numIter;k++)
    {
        cout<<k<<"……"<<endl;
        NeumannBoundCond(u);
        Sobel(u,ux,uy);

        for(i=0;i<size.height;i++)
        {
            for(j=0;j<size.width;j++)
            {
                s1=cvGet2D(ux,i,j);
                s2=cvGet2D(uy,i,j);
                double normDu=sqrt(pow(s1.val[0],2)+pow(s2.val[0],2)+1e-10);
                s11.val[0]=s1.val[0]/normDu;
                s22.val[0]=s2.val[0]/normDu;
                cvSet2D(Nx,i,j,s11);
                cvSet2D(Ny,i,j,s22);
            }
        }

        Dirac(u,diracU,epsilon);
        CurvatureCentral2(Nx,Ny,K);
        cvLaplace(u, Laplace, 1);
        for(i=0;i<size.height;i++)
        {
            for(j=0;j<size.width;j++)
            {
                Cdirac=cvGet2D(diracU,i,j);
                Cvx=cvGet2D(vx,i,j);
                Cvy=cvGet2D(vy,i,j);
                CNx=cvGet2D(Nx,i,j);
                CNy=cvGet2D(Ny,i,j);
                Cg=cvGet2D(g,i,j);
                CK=cvGet2D(K,i,j);
                CLaplace=cvGet2D(Laplace,i,j);
                Cu=cvGet2D(u,i,j);

                double weightedLengthTerm=lambda*Cdirac.val[0]*(Cvx.val[0]*CNx.val[0]+Cvy.val[0]*CNy.val[0]+Cg.val[0]*CK.val[0]);
                double weightedAreaTerm=alf*Cdirac.val[0]*Cg.val[0];
                double penalizingTerm=mu*(CLaplace.val[0]-CK.val[0]);
                double total=weightedLengthTerm+weightedAreaTerm+penalizingTerm;
                Cu.val[0]+=delt*total;
                cvSet2D(u,i,j,Cu);
            }
        }
    }
    cvReleaseImage(&vx);
    cvReleaseImage(&vy);
    cvReleaseImage(&ux);
    cvReleaseImage(&uy);
    cvReleaseImage(&Nx);
    cvReleaseImage(&Ny);
    cvReleaseImage(&diracU);
    cvReleaseImage(&K);
    cvReleaseImage(&Laplace);
}