コード例 #1
0
ファイル: eige.c プロジェクト: erdc-cm/petsc-dev
/* collective on KSP */
PetscErrorCode KSPPlotEigenContours_Private(KSP ksp,PetscInt neig,const PetscReal *r,const PetscReal *c)
{
  PetscErrorCode      ierr;
  PetscReal           xmin,xmax,ymin,ymax,*xloc,*yloc,*value,px0,py0,rscale,iscale;
  PetscInt            M,N,i,j;
  PetscMPIInt         rank;
  PetscViewer         viewer;
  PetscDraw           draw;
  PetscDrawAxis       drawaxis;

  PetscFunctionBegin;
  ierr = MPI_Comm_rank(((PetscObject)ksp)->comm,&rank);CHKERRQ(ierr);
  if (rank) PetscFunctionReturn(0);
  M = 80;
  N = 80;
  xmin = r[0]; xmax = r[0];
  ymin = c[0]; ymax = c[0];
  for (i=1; i<neig; i++) {
    xmin = PetscMin(xmin,r[i]);
    xmax = PetscMax(xmax,r[i]);
    ymin = PetscMin(ymin,c[i]);
    ymax = PetscMax(ymax,c[i]);
  }
  ierr = PetscMalloc3(M,PetscReal,&xloc,N,PetscReal,&yloc,M*N,PetscReal,&value);CHKERRQ(ierr);
  for (i=0; i<M; i++) xloc[i] = xmin - 0.1*(xmax-xmin) + 1.2*(xmax-xmin)*i/(M-1);
  for (i=0; i<N; i++) yloc[i] = ymin - 0.1*(ymax-ymin) + 1.2*(ymax-ymin)*i/(N-1);
  ierr = PolyEval(neig,r,c,0,0,&px0,&py0);CHKERRQ(ierr);
  rscale = px0/(PetscSqr(px0)+PetscSqr(py0));
  iscale = -py0/(PetscSqr(px0)+PetscSqr(py0));
  for (j=0; j<N; j++) {
    for (i=0; i<M; i++) {
      PetscReal px,py,tx,ty,tmod;
      ierr = PolyEval(neig,r,c,xloc[i],yloc[j],&px,&py);CHKERRQ(ierr);
      tx = px*rscale - py*iscale;
      ty = py*rscale + px*iscale;
      tmod = PetscSqr(tx) + PetscSqr(ty); /* modulus of the complex polynomial */
      if (tmod > 1) tmod = 1.0;
      if (tmod > 0.5 && tmod < 1) tmod = 0.5;
      if (tmod > 0.2 && tmod < 0.5) tmod = 0.2;
      if (tmod > 0.05 && tmod < 0.2) tmod = 0.05;
      if (tmod < 1e-3) tmod = 1e-3;
      value[i+j*M] = PetscLogScalar(tmod) / PetscLogScalar(10.0);
    }
  }
  ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Iteratively Computed Eigen-contours",PETSC_DECIDE,PETSC_DECIDE,450,450,&viewer);CHKERRQ(ierr);
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
  ierr = PetscDrawTensorContour(draw,M,N,PETSC_NULL,PETSC_NULL,value);CHKERRQ(ierr);
  if (0) {
    ierr = PetscDrawAxisCreate(draw,&drawaxis);CHKERRQ(ierr);
    ierr = PetscDrawAxisSetLimits(drawaxis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
    ierr = PetscDrawAxisSetLabels(drawaxis,"Eigen-counters","real","imag");CHKERRQ(ierr);
    ierr = PetscDrawAxisDraw(drawaxis);CHKERRQ(ierr);
    ierr = PetscDrawAxisDestroy(&drawaxis);CHKERRQ(ierr);
  }
  ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
  ierr = PetscFree3(xloc,yloc,value);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
コード例 #2
0
ファイル: polysolv.cpp プロジェクト: Kalamatee/RayStorm
/*************
 * DESCRIPTION:   Return the number of sign changes in the Sturm sequence in
 *    sseq at the value a.
 * INPUT:         np
 *                sseq
 *                a
 * OUTPUT:        sign changes
 *************/
static int NumChanges(int np, POLYNOMIAL *sseq, double a)
{
	int changes;
	double f, lf;
	POLYNOMIAL *s;

	changes = 0;

	lf = PolyEval(a, sseq[0].ord, sseq[0].coef);

	for (s = sseq + 1; s <= sseq + np; s++)
	{
		f = PolyEval(a, s->ord, s->coef);

		if(lf == 0.0 || lf * f < 0)
			changes++;

		lf = f;
	}

	return changes;
}
コード例 #3
0
ファイル: polysolv.cpp プロジェクト: Kalamatee/RayStorm
/*************
 * DESCRIPTION:   Close in on a root by using regula-falsa
 * INPUT:         order
 *                coef
 *                a
 *                b
 *                val
 * OUTPUT:
 *************/
static int RegulaFalsa(int order, double *coef, double a, double b, double *val)
{
	int its;
	double fa, fb, x, fx, lfx;

	fa = PolyEval(a, order, coef);
	fb = PolyEval(b, order, coef);

	if(fa * fb > 0.0)
		return 0;

	if(fabs(fa) < COEFF_LIMIT)
	{
		*val = a;
		return 1;
	}

	if(fabs(fb) < COEFF_LIMIT)
	{
		*val = b;
		return 1;
	}

	lfx = fa;

	for(its = 0; its < MAX_ITERATIONS; its++)
	{
		x = (fb * a - fa * b) / (fb - fa);

		fx = PolyEval(x, order, coef);

		if(fabs(x) > EPSILON)
		{
			if (fabs(fx / x) < EPSILON)
			{
				*val = x;
				return 1;
			}
		}
		else
		{
			if(fabs(fx) < EPSILON)
			{
				*val = x;
				return 1;
			}
		}

		if(fa < 0)
		{
			if(fx < 0)
			{
				a = x;
				fa = fx;

				if((lfx * fx) > 0)
					fb *= .5;
			}
			else
			{
				b = x;
				fb = fx;

				if((lfx * fx) > 0)
					fa *= .5;
			}
		}
		else
		{
			if(fx < 0)
			{
				b = x;
				fb = fx;

				if((lfx * fx) > 0)
					fa *= .5;
			}
			else
			{
				a = x;
				fa = fx;

				if((lfx * fx) > 0)
					fb *= .5;
			}
		}

		// Check for underflow in the domain
		if(fabs(b-a) < EPSILON)
		{
			*val = x;
			return 1;
		}

		lfx = fx;
	}

	return 0;
}