Beispiel #1
0
Datei: rd.c Projekt: gnovak/bin
float rd(float x, float y, float z)
{
	float alamb,ave,delx,dely,delz,ea,eb,ec,ed,ee,fac,sqrtx,sqrty,
		sqrtz,sum,xt,yt,zt;

	if (FMIN(x,y) < 0.0 || FMIN(x+y,z) < TINY || FMAX(FMAX(x,y),z) > BIG)
		nrerror("invalid arguments in rd");
	xt=x;
	yt=y;
	zt=z;
	sum=0.0;
	fac=1.0;
	do {
		sqrtx=sqrt(xt);
		sqrty=sqrt(yt);
		sqrtz=sqrt(zt);
		alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
		sum += fac/(sqrtz*(zt+alamb));
		fac=0.25*fac;
		xt=0.25*(xt+alamb);
		yt=0.25*(yt+alamb);
		zt=0.25*(zt+alamb);
		ave=0.2*(xt+yt+3.0*zt);
		delx=(ave-xt)/ave;
		dely=(ave-yt)/ave;
		delz=(ave-zt)/ave;
	} while (FMAX(FMAX(fabs(delx),fabs(dely)),fabs(delz)) > ERRTOL);
	ea=delx*dely;
	eb=delz*delz;
	ec=ea-eb;
	ed=ea-6.0*eb;
	ee=ed+ec+ec;
	return 3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*delz*ee)
		+delz*(C2*ee+delz*(-C3*ec+delz*C4*ea)))/(ave*sqrt(ave));
}
/**************************************************************************
|
|     Method: AdjustNearestPoints
|
|    Purpose: Given nearest point information for two infinite lines, adjust
|             to model finite line segments.
|
| Parameters: Input:
|             ------
|             A1x, A1y, A1z   - Coordinates of first defining point of line/segment A
|             Lax, Lay, Laz   - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|             B1x, B1y, B1z   - Coordinates of first defining point of line/segment B
|             Lbx, Lby, Lbz   - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|             epsilon_squared - tolerance value to be used to check for degenerate
|                               and parallel lines, and to check for true intersection.
|             s               - parameter representing nearest point on infinite line A
|             t               - parameter representing nearest point on infinite line B
|
|             Output:
|             -------
|             PointOnSegAx,   - Coordinates of the point on segment A that are nearest
|             PointOnSegAy,     to segment B. This corresponds to point C in the text.
|             PointOnSegAz
|             PointOnSegBx,   - Coordinates of the point on segment B that are nearest
|             PointOnSegBy,     to segment A. This corresponds to point D in the text.
|             PointOnSegBz
**************************************************************************/
void AdjustNearestPoints(number A1x, number A1y, number A1z,
                         number Lax, number Lay, number Laz,
                         number B1x, number B1y, number B1z,
                         number Lbx, number Lby, number Lbz,
                         number epsilon_squared, number s, number t,
                         number &PointOnSegAx, number &PointOnSegAy, number &PointOnSegAz,
                         number &PointOnSegBx, number &PointOnSegBy, number &PointOnSegBz)
{
// handle the case where both parameter s and t are out of range
  if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
  {
    s = FMAX(0.0f, FMIN(1.0f, s));
    PointOnSegAx = (A1x + s * Lax);
    PointOnSegAy = (A1y + s * Lay);
    PointOnSegAz = (A1z + s * Laz);
    FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
                                  PointOnSegAy, PointOnSegAz, true, epsilon_squared,
                                  PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
    if (OUT_OF_RANGE(t))
    {
      t = FMAX(0.0f, FMIN(1.0f, t));
      PointOnSegBx = (B1x + t * Lbx);
      PointOnSegBy = (B1y + t * Lby);
      PointOnSegBz = (B1z + t * Lbz);
      FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
                                    PointOnSegBy, PointOnSegBz, false, epsilon_squared,
                                    PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
      FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
                                    PointOnSegAy, PointOnSegAz, false, epsilon_squared,
                                    PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
    }
  }
// otherwise, handle the case where the parameter for only one segment is
// out of range
  else if (OUT_OF_RANGE(s))
  {
    s = FMAX(0.0f, FMIN(1.0f, s));
    PointOnSegAx = (A1x + s * Lax);
    PointOnSegAy = (A1y + s * Lay);
    PointOnSegAz = (A1z + s * Laz);
    FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
                                  PointOnSegAy, PointOnSegAz, false, epsilon_squared,
                                  PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
  }
  else if (OUT_OF_RANGE(t))
  {
    t = FMAX(0.0f, FMIN(1.0f, t));
    PointOnSegBx = (B1x + t * Lbx);
    PointOnSegBy = (B1y + t * Lby);
    PointOnSegBz = (B1z + t * Lbz);
    FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
                                  PointOnSegBy, PointOnSegBz, false, epsilon_squared,
                                  PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
  }
  else
  {
    assert(0);
  }
}
/**************************************************************************
|
|     Method: FindNearestPointOfParallelLineSegments
|
|    Purpose: Given two lines (segments) that are known to be parallel, find
|             a representative point on each that is nearest to the other. If
|             the lines are considered to be finite then it is possible that there
|             is one true point on each line that is nearest to the other. This
|             code properly handles this case.
|
|             This is the most difficult line intersection case to handle, since
|             there is potentially a family, or locus of points on each line/segment
|             that are nearest to the other.
| Parameters: Input:
|             ------
|             A1x, A1y, A1z   - Coordinates of first defining point of line/segment A
|             A2x, A2y, A2z   - Coordinates of second defining point of line/segment A
|             Lax, Lay, Laz   - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|             B1x, B1y, B1z   - Coordinates of first defining point of line/segment B
|             B2x, B2y, B2z   - Coordinates of second defining point of line/segment B
|             Lbx, Lby, Lbz   - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|             infinite_lines  - set to true if lines are to be treated as infinite
|             epsilon_squared - tolerance value to be used to check for degenerate
|                               and parallel lines, and to check for true intersection.
|
|             Output:
|             -------
|             PointOnSegAx,   - Coordinates of the point on segment A that are nearest
|             PointOnSegAy,     to segment B. This corresponds to point C in the text.
|             PointOnSegAz
|             PointOnSegBx,   - Coordinates of the point on segment B that are nearest
|             PointOnSegBy,     to segment A. This corresponds to point D in the text.
|             PointOnSegBz

**************************************************************************/
__forceinline void FindNearestPointOfParallelLineSegments(const D3DXVECTOR3 & A1,
														  const D3DXVECTOR3 & A2,
														  const D3DXVECTOR3 & La,
														  const D3DXVECTOR3 & B1,
														  const D3DXVECTOR3 & B2,
														  const D3DXVECTOR3 & Lb,
														  //bool infinite_lines, float epsilon_squared,
														  D3DXVECTOR3 & OutA,
														  D3DXVECTOR3 & OutB)
{
	float s[2], temp;
	FindNearestPointOnLineSegment(A1, La, B1, OutA, s[0]);
	/*if (true == infinite_lines)
	{
	    PointOnSegBx = B1x;
	    PointOnSegBy = B1y;
	    PointOnSegBz = B1z;
	}
	else*/
	{
		//float tp[3];
		D3DXVECTOR3 tp;
		FindNearestPointOnLineSegment(A1, La, B2,
			tp, s[1]);
		if (s[0] < 0.f && s[1] < 0.f)
		{
			OutA = A1;
			if (s[0] < s[1])
			{
				OutB =B2;
			}
			else
			{
				OutB = B1;
			}
		}
		else if (s[0] > 1.f && s[1] > 1.f)
		{
			OutA = A2;
			if (s[0] < s[1])
			{
				OutB = B1;
			}
			else
			{
				OutB = B2;
			}
		}
		else
		{
			temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
			OutA = A1 + temp * La;
			FindNearestPointOnLineSegment(B1, Lb,
				OutA, OutB, temp);
		}
	}
}
Beispiel #4
0
//l corresponds to vector with 3 elements
void lsort(float *c, float *a, float *b, int *l)
{
    int tmp = 0;
    float arg1 = 0.0;
    float arg2 = 0.0;

    //initialise
    *l = 0;
    *(l + 1) = 1;
    *(l + 2) = 2;

    if (c < a)
    {
        tmp = *l;
        *l = *(l + 1);
        *(l + 1) = tmp;

        arg1 = *c;
        arg2 = *a;
        *c = FMAX(arg1, arg2);
        *a = FMIN(arg1, arg2);
    }
    else
        ;

    if (c < b)
    {
        tmp = *l;
        *l = *(l + 2);
        *(l + 2) = tmp;

        arg1 = *c;
        arg2 = *b;
        *c = FMAX(arg1, arg2);
        *b = FMIN(arg1, arg2);
    }
    else
        ;

    if (a < b)
    {
        tmp = *(l + 1);
        *(l + 1) = *(l + 2);
        *(l + 2) = tmp;

        arg1 = *a;
        arg2 = *b;
        *a = FMAX(arg1, arg2);
        *b = FMIN(arg1, arg2);
    }
    else
        ;
}
Beispiel #5
0
void quadvl(float x, float y, float *fa, float *fb, float *fc, float *fd)
{
	float qa,qb,qc,qd;

	qa=FMIN(2.0,FMAX(0.0,1.0-x));
	qb=FMIN(2.0,FMAX(0.0,1.0-y));
	qc=FMIN(2.0,FMAX(0.0,x+1.0));
	qd=FMIN(2.0,FMAX(0.0,y+1.0));
	*fa=0.25*qa*qb;
	*fb=0.25*qb*qc;
	*fc=0.25*qc*qd;
	*fd=0.25*qd*qa;
}
Beispiel #6
0
void minmod2grav_mix(struct Gtype *U1, struct Gtype *U2){
  REAL Dm=U1->d;
  REAL Dp=U2->d;
  REAL beta=1.; // 1 MINBEE 2 SUPERBEE

  if(Dp>0){
    U1->d=FMAX(FMAX(0.,FMIN(beta*Dm,Dp)),FMIN(Dm,beta*Dp));
    U2->d=U1->d;
  }
  else{
    U1->d=FMIN(FMIN(0.,FMAX(beta*Dm,Dp)),FMAX(Dm,beta*Dp));
    U2->d=U1->d;
  }
}
Beispiel #7
0
void my_float_listener (PluginParam *param) {
  GtkProgressBar *progress;

  if (sdlGoom->config_win == 0) return;
  progress = GTK_PROGRESS_BAR(param->user_data);

  if (progress) {
    if (FVAL(*param)<FMIN(*param))
      FVAL(*param) = FMIN(*param);
    if (FVAL(*param)>FMAX(*param))
      FVAL(*param) = FMAX(*param);
    gtk_progress_bar_update (progress, FVAL(*param));
  }
}
/**************************************************************************
|
|     Method: AdjustNearestPoints
|
|    Purpose: Given nearest point information for two infinite lines, adjust
|             to model finite line segments.
|
| Parameters: Input:
|             ------
|             A1x, A1y, A1z   - Coordinates of first defining point of line/segment A
|             Lax, Lay, Laz   - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|             B1x, B1y, B1z   - Coordinates of first defining point of line/segment B
|             Lbx, Lby, Lbz   - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|             epsilon_squared - tolerance value to be used to check for degenerate
|                               and parallel lines, and to check for true intersection.
|             s               - parameter representing nearest point on infinite line A
|             t               - parameter representing nearest point on infinite line B
|
|             Output:
|             -------
|             PointOnSegAx,   - Coordinates of the point on segment A that are nearest
|             PointOnSegAy,     to segment B. This corresponds to point C in the text.
|             PointOnSegAz
|             PointOnSegBx,   - Coordinates of the point on segment B that are nearest
|             PointOnSegBy,     to segment A. This corresponds to point D in the text.
|             PointOnSegBz
**************************************************************************/
__forceinline void AdjustNearestPoints(const D3DXVECTOR3 & A1,
									   const D3DXVECTOR3 & La,
									   const D3DXVECTOR3 & B1,
									   const D3DXVECTOR3 & Lb,
									   float s, float t,
									   D3DXVECTOR3 & OutA,
									   D3DXVECTOR3 & OutB)
{
	// handle the case where both parameter s and t are out of range
	if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
	{
		s = FMAX(0.0f, FMIN(1.0f, s));
		OutA = A1 + s*La;
		FindNearestPointOnLineSegment(B1, Lb, 
			OutA,
			OutB, t);
		if (OUT_OF_RANGE(t))
		{
			t = FMAX(0.0f, FMIN(1.0f, t));
			OutB = B1 + t*Lb;
			FindNearestPointOnLineSegment(A1, La, OutB, 
				OutA, s);
			FindNearestPointOnLineSegment(B1, Lb, OutA,
				OutB, t);
		}
	}
	// otherwise, handle the case where the parameter for only one segment is
	// out of range
	else if (OUT_OF_RANGE(s))
	{
		s = FMAX(0.0f, FMIN(1.0f, s));
		OutA = A1 + s*La;
		FindNearestPointOnLineSegment(B1, Lb, 
			OutA, 
			OutB, t);
	}
	else if (OUT_OF_RANGE(t))
	{
		t = FMAX(0.0f, FMIN(1.0f, t));
		OutB = B1 + t*Lb;
		FindNearestPointOnLineSegment(A1, La, OutB,
			OutA, s);
	}
	else
	{
		assert(0);
	}
}
Beispiel #9
0
void savgol(float c[], int np, int nl, int nr, int ld, int m)
{
	void lubksb(float **a, int n, int *indx, float b[]);
	void ludcmp(float **a, int n, int *indx, float *d);
	int imj,ipj,j,k,kk,mm,*indx;
	float d,fac,sum,**a,*b;

	if (np < nl+nr+1 || nl < 0 || nr < 0 || ld > m || nl+nr < m)
	nrerror("bad args in savgol");
	indx=ivector(1,m+1);
	a=matrix(1,m+1,1,m+1);
	b=vector(1,m+1);
	for (ipj=0;ipj<=(m << 1);ipj++) {
		sum=(ipj ? 0.0 : 1.0);
		for (k=1;k<=nr;k++) sum += pow((double)k,(double)ipj);
		for (k=1;k<=nl;k++) sum += pow((double)-k,(double)ipj);
		mm=FMIN(ipj,2*m-ipj);
		for (imj = -mm;imj<=mm;imj+=2) a[1+(ipj+imj)/2][1+(ipj-imj)/2]=sum;
	}
	ludcmp(a,m+1,indx,&d);
	for (j=1;j<=m+1;j++) b[j]=0.0;
	b[ld+1]=1.0;
	lubksb(a,m+1,indx,b);
	for (kk=1;kk<=np;kk++) c[kk]=0.0;
	for (k = -nl;k<=nr;k++) {
		sum=b[1];
		fac=1.0;
		for (mm=1;mm<=m;mm++) sum += b[mm+1]*(fac *= k);
		kk=((np-k) % np)+1;
		c[kk]=sum;
	}
	free_vector(b,1,m+1);
	free_matrix(a,1,m+1,1,m+1);
	free_ivector(indx,1,m+1);
}
Beispiel #10
0
/**************************************************************************
|
|     Method: FindNearestPointOnLineSegment
|
|    Purpose: Given a line (segment) and a point in 3-dimensional space,
|             find the point on the line (segment) that is closest to the
|             point.
|
| Parameters: Input:
|             ------
|             A1x, A1y, A1z   - Coordinates of first defining point of the line/segment
|             Lx, Ly, Lz      - Vector from (A1x, A1y, A1z) to the second defining point
|                               of the line/segment.
|             Bx, By, Bz      - Coordinates of the point
|             infinite_lines  - set to true if lines are to be treated as infinite
|             epsilon_squared - tolerance value to be used to check for degenerate
|                               and parallel lines, and to check for true intersection.
|
|             Output:
|             -------
|             NearestPointX,  - Point on line/segment that is closest to (Bx, By, Bz)
|             NearestPointY,
|             NearestPointZ
|             parameter       - Parametric coordinate of the nearest point along the
|                               line/segment. parameter = 0 at (A1x, A1y, A1z) and
|                               parameter = 1 at the second defining point of the line/
|                               segmetn
**************************************************************************/
void FindNearestPointOnLineSegment(const number A1x, const number A1y, const number A1z,
                                   const number Lx, const number Ly, const number Lz,
                                   const number Bx, const number By, const number Bz,
                                   bool infinite_line, number epsilon_squared, number &NearestPointX,
                                   number &NearestPointY, number &NearestPointZ,
                                   number &parameter)
{
// Line/Segment is degenerate --- special case #1
  number D = Lx * Lx + Ly * Ly + Lz * Lz;
  if (D < epsilon_squared)
  {
    NearestPointX = A1x;
    NearestPointY = A1y;
    NearestPointZ = A1z;
    return;
  }

  number ABx = Bx - A1x;
  number ABy = By - A1y;
  number ABz = Bz - A1z;

// parameter is computed from Equation (20).
  parameter = (Lx * ABx + Ly * ABy + Lz * ABz) / D;

  if (false == infinite_line) parameter = FMAX(0.0f, FMIN(1.0f, parameter));

  NearestPointX = A1x + parameter * Lx;
  NearestPointY = A1y + parameter * Ly;
  NearestPointZ = A1z + parameter * Lz;
  return;
}
Beispiel #11
0
__forceinline void FindNearestPointOnLineSegment(const D3DXVECTOR3 & A1,
												 const D3DXVECTOR3 & L,
												 const D3DXVECTOR3 & B,
												 D3DXVECTOR3 & Nearest,
												 float &parameter)
{
	// Line/Segment is degenerate --- special case #1
	float D = D3DXVec3LengthSq(&L);
	if (D < MY_EPSILON*MY_EPSILON)
	{
		Nearest = A1;
		return;
	}
	
	D3DXVECTOR3 AB = B-A1;
	
	// parameter is computed from Equation (20).
	parameter = (D3DXVec3Dot(&AB,&L)) / D;
	
	//if (false == infinite_line) 
	parameter = FMAX(0.0f, FMIN(1.0f, parameter));
	
	Nearest = A1 + parameter * L;
	return;
}
void
update_Screen(void)
{
    int tem_co, row, col;
    tem_co = FMIN(co, TEMPLATE_COLS);
    for (row = 0; !BU_STR_EMPTY(screen_template[row]); row++) {
	int lastcol = -2;

	if (BU_STR_EMPTY(screen_template[row + 1])) {
	    SetStandout();
	}

	for (col = 0; col < tem_co; col++)
	    if (screen[row][col] != screen_template[row][col]) {
		if (col != lastcol+1)
		    MvCursor(col+1, row+1);
		lastcol = col;
		(void) putchar(screen_template[row][col]);
		screen[row][col] = screen_template[row][col];
	    }
    }
    (void) ClrStandout();
    EVENT_MOVE();
    (void) fflush(stdout);
    return;
}
Beispiel #13
0
void rkqs(float y[], float dydx[], int n, float *x, float htry, float eps,
	float yscal[], float *hdid, float *hnext,
	void (*derivs)(float, float [], float []))
{
	void rkck(float y[], float dydx[], int n, float x, float h,
		float yout[], float yerr[], void (*derivs)(float, float [], float []));
	int i;
	float errmax,h,htemp,xnew,*yerr,*ytemp;

	yerr=vector(1,n);
	ytemp=vector(1,n);
	h=htry;
	for (;;) {
		rkck(y,dydx,n,*x,h,ytemp,yerr,derivs);
		errmax=0.0;
		for (i=1;i<=n;i++) errmax=FMAX(errmax,fabs(yerr[i]/yscal[i]));
		errmax /= eps;
		if (errmax <= 1.0) break;
		htemp=SAFETY*h*pow(float(errmax),float(PSHRNK));
		h=(h >= 0.0 ? FMAX(htemp,0.1*h) : FMIN(htemp,0.1*h));
		xnew=(*x)+h;
		if (xnew == *x) nrerror("stepsize underflow in rkqs");
	}
	if (errmax > ERRCON) *hnext=SAFETY*h*pow(float(errmax),float(PGROW));
	else *hnext=5.0*h;
	*x += (*hdid=h);
	for (i=1;i<=n;i++) y[i]=ytemp[i];
	free_vector(ytemp,1,n);
	free_vector(yerr,1,n);
}
Beispiel #14
0
float rj(float x, float y, float z, float p)
{
	float rc(float x, float y);
	float rf(float x, float y, float z);
	float a,alamb,alpha,ans,ave,b,beta,delp,delx,dely,delz,ea,eb,ec,
		ed,ee,fac,pt,rcx,rho,sqrtx,sqrty,sqrtz,sum,tau,xt,yt,zt;

	if (FMIN(FMIN(x,y),z) < 0.0 || FMIN(FMIN(x+y,x+z),FMIN(y+z,fabs(p))) < TINY
		|| FMAX(FMAX(x,y),FMAX(z,fabs(p))) > BIG)
			nrerror("invalid arguments in rj");
	sum=0.0;
	fac=1.0;
	if (p > 0.0) {
		xt=x;
		yt=y;
		zt=z;
		pt=p;
	} else {
		xt=FMIN(FMIN(x,y),z);
		zt=FMAX(FMAX(x,y),z);
		yt=x+y+z-xt-zt;
		a=1.0/(yt-p);
		b=a*(zt-yt)*(yt-xt);
		pt=yt+b;
		rho=xt*zt/yt;
		tau=p*pt/yt;
		rcx=rc(rho,tau);
	}
	do {
		sqrtx=sqrt(xt);
		sqrty=sqrt(yt);
		sqrtz=sqrt(zt);
		alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
		alpha=SQR(pt*(sqrtx+sqrty+sqrtz)+sqrtx*sqrty*sqrtz);
		beta=pt*SQR(pt+alamb);
		sum += fac*rc(alpha,beta);
		fac=0.25*fac;
		xt=0.25*(xt+alamb);
		yt=0.25*(yt+alamb);
		zt=0.25*(zt+alamb);
		pt=0.25*(pt+alamb);
		ave=0.2*(xt+yt+zt+pt+pt);
		delx=(ave-xt)/ave;
		dely=(ave-yt)/ave;
		delz=(ave-zt)/ave;
		delp=(ave-pt)/ave;
	} while (FMAX(FMAX(fabs(delx),fabs(dely)),
		FMAX(fabs(delz),fabs(delp))) > ERRTOL);
	ea=delx*(dely+delz)+dely*delz;
	eb=delx*dely*delz;
	ec=delp*delp;
	ed=ea-3.0*ec;
	ee=eb+2.0*delp*(ea-ec);
	ans=3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*ee)+eb*(C7+delp*(-C8+delp*C4))
		+delp*ea*(C2-delp*C3)-C2*delp*ec)/(ave*sqrt(ave));
	if (p <= 0.0) ans=a*(b*ans+3.0*(rcx-rf(xt,yt,zt)));
	return ans;
}
void
prnt_Status(void)
{
    static char scratchbuf[TEMPLATE_COLS+1];
    pad_Strcpy(TITLE_PTR, title, TITLE_LEN - 1);
    pad_Strcpy(TIMER_PTR, timer, TIMER_LEN - 1);
    pad_Strcpy(F_SCRIPT_PTR, script_file, 32);
    sprintf(scratchbuf, "%11.4f", view_size);
    bu_strlcpy(VU_SIZE_PTR, scratchbuf, strlen(scratchbuf));
    pad_Strcpy(F_ERRORS_PTR, err_file, 32);
    sprintf(scratchbuf, "%11.4f", grid_dist);
    bu_strlcpy(GRID_DIS_PTR, scratchbuf, strlen(scratchbuf));
    pad_Strcpy(F_MAT_DB_PTR, mat_db_file, 32);
    sprintf(scratchbuf, "%11.4f", x_grid_offset);
    bu_strlcpy(GRID_XOF_PTR, scratchbuf, strlen(scratchbuf));
    pad_Strcpy(F_LGT_DB_PTR, lgt_db_file, 32);
    sprintf(scratchbuf, "%11.4f", y_grid_offset);
    bu_strlcpy(GRID_YOF_PTR, scratchbuf, strlen(scratchbuf));
    pad_Strcpy(F_RASTER_PTR, fb_file, 32);
    sprintf(scratchbuf, "%11.4f", modl_radius);
    bu_strlcpy(MODEL_RA_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%3d %3d %3d",
	    background[0], background[1], background[2]);
    bu_strlcpy(BACKGROU_PTR, scratchbuf, strlen(scratchbuf));
    snprintf(scratchbuf, TEMPLATE_COLS+1,
	     "%4s",	pix_buffered == B_PAGE ? "PAGE" :
	     pix_buffered == B_PIO ? "PIO" :
	     pix_buffered == B_LINE ? "LINE" : "?"
	);
    bu_strlcpy(BUFFERED_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "0x%06x", RT_G_DEBUG);
    bu_strlcpy(DEBUGGER_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%-2d", max_bounce);
    bu_strlcpy(MAX_BOUN_PTR, scratchbuf, strlen(scratchbuf));
    snprintf(scratchbuf, TEMPLATE_COLS+1, " LGT");
    bu_strlcpy(PROGRAM_NM_PTR, scratchbuf, strlen(scratchbuf));
    snprintf(scratchbuf, TEMPLATE_COLS+1, " %s ",
	     ged_file == NULL ? "(null)" : ged_file);
    bu_strlcpy(F_GED_DB_PTR, scratchbuf, FMIN(strlen(scratchbuf), 26));
    sprintf(scratchbuf, " [%04d-", grid_x_org);
    bu_strlcpy(GRID_PIX_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%04d, ", grid_x_fin);
    bu_strlcpy(GRID_SIZ_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%04d-", grid_y_org);
    bu_strlcpy(GRID_SCN_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%04d:", grid_y_fin);
    bu_strlcpy(GRID_FIN_PTR, scratchbuf, strlen(scratchbuf));
    sprintf(scratchbuf, "%04d] ", frame_no);
    bu_strlcpy(FRAME_NO_PTR, scratchbuf, strlen(scratchbuf));
    update_Screen();
    return;
}
Beispiel #16
0
int main(void)
{
	unsigned long i,nused;
	int itest,k;
	float *u,*v,*w,frac,thresh,tmp;

	u=vector(1,NMAX);
	v=vector(1,NMAX);
	w=vector(1,NMAX);
	for (;;) {
		printf("Enter k (4, -4, 12, or 20) and frac (0.0 to 1.0):\n");
		if (scanf("%d %f",&k,&frac) == EOF) break;
		frac=FMIN(1.0,FMAX(0.0,frac));
		itest=(k == -4 ? 1 : 0);
		if (k < 0) k = -k;
		if (k != 4 && k != 12 && k != 20) continue;
		for (i=1;i<=NMAX;i++)
			w[i]=v[i]=(i > NCEN-NWID && i < NCEN+NWID ?
				((float)(i-NCEN+NWID)*(float)(NCEN+NWID-i))/(NWID*NWID) : 0.0);
		if (!itest) pwtset(k);
		wt1(v,NMAX,1,itest ? daub4 : pwt);
		for (i=1;i<=NMAX;i++) u[i]=fabs(v[i]);
		thresh=select((int)((1.0-frac)*NMAX),NMAX,u);
		nused=0;
		for (i=1;i<=NMAX;i++) {
			if (fabs(v[i]) <= thresh)
				v[i]=0.0;
			else
				nused++;
		}
		wt1(v,NMAX,-1,itest ? daub4 : pwt);
		for (thresh=0.0,i=1;i<=NMAX;i++)
			if ((tmp=fabs(v[i]-w[i])) > thresh) thresh=tmp;
		printf("k,NMAX,nused= %d %d %d\n",k,NMAX,nused);
		printf("discrepancy= %12.6f\n",thresh);
	}
	free_vector(w,1,NMAX);
	free_vector(v,1,NMAX);
	free_vector(u,1,NMAX);
	return 0;
}
Beispiel #17
0
void bsstep(double y[], double dydx[], int nv, double *xx, double htry, double eps,
    double yscal[], double *hdid, double *hnext,
    void (*derivs)(double, double [], double []))
{
    void mmid(double y[], double dydx[], int nvar, double xs, double htot,
        int nstep, double yout[], void (*derivs)(double, double[], double[]));
    void pzextr(int iest, double xest, double yest[], double yz[], double dy[],
        int nv);
    int i,iq,k,kk,km;
    static int first=1,kmax,kopt;
    static double epsold = -1.0,xnew;
    double eps1,errmax,fact,h,red,scale,work,wrkmin,xest;
    double *err,*yerr,*ysav,*yseq;
    static double a[IMAXX+1];
    static double alf[KMAXX+1][KMAXX+1];
    static int nseq[IMAXX+1]={0,2,4,6,8,10,12,14,16,18};
    int reduct,exitflag=0;

    d=dmatrix(1,nv,1,KMAXX);
    err=dvector(1,KMAXX);
    x=dvector(1,KMAXX);
    yerr=dvector(1,nv);
    ysav=dvector(1,nv);
    yseq=dvector(1,nv);
    if (eps != epsold) {
        *hnext = xnew = -1.0e29;
        eps1=SAFE1*eps;
        a[1]=nseq[1]+1;
        for (k=1;k<=KMAXX;k++) a[k+1]=a[k]+nseq[k+1];
        for (iq=2;iq<=KMAXX;iq++) {
            for (k=1;k<iq;k++)
                alf[k][iq]=pow(eps1,(a[k+1]-a[iq+1])/
                    ((a[iq+1]-a[1]+1.0)*(2*k+1)));
        }
        epsold=eps;
        for (kopt=2;kopt<KMAXX;kopt++)
            if (a[kopt+1] > a[kopt]*alf[kopt-1][kopt]) break;
        kmax=kopt;
    }
    h=htry;
    for (i=1;i<=nv;i++) ysav[i]=y[i];
    if (*xx != xnew || h != (*hnext)) {
        first=1;
        kopt=kmax;
    }
    reduct=0;
    for (;;) {
        for (k=1;k<=kmax;k++) {
            xnew=(*xx)+h;
            if (xnew == (*xx)) nrerror("step size underflow in bsstep");
            mmid(ysav,dydx,nv,*xx,h,nseq[k],yseq,derivs);
            xest=SQR(h/nseq[k]);
            pzextr(k,xest,yseq,y,yerr,nv);
            if (k != 1) {
                errmax=TINY;
                for (i=1;i<=nv;i++) errmax=FMAX(errmax,fabs(yerr[i]/yscal[i]));
                errmax /= eps;
                km=k-1;
                err[km]=pow(errmax/SAFE1,1.0/(2*km+1));
            }
            if (k != 1 && (k >= kopt-1 || first)) {
                if (errmax < 1.0) {
                    exitflag=1;
                    break;
                }
                if (k == kmax || k == kopt+1) {
                    red=SAFE2/err[km];
                    break;
                }
                else if (k == kopt && alf[kopt-1][kopt] < err[km]) {
                        red=1.0/err[km];
                        break;
                    }
                else if (kopt == kmax && alf[km][kmax-1] < err[km]) {
                        red=alf[km][kmax-1]*SAFE2/err[km];
                        break;
                    }
                else if (alf[km][kopt] < err[km]) {
                    red=alf[km][kopt-1]/err[km];
                    break;
                }
            }
        }
        if (exitflag) break;
        red=FMIN(red,REDMIN);
        red=FMAX(red,REDMAX);
        h *= red;
        reduct=1;
    }
    *xx=xnew;
    *hdid=h;
    first=0;
    wrkmin=1.0e35;
    for (kk=1;kk<=km;kk++) {
        fact=FMAX(err[kk],SCALMX);
        work=fact*a[kk+1];
        if (work < wrkmin) {
            scale=fact;
            wrkmin=work;
            kopt=kk+1;
        }
    }
    *hnext=h/scale;
    if (kopt >= k && kopt != kmax && !reduct) {
        fact=FMAX(scale/alf[kopt-1][kopt],SCALMX);
        if (a[kopt+1]*fact <= wrkmin) {
            *hnext=h/fact;
            kopt++;
        }
    }
    free_dvector(yseq,1,nv);
    free_dvector(ysav,1,nv);
    free_dvector(yerr,1,nv);
    free_dvector(x,1,KMAXX);
    free_dvector(err,1,KMAXX);
    free_dmatrix(d,1,nv,1,KMAXX);
}
Beispiel #18
0
/**
 * Intersect a ray with a revolve.  If an intersection occurs, a struct
 * seg will be acquired and filled in.
 *
 * Returns -
 * 0 MISS
 * >0 HIT
 */
int
rt_revolve_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
{
    struct revolve_specific *rev =
	(struct revolve_specific *)stp->st_specific;
    struct seg *segp;

    struct hit *hitp;
    struct hit *hits[MAX_HITS], hit[MAX_HITS];

    size_t i, j, nseg, nhits;
    int in, out;

    fastf_t k, m, h, aa, bb;
    point_t dp, pr, xlated;
    vect_t vr, ur, norm, normS, normE;

    fastf_t start, end, angle;

    vect_t dir;
    point_t hit1, hit2;
    point2d_t hit2d, pt1, pt2;
    fastf_t a, b, c, disc, k1, k2, t1, t2;
    uint32_t *lng;
    struct line_seg *lsg;
    struct carc_seg *csg;

    nhits = 0;

    for (i=0; i<MAX_HITS; i++) hits[i] = &hit[i];

    vr[X] = VDOT(rev->xUnit, rp->r_dir);
    vr[Y] = VDOT(rev->yUnit, rp->r_dir);
    vr[Z] = VDOT(rev->zUnit, rp->r_dir);

    VSUB2(xlated, rp->r_pt, rev->v3d);
    pr[X] = VDOT(rev->xUnit, xlated);
    pr[Y] = VDOT(rev->yUnit, xlated);
    pr[Z] = VDOT(rev->zUnit, xlated);

    VMOVE(ur, vr);
    VUNITIZE(ur);

    if (rev->ang < M_2PI) {
	VREVERSE(normS, rev->yUnit);	/* start normal */
	start = (VDOT(normS, rev->v3d) - VDOT(normS, rp->r_pt)) / VDOT(normS, rp->r_dir);

	VCROSS(normE, rev->zUnit, rev->rEnd);	/* end normal */
	end = (VDOT(normE, rev->v3d) - VDOT(normE, rp->r_pt)) / VDOT(normE, rp->r_dir);

	VJOIN1(hit1, pr, start, vr);
	hit2d[Y] = hit1[Z];
	hit2d[X] = sqrt(hit1[X]*hit1[X] + hit1[Y]*hit1[Y]);

	VJOIN1(hit2, xlated, start, rp->r_dir);
	if (VDOT(rev->xUnit, hit2) < 0) {
	    /* set the sign of the 2D point's x coord */
	    hit2d[X] = -hit2d[X];
	}

	if (rt_sketch_contains(rev->skt, hit2d)) {
	    hit2d[X] = -hit2d[X];
	    if (rev->ang > M_PI && rt_sketch_contains(rev->skt, hit2d)) {
		/* skip it */
	    } else {
		hitp = hits[nhits++];
		hitp->hit_magic = RT_HIT_MAGIC;
		hitp->hit_dist = start;
		hitp->hit_surfno = (hit2d[X]>0) ? START_FACE_NEG : START_FACE_POS;
		VSET(hitp->hit_vpriv, -hit2d[X], hit2d[Y], 0);
	    }
	}

	VJOIN1(hit1, pr, end, vr);
	hit2d[Y] = hit1[Z];
	hit2d[X] = sqrt(hit1[X]*hit1[X] + hit1[Y]*hit1[Y]);

	VJOIN1(hit2, xlated, end, rp->r_dir);
	if (VDOT(rev->rEnd, hit2) < 0) {
	    /* set the sign of the 2D point's x coord */
	    hit2d[X] = -hit2d[X];
	}

	if (rt_sketch_contains(rev->skt, hit2d)) {
	    hit2d[X] = -hit2d[X];
	    if (rev->ang > M_PI && rt_sketch_contains(rev->skt, hit2d)) {
		/* skip it */
	    } else {
		if (nhits >= MAX_HITS) return -1; /* too many hits */
		hitp = hits[nhits++];
		hitp->hit_magic = RT_HIT_MAGIC;
		hitp->hit_dist = end;
		hitp->hit_surfno = (hit2d[X]>0) ? END_FACE_NEG : END_FACE_POS;
		VSET(hitp->hit_vpriv, -hit2d[X], hit2d[Y], 0);
	    }
	}
    }

    /**
     * calculate hyperbola parameters
     *
     * [ (x*x) / aa^2 ] - [ (y-h)^2 / bb^2 ] = 1
     *
     * x = aa cosh(t - k);
     * y = h + bb sinh(t - k);
     */

    VREVERSE(dp, pr);
    VSET(norm, ur[X], ur[Y], 0);

    k = VDOT(dp, norm) / VDOT(ur, norm);
    h = pr[Z] + k*vr[Z];

    if (NEAR_EQUAL(fabs(ur[Z]), 1.0, RT_DOT_TOL)) {
	aa = sqrt(pr[X]*pr[X] + pr[Y]*pr[Y]);
	bb = MAX_FASTF;
    } else {
	aa = sqrt((pr[X] + k*vr[X])*(pr[X] + k*vr[X]) + (pr[Y] + k*vr[Y])*(pr[Y] + k*vr[Y]));
	bb = sqrt(aa*aa * (1.0/(1 - ur[Z]*ur[Z]) - 1.0));
    }

    /**
     * if (ur[Z] == 1) {
     *	    bb = inf;
     *	    // ray becomes a line parallel to sketch's y-axis instead of a hyberbola
     * }
     * if (ur[Z] == 0) {
     *	    bb = 0;
     *	    // ray becomes a line parallel to sketch's x-axis instead of a hyperbola
     *	    // all hits must have x > aa
     * }
     */

    /* handle open sketches */
    if (!NEAR_ZERO(ur[Z], RT_DOT_TOL)) {
	for (i=0; i<rev->skt->vert_count && rev->ends[i] != -1; i++) {
	    V2MOVE(pt1, rev->skt->verts[rev->ends[i]]);
	    hit2d[Y] = pt1[Y];
	    if (NEAR_EQUAL(fabs(ur[Z]), 1.0, RT_DOT_TOL)) {
		/* ur[Z] == 1 */
		hit2d[X] = aa;
	    } else {
		hit2d[X] = aa*sqrt((hit2d[Y]-h)*(hit2d[Y]-h)/(bb*bb) + 1);
	    }
	    if (pt1[X] < 0) hit2d[X] = -fabs(hit2d[X]);
	    if (fabs(hit2d[X]) < fabs(pt1[X])) {
		/* valid hit */
		if (nhits >= MAX_HITS) return -1; /* too many hits */
		hitp = hits[nhits++];
		hitp->hit_magic = RT_HIT_MAGIC;
		hitp->hit_dist = (hit2d[Y] - pr[Z]) / vr[Z];
		hitp->hit_surfno = HORIZ_SURF;
		VJOIN1(hitp->hit_vpriv, pr, hitp->hit_dist, vr);
		hitp->hit_point[X] = hit2d[X];
		hitp->hit_point[Y] = hit2d[Y];
		hitp->hit_point[Z] = 0;

		angle = atan2(hitp->hit_vpriv[Y], hitp->hit_vpriv[X]);
		if (pt1[X] < 0) {
		    angle += M_PI;
		} else if (angle < 0) {
		    angle += M_2PI;
		}
		hit2d[X] = -hit2d[X];
		if (angle > rev->ang) {
		    nhits--;
		    continue;
		} else if ((angle + M_PI < rev->ang || angle - M_PI > 0)
			   && rt_sketch_contains(rev->skt, hit2d)
			   && hit2d[X] > 0) {
		    nhits--;
		    continue;
		}
		/* X and Y are used for uv(), Z is used for norm() */
		hitp->hit_vpriv[X] = pt1[X];
		hitp->hit_vpriv[Y] = angle;
		if (i+1 < rev->skt->vert_count && rev->ends[i+1] != -1 &&
		    NEAR_EQUAL(rev->skt->verts[rev->ends[i]][Y],
			       rev->skt->verts[rev->ends[i+1]][Y], SMALL)) {
		    hitp->hit_vpriv[Z] = rev->skt->verts[rev->ends[i+1]][X];
		    i++;
		    if (fabs(hit2d[X]) < fabs(hitp->hit_vpriv[Z])) {
			nhits--;
		    }
		} else {
		    hitp->hit_vpriv[Z] = 0;
		}
	    }
	}
    }

    /* find hyperbola intersection with each sketch segment */
    nseg = rev->skt->curve.count;
    for (i=0; i<nseg; i++) {
	lng = (uint32_t *)rev->skt->curve.segment[i];

	switch (*lng) {
	    case CURVE_LSEG_MAGIC:
		lsg = (struct line_seg *)lng;
		V2MOVE(pt1, rev->skt->verts[lsg->start]);
		V2MOVE(pt2, rev->skt->verts[lsg->end]);
		V2SUB2(dir, pt2, pt1);
		if (ZERO(dir[X])) {
		    m = 1.0;
		} else {
		    m = dir[Y] / dir[X];
		}

		if (NEAR_EQUAL(fabs(ur[Z]), 1.0, RT_DOT_TOL)) {
		    /* ray is vertical line at x=aa */
		    if (FMIN(pt1[X], pt2[X]) < aa && aa < FMAX(pt1[X], pt2[X])) {
			/* check the positive side of the sketch (x > 0) */
			k1 = (m * (aa - pt1[X]) + pt1[Y] - pr[Z]) / vr[Z];
			VJOIN1(hit1, pr, k1, vr);
			angle = atan2(hit1[Y], hit1[X]);
			hit2d[X] = -aa;		/* use neg to check for overlap in contains() */
			hit2d[Y] = hit1[Z];
			if (angle < 0) {
			    angle += M_2PI;
			}
			if (angle < rev->ang &&
			    !((angle + M_PI < rev->ang || angle - M_PI > 0)
			      && rt_sketch_contains(rev->skt, hit2d))) {
			    if (nhits >= MAX_HITS) return -1; /* too many hits */
			    hitp = hits[nhits++];
			    hitp->hit_point[X] = -hit2d[X];
			    hitp->hit_point[Y] = hit2d[Y];
			    hitp->hit_point[Z] = 0;
			    VMOVE(hitp->hit_vpriv, hit1);
			    if (ZERO(m)) {
				hitp->hit_vpriv[Z] = 0.0;
			    } else {
				hitp->hit_vpriv[Z] = -1.0/m;
			    }
			    hitp->hit_magic = RT_HIT_MAGIC;
			    hitp->hit_dist = k1;
			    hitp->hit_surfno = i;
			}
		    }
		    if (FMIN(pt1[X], pt2[X]) < -aa && -aa < FMAX(pt1[X], pt2[X])) {
			/* check negative side of the sketch (x < 0) */
			k1 = (m * (-aa - pt1[X]) + pt1[Y] - pr[Z]) / vr[Z];
			VJOIN1(hit1, pr, k1, vr);
			angle = atan2(hit1[Y], hit1[X]);
			hit2d[X] = aa;		/* use neg to check for overlap in contains() */
			hit2d[Y] = hit1[Z];
			if (angle < 0) {
			    angle += M_PI;
			}
			if (angle < rev->ang &&
			    !((angle + M_PI < rev->ang || angle - M_PI > 0)
			      && rt_sketch_contains(rev->skt, hit2d))) {
			    if (nhits >= MAX_HITS) return -1; /* too many hits */
			    hitp = hits[nhits++];
			    hitp->hit_point[X] = -hit2d[X];
			    hitp->hit_point[Y] = hit2d[Y];
			    hitp->hit_point[Z] = 0;
			    VMOVE(hitp->hit_vpriv, hit1);
			    if (ZERO(m)) {
				hitp->hit_vpriv[Z] = 0.0;
			    } else {
				hitp->hit_vpriv[Z] = 1.0/m;
			    }
			    hitp->hit_magic = RT_HIT_MAGIC;
			    hitp->hit_dist = k1;
			    hitp->hit_surfno = i;
			}
		    }
		} else if (NEAR_ZERO(ur[Z], RT_DOT_TOL)) {
		    /* ray is horizontal line at y = h; hit2d[X] > aa */
		    if (FMIN(pt1[Y], pt2[Y]) < h && h < FMAX(pt1[Y], pt2[Y])) {
			if (ZERO(m)) {
			    hit2d[X] = pt1[X];
			} else {
			    hit2d[X] = pt1[X] + (h-pt1[Y])/m;
			}
			hit2d[Y] = h;
			if (fabs(hit2d[X]) > aa) {
			    k1 = k + sqrt(hit2d[X]*hit2d[X] - aa*aa);
			    k2 = k - sqrt(hit2d[X]*hit2d[X] - aa*aa);

			    VJOIN1(hit1, pr, k1, vr);
			    angle = atan2(hit1[Y], hit1[X]);
			    if (hit2d[X] < 0) {
				angle += M_PI;
			    } else if (angle < 0) {
				angle += M_2PI;
			    }
			    hit2d[X] = -hit2d[X];
			    if (angle < rev->ang &&
				!((angle + M_PI < rev->ang || angle - M_PI > 0)
				  && rt_sketch_contains(rev->skt, hit2d))) {
				if (nhits >= MAX_HITS) return -1; /* too many hits */
				hitp = hits[nhits++];
				hitp->hit_point[X] = -hit2d[X];
				hitp->hit_point[Y] = hit2d[Y];
				hitp->hit_point[Z] = 0;
				VMOVE(hitp->hit_vpriv, hit1);
				if (ZERO(m)) {
				    hitp->hit_vpriv[Z] = 0.0;
				} else {
				    hitp->hit_vpriv[Z] = (hit2d[X]>0) ? 1.0/m : -1.0/m;
				}
				hitp->hit_magic = RT_HIT_MAGIC;
				hitp->hit_dist = k1;
				hitp->hit_surfno = i;
			    }

			    VJOIN1(hit2, pr, k2, vr);
			    angle = atan2(hit2[Y], hit2[X]);
			    if (-hit2d[X] < 0) {
				angle += M_PI;
			    } else if (angle < 0) {
				angle += M_2PI;
			    }
			    if (angle < rev->ang &&
				!((angle + M_PI < rev->ang || angle - M_PI > 0)
				  && rt_sketch_contains(rev->skt, hit2d))) {
				if (nhits >= MAX_HITS) return -1; /* too many hits */
				hitp = hits[nhits++];
				hitp->hit_point[X] = -hit2d[X];
				hitp->hit_point[Y] = hit2d[Y];
				hitp->hit_point[Z] = 0;
				VMOVE(hitp->hit_vpriv, hit2);
				if (ZERO(m)) {
				    hitp->hit_vpriv[Z] = 0.0;
				} else {
				    hitp->hit_vpriv[Z] = (hit2d[X]>0) ? 1.0/m : -1.0/m;
				}
				hitp->hit_magic = RT_HIT_MAGIC;
				hitp->hit_dist = k2;
				hitp->hit_surfno = i;
			    }
			}
		    }
		} else {

		    a = dir[X]*dir[X]/(aa*aa) - dir[Y]*dir[Y]/(bb*bb);
		    b = 2*(dir[X]*pt1[X]/(aa*aa) - dir[Y]*(pt1[Y]-h)/(bb*bb));
		    c = pt1[X]*pt1[X]/(aa*aa) - (pt1[Y]-h)*(pt1[Y]-h)/(bb*bb) - 1;
		    disc = b*b - (4.0 * a * c);
		    if (!NEAR_ZERO(a, RT_PCOEF_TOL)) {
			if (disc > 0) {
			    disc = sqrt(disc);
			    t1 =  (-b + disc) / (2.0 * a);
			    t2 =  (-b - disc) / (2.0 * a);
			    k1 = (pt1[Y]-pr[Z] + t1*dir[Y])/vr[Z];
			    k2 = (pt1[Y]-pr[Z] + t2*dir[Y])/vr[Z];

			    if (t1 > 0 && t1 < 1) {
				if (nhits >= MAX_HITS) return -1; /* too many hits */
				VJOIN1(hit1, pr, k1, vr);
				angle = atan2(hit1[Y], hit1[X]);
				V2JOIN1(hit2d, pt1, t1, dir);
				if (hit2d[X] < 0) {
				    angle += M_PI;
				} else if (angle < 0) {
				    angle += M_2PI;
				}
				hit2d[X] = -hit2d[X];
				if (angle < rev->ang) {
				    if ((angle + M_PI < rev->ang || angle - M_PI > 0)
					&& rt_sketch_contains(rev->skt, hit2d)) {
					/* overlap, so ignore it */
				    } else {
					hitp = hits[nhits++];
					hitp->hit_point[X] = -hit2d[X];
					hitp->hit_point[Y] = hit2d[Y];
					hitp->hit_point[Z] = 0;
					VMOVE(hitp->hit_vpriv, hit1);
					if (ZERO(m)) {
					    hitp->hit_vpriv[Z] = 0.0;
					} else {
					    hitp->hit_vpriv[Z] = (hit2d[X]>0) ? 1.0/m : -1.0/m;
					}
					hitp->hit_magic = RT_HIT_MAGIC;
					hitp->hit_dist = k1;
					hitp->hit_surfno = i;
				    }
				}
			    }
			    if (t2 > 0 && t2 < 1) {
				if (nhits >= MAX_HITS) return -1; /* too many hits */
				VJOIN1(hit2, pr, k2, vr);
				angle = atan2(hit2[Y], hit2[X]);
				V2JOIN1(hit2d, pt1, t2, dir);
				if (hit2d[X] < 0) {
				    angle += M_PI;
				} else if (angle < 0) {
				    angle += M_2PI;
				}
				hit2d[X] = -hit2d[X];
				if (angle < rev->ang) {
				    if ((angle + M_PI < rev->ang || angle - M_PI > 0)
					&& rt_sketch_contains(rev->skt, hit2d)) {
					/* overlap, so ignore it */
				    } else {
					hitp = hits[nhits++];
					hitp->hit_point[X] = -hit2d[X];
					hitp->hit_point[Y] = hit2d[Y];
					hitp->hit_point[Z] = 0;
					VMOVE(hitp->hit_vpriv, hit2);
					if (ZERO(m)) {
					    hitp->hit_vpriv[Z] = 0.0;
					} else {
					    hitp->hit_vpriv[Z] = (hit2d[X]>0) ? 1.0/m : -1.0/m;
					}
					hitp->hit_magic = RT_HIT_MAGIC;
					hitp->hit_dist = k2;
					hitp->hit_surfno = i;
				    }
				}
			    }
			}
		    } else if (!NEAR_ZERO(b, RT_PCOEF_TOL)) {
			t1 = -c / b;
			k1 = (pt1[Y]-pr[Z] + t1*dir[Y])/vr[Z];
			if (t1 > 0 && t1 < 1) {
			    if (nhits >= MAX_HITS) return -1; /* too many hits */

			    VJOIN1(hit1, pr, k1, vr);
			    angle = atan2(hit1[Y], hit1[X]);
			    V2JOIN1(hit2d, pt1, t1, dir);
			    if (hit2d[X] < 0) {
				angle += M_PI;
			    } else if (angle < 0) {
				angle += M_2PI;
			    }
			    hit2d[X] = -hit2d[X];
			    if (angle < rev->ang) {
				if ((angle + M_PI < rev->ang || angle - M_PI > 0)
				    && rt_sketch_contains(rev->skt, hit2d)) {
				    /* overlap, so ignore it */
				} else {
				    hitp = hits[nhits++];
				    hitp->hit_point[X] = -hit2d[X];
				    hitp->hit_point[Y] = hit2d[Y];
				    hitp->hit_point[Z] = 0;
				    VMOVE(hitp->hit_vpriv, hit1);
				    if (ZERO(m)) {
					hitp->hit_vpriv[Z] = 0.0;
				    } else {
					hitp->hit_vpriv[Z] = (hit2d[X]>0) ? 1.0/m : -1.0/m;
				    }
				    hitp->hit_magic = RT_HIT_MAGIC;
				    hitp->hit_dist = k1;
				    hitp->hit_surfno = i;
				}
			    }
			}
		    }
		}
		break;
	    case CURVE_CARC_MAGIC:
		/*
		  circle: (x-cx)^2 + (y-cy)^2 = cr^2
		  x = (1/2cx)y^2 + (-cy/cx)y + (1/2cx)(cy^2 + cx^2 - cr^2) + (1/2cx)(x^2)
		  x = f(y) + (1/2cx)x^2

		  hyperbola:
		  [(x-hx)/a]^2 - [(y-hy)/b]^2 = 1
		  x^2 = (a^2/b^2)y^2 + (-2*hy*a^2/b^2)y + (hy^2 * a^2/b^2) + a^2
		  x^2 = g(y)

		  plug the second equation into the first to get:
		  x = f(y) + (1/2cx)g(y)
		  then square that to get:
		  x^2 = {f(y) + (1/2cx)g(y)}^2 = g(y)
		  move all to one side to get:
		  0 = {f(y) + (1/2cx)g(y)}^2 - g(y)
		  this is a fourth order polynomial in y.
		*/
		{
		    bn_poly_t circleX;	/* f(y) */
		    bn_poly_t hypXsq;		/* g(y) */
		    bn_poly_t hypXsq_scaled;	/* g(y) / (2*cx) */
		    bn_poly_t sum;		/* f(y) + g(y)/(2cx) */
		    bn_poly_t sum_sq;		/* {f(y) + g(y)/(2cx)}^2 */
		    bn_poly_t answer;		/* {f(y) + g(y)/(2cx)}^2 - g(y) */
		    bn_complex_t roots[4];
		    int rootcnt;

		    fastf_t cx, cy, crsq = 0;	/* carc's (x, y) coords and radius^2 */
		    point2d_t center, radius;

		    /* calculate circle parameters */
		    csg = (struct carc_seg *)lng;

		    if (csg->radius <= 0.0) {
			/* full circle, "end" is center and "start" is on the circle */
			V2MOVE(center, rev->skt->verts[csg->end]);
			V2SUB2(radius, rev->skt->verts[csg->start], center);
			crsq = MAG2SQ(radius);
		    } else {
			point_t startpt, endpt, midpt;
			vect_t s_to_m;
			vect_t bisector;
			vect_t vertical;
			fastf_t distance;
			fastf_t magsq_s2m;

			VSET(vertical, 0, 0, 1);
			V2MOVE(startpt, rev->skt->verts[csg->start]);
			startpt[Z] = 0.0;
			V2MOVE(endpt, rev->skt->verts[csg->end]);
			endpt[Z] = 0.0;

			VBLEND2(midpt, 0.5, startpt, 0.5, endpt);
			VSUB2(s_to_m, midpt, startpt);
			VCROSS(bisector, vertical, s_to_m);
			VUNITIZE(bisector);
			magsq_s2m = MAGSQ(s_to_m);
			if (magsq_s2m > csg->radius*csg->radius) {
			    fastf_t max_radius;

			    max_radius = sqrt(magsq_s2m);
			    if (NEAR_EQUAL(max_radius, csg->radius, RT_LEN_TOL)) {
				csg->radius = max_radius;
			    } else {
				bu_log("Impossible radius for circular arc in extrusion (%s), is %g, cannot be more than %g!\n",
				       stp->st_dp->d_namep, csg->radius, sqrt(magsq_s2m));
				bu_log("Difference is %g\n", max_radius - csg->radius);
				return -1;
			    }
			}
			distance = sqrt(csg->radius*csg->radius - magsq_s2m);

			/* save arc center */
			if (csg->center_is_left) {
			    V2JOIN1(center, midpt, distance, bisector);
			} else {
			    V2JOIN1(center, midpt, -distance, bisector);
			}
		    }

		    cx = center[X];
		    cy = center[Y];

		    circleX.dgr = 2;
		    hypXsq.dgr = 2;
		    hypXsq_scaled.dgr = 2;
		    sum.dgr = 2;
		    sum_sq.dgr = 4;
		    answer.dgr = 4;

		    circleX.cf[0] = (cy*cy + cx*cx - crsq)/(2.0*cx);
		    circleX.cf[1] = -cy/cx;
		    circleX.cf[2] = 1/(2.0*cx);

		    hypXsq_scaled.cf[0] = hypXsq.cf[0] = aa*aa + h*h*aa*aa/(bb*bb);
		    hypXsq_scaled.cf[1] = hypXsq.cf[1] = -2.0*h*aa*aa/(bb*bb);
		    hypXsq_scaled.cf[2] = hypXsq.cf[2] = (aa*aa)/(bb*bb);

		    bn_poly_scale(&hypXsq_scaled, 1.0 / (2.0 * cx));
		    bn_poly_add(&sum, &hypXsq_scaled, &circleX);
		    bn_poly_mul(&sum_sq, &sum, &sum);
		    bn_poly_sub(&answer, &sum_sq, &hypXsq);

		    /* It is known that the equation is 4th order.  Therefore, if the
		     * root finder returns other than 4 roots, error.
		     */
		    rootcnt = rt_poly_roots(&answer, roots, stp->st_dp->d_namep);
		    if (rootcnt != 4) {
			if (rootcnt > 0) {
			    bu_log("tor:  rt_poly_roots() 4!=%d\n", rootcnt);
			    bn_pr_roots(stp->st_name, roots, rootcnt);
			} else if (rootcnt < 0) {
			    static int reported=0;
			    bu_log("The root solver failed to converge on a solution for %s\n", stp->st_dp->d_namep);
			    if (!reported) {
				VPRINT("while shooting from:\t", rp->r_pt);
				VPRINT("while shooting at:\t", rp->r_dir);
				bu_log("Additional torus convergence failure details will be suppressed.\n");
				reported=1;
			    }
			}
		    }

		    break;
		}
	    case CURVE_BEZIER_MAGIC:
		break;
	    case CURVE_NURB_MAGIC:
		break;
	    default:
		bu_log("rt_revolve_prep: ERROR: unrecognized segment type!\n");
		break;
	}

    }

    if (nhits%2 != 0) {
	bu_log("odd number of hits: %zu\n", nhits);
	for (i=0; i<nhits; i++) {
	    bu_log("\t(%6.2f, %6.2f)\t%6.2f\t%2d\n",
		   hits[i]->hit_point[X], hits[i]->hit_point[Y], hits[i]->hit_dist, hits[i]->hit_surfno);
	}
	return -1;
    }

    /* sort hitpoints (an arbitrary number of hits depending on sketch) */
    for (i=0; i<nhits; i+=2) {
	in = out = -1;
	for (j=0; j<nhits; j++) {
	    if (hits[j] == NULL) continue;
	    if (in == -1) {
		in = j;
		continue;
	    }
	    /* store shortest dist as 'in', second shortest as 'out' */
	    if (hits[j]->hit_dist <= hits[in]->hit_dist) {
		out = in;
		in = j;
	    } else if (out == -1 || hits[j]->hit_dist <= hits[out]->hit_dist) {
		out = j;
	    }
	}
	if (in == -1 || out == -1) {
	    bu_log("failed to find valid segment. nhits: %zu\n", nhits);
	    break;
	}

	if (ZERO(hits[in]->hit_dist - hits[out]->hit_dist)) {
	    hits[in] = NULL;
	    hits[out] = NULL;
	    continue;
	}

	RT_GET_SEG(segp, ap->a_resource);
	segp->seg_stp = stp;

	segp->seg_in = *hits[in];
	hits[in] = NULL;
	segp->seg_out = *hits[out];
	hits[out] = NULL;
	BU_LIST_INSERT(&(seghead->l), &(segp->l));
    }

    return nhits;
}
Beispiel #19
0
void kineticFeedback_impulsion(struct RUNPARAMS *param, struct CELL *cell,struct PART *curp, REAL aexp, int level, REAL E){
// ----------------------------------------------------------//
/// Inject an energy "E" in all cells of the oct contening
/// the cell "cell" on kinetic form, radially to the center
/// of the oct and uniformly in all cells
// ----------------------------------------------------------//

  REAL mtot_feedback = curp->mass* param->sn->ejecta_proportion;
  curp->mass -= mtot_feedback;
  struct OCT* oct = cell2oct(cell);

  int i;
//#define LOAD_FACTOR
#ifdef LOAD_FACTOR

  REAL load_factor=10;

  REAL local_rho_min=FLT_MAX;

  for(i=0;i<8;i++){
    struct CELL* curcell = &oct->cell[i];
    local_rho_min = FMIN(curcell->field.d,local_rho_min);
  }

  REAL lf = FMIN(load_factor*curp->mass,local_rho_min);

  mtot_feedback += lf;
  for(i=0;i<8;i++){
    struct CELL* curcell = &oct->cell[i];
    curcell->field.d -= lf/8.;
  }
#endif // LOAD_FACTOR

  for(i=0;i<8;i++){
    struct CELL* curcell = &oct->cell[i];
    REAL dv = POW(0.5,3*level);// curent volume

    REAL dir_x[]={-1., 1.,-1., 1.,-1., 1.,-1., 1.};// diagonal projection
    REAL dir_y[]={-1.,-1., 1., 1.,-1.,-1., 1., 1.};
    REAL dir_z[]={-1.,-1.,-1.,-1., 1., 1., 1., 1.};

    REAL E_e = E/8.; // uniform distribution
    REAL m_e = mtot_feedback/8.;

    REAL d_e = m_e/dv; // ejecta density
    REAL v_e = SQRT(2.*E_e/d_e);// ejecta velocity / particle
    REAL vxe = curp->vx + v_e*dir_x[i]/SQRT(3.); // ejecta velocity /grid
    REAL vye = curp->vy + v_e*dir_y[i]/SQRT(3.);
    REAL vze = curp->vz + v_e*dir_z[i]/SQRT(3.);

    REAL d_i = curcell->field.d; // initial density
    REAL vxi = curcell->field.u; // initial velocity
    REAL vyi = curcell->field.v;
    REAL vzi = curcell->field.w;

    curcell->field.d += d_e; //new density
    curcell->field.u = (vxi*d_i + vxe*d_e)/(d_i+d_e); //new velocity
    curcell->field.v = (vyi*d_i + vye*d_e)/(d_i+d_e);
    curcell->field.w = (vzi*d_i + vze*d_e)/(d_i+d_e);


    //Energy conservation
#ifdef DUAL_E
    struct Utype U; // conservative field structure
    W2U(&curcell->field, &U); // primitive to conservative
    U.eint*=1.+d_e/curcell->field.d; // compute new internal energy
    U2W(&U, &curcell->field); // back to primitive
#else
    curcell->field.p*=1.+d_e/curcell->field.d; // compute new internal energy
#endif

    getE(&curcell->field); //compute new total energy
    curcell->field.p=FMAX(curcell->field.p,PMIN);
    curcell->field.a=SQRT(GAMMA*curcell->field.p/curcell->field.d); // compute new sound speed
  }
}
Beispiel #20
0
/**************************************************************************
|
|     Method: FindNearestPointOfParallelLineSegments
|
|    Purpose: Given two lines (segments) that are known to be parallel, find
|             a representative point on each that is nearest to the other. If
|             the lines are considered to be finite then it is possible that there
|             is one true point on each line that is nearest to the other. This
|             code properly handles this case.
|
|             This is the most difficult line intersection case to handle, since
|             there is potentially a family, or locus of points on each line/segment
|             that are nearest to the other.
| Parameters: Input:
|             ------
|             A1x, A1y, A1z   - Coordinates of first defining point of line/segment A
|             A2x, A2y, A2z   - Coordinates of second defining point of line/segment A
|             Lax, Lay, Laz   - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
|             B1x, B1y, B1z   - Coordinates of first defining point of line/segment B
|             B2x, B2y, B2z   - Coordinates of second defining point of line/segment B
|             Lbx, Lby, Lbz   - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
|             infinite_lines  - set to true if lines are to be treated as infinite
|             epsilon_squared - tolerance value to be used to check for degenerate
|                               and parallel lines, and to check for true intersection.
|
|             Output:
|             -------
|             PointOnSegAx,   - Coordinates of the point on segment A that are nearest
|             PointOnSegAy,     to segment B. This corresponds to point C in the text.
|             PointOnSegAz
|             PointOnSegBx,   - Coordinates of the point on segment B that are nearest
|             PointOnSegBy,     to segment A. This corresponds to point D in the text.
|             PointOnSegBz

**************************************************************************/
void FindNearestPointOfParallelLineSegments(number A1x, number A1y, number A1z,
                                            number A2x, number A2y, number A2z,
                                            number Lax, number Lay, number Laz,
                                            number B1x, number B1y, number B1z,
                                            number B2x, number B2y, number B2z,
                                            number Lbx, number Lby, number Lbz,
                                            bool infinite_lines, number epsilon_squared,
                                            number &PointOnSegAx, number &PointOnSegAy, number &PointOnSegAz,
                                            number &PointOnSegBx, number &PointOnSegBy, number &PointOnSegBz)
{
  number s[2] = {0, 0};
  number temp;
  FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
                                true, epsilon_squared, PointOnSegAx, PointOnSegAy, PointOnSegAz, s[0]);
  if (true == infinite_lines)
  {
    PointOnSegBx = B1x;
    PointOnSegBy = B1y;
    PointOnSegBz = B1z;
  }
  else
  {
    number tp[3];
    FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B2x, B2y, B2z,
                                  true, epsilon_squared, tp[0], tp[1], tp[2], s[1]);
    if (s[0] < 0.f && s[1] < 0.f)
    {
      PointOnSegAx = A1x;
      PointOnSegAy = A1y;
      PointOnSegAz = A1z;
      if (s[0] < s[1])
      {
        PointOnSegBx = B2x;
        PointOnSegBy = B2y;
        PointOnSegBz = B2z;
      }
      else
      {
        PointOnSegBx = B1x;
        PointOnSegBy = B1y;
        PointOnSegBz = B1z;
      }
    }
    else if (s[0] > 1.f && s[1] > 1.f)
    {
      PointOnSegAx = A2x;
      PointOnSegAy = A2y;
      PointOnSegAz = A2z;
      if (s[0] < s[1])
      {
        PointOnSegBx = B1x;
        PointOnSegBy = B1y;
        PointOnSegBz = B1z;
      }
      else
      {
        PointOnSegBx = B2x;
        PointOnSegBy = B2y;
        PointOnSegBz = B2z;
      }
    }
    else
    {
      temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
      PointOnSegAx = (A1x + temp * Lax);
      PointOnSegAy = (A1y + temp * Lay);
      PointOnSegAz = (A1z + temp * Laz);
      FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz,
                                    PointOnSegAx, PointOnSegAy, PointOnSegAz, true,
                                    epsilon_squared, PointOnSegBx, PointOnSegBy, PointOnSegBz, temp);
    }
  }
}
Beispiel #21
0
int kineticFeedback_mixt(struct RUNPARAMS *param, struct CELL *cell,struct PART *curp, REAL aexp, int level, REAL E, REAL dt){
// ----------------------------------------------------------//
/// Inject an energy "E" in all cells of the oct contening
/// the cell "cell" on kinetic form, radially to the center
/// of the oct and uniformly in all cells
// ----------------------------------------------------------//

  //REAL mtot_feedback = curp->mass* param->sn->ejecta_proportion;
  //printf("injecting_old m=%e, e=%e\t",curp->mass* param->sn->ejecta_proportion,E);

  REAL mtot_feedback = get_mass(param,curp,aexp,dt);

  if (mtot_feedback==0){
    printf("WARNING null mass in kinetic feedback!\n");
    return 1;
  }

  printf("injecting_new m=%e, e=%e\n",mtot_feedback ,E);

  int i;
{
//#define LOAD_FACTOR
#ifdef LOAD_FACTOR

  REAL load_factor=10;
  REAL local_rho_min=FLT_MAX;

  for(i=0;i<8;i++){
    struct OCT* oct = cell2oct(cell);
    struct CELL* curcell = &oct->cell[i];
    local_rho_min = FMIN(curcell->field.d,local_rho_min);
  }

  REAL lf = FMIN(load_factor*curp->mass,local_rho_min);
  mtot_feedback += lf;

  for(i=0;i<8;i++){
    struct OCT* oct = cell2oct(cell);
    struct CELL* curcell = &oct->cell[i];
    curcell->field.d -= lf/8.;
  }
#endif // LOAD_FACTOR
}

  for(i=0;i<8;i++){
    struct OCT* oct = cell2oct(cell);
    struct CELL* curcell = &oct->cell[i];
    REAL dv = POW(0.5,3*level);// curent volume

    REAL dir_x[]={-1., 1.,-1., 1.,-1., 1.,-1., 1.};// diagonal projection
    REAL dir_y[]={-1.,-1., 1., 1.,-1.,-1., 1., 1.};
    REAL dir_z[]={-1.,-1.,-1.,-1., 1., 1., 1., 1.};

    REAL fact = 1.0;

    REAL m_e = mtot_feedback/8.;
    REAL d_e = m_e/dv; // ejecta density
//--------------------------------------------------------------------------//

    // kinetic energy injection
    REAL E_e = E/8. *fact;
    REAL v_e = SQRT(2.*E_e/curcell->field.d);

    //printf("field.d=%e\n",curcell->field.d);
    REAL sqrt3 = SQRT(3.);
    curcell->field.u += v_e*dir_x[i]/sqrt3;
    curcell->field.v += v_e*dir_y[i]/sqrt3;
    curcell->field.w += v_e*dir_z[i]/sqrt3;
//--------------------------------------------------------------------------//
/*
    // momentum injection
    E_e = E/8. *(1.-fact) ; // uniform distribution
    v_e = SQRT(2.*E_e/d_e);// ejecta velocity / particle

    REAL vxe = curp->vx + v_e*dir_x[i]/sqrt3; // ejecta velocity /grid
    REAL vye = curp->vy + v_e*dir_y[i]/sqrt3;
    REAL vze = curp->vz + v_e*dir_z[i]/sqrt3;

    REAL d_i = curcell->field.d; // initial density
    REAL vxi = curcell->field.u; // initial velocity
    REAL vyi = curcell->field.v;
    REAL vzi = curcell->field.w;

    curcell->field.u = (vxi*d_i + vxe*d_e)/(d_i+d_e); //new velocity
    curcell->field.v = (vyi*d_i + vye*d_e)/(d_i+d_e);
    curcell->field.w = (vzi*d_i + vze*d_e)/(d_i+d_e);
*/
//--------------------------------------------------------------------------//

    // mass conservation
    curp->mass       -= m_e;
    curcell->field.d += d_e; //new density

    //Energy conservation
#ifdef DUAL_E
    struct Utype U; // conservative field structure
    W2U(&curcell->field, &U); // primitive to conservative
    U.eint*=1.+d_e/curcell->field.d; // compute new internal energy
    U2W(&U, &curcell->field); // back to primitive
#else
    curcell->field.p*=1.+d_e/curcell->field.d; // compute new internal energy
#endif

    getE(&curcell->field); //compute new total energy
    curcell->field.p=FMAX(curcell->field.p,PMIN);
    curcell->field.a=SQRT(GAMMA*curcell->field.p/curcell->field.d); // compute new sound speed
  }
  return 0;
}
Beispiel #22
0
void Stars(struct RUNPARAMS *param, struct CPUINFO *cpu, REAL dt, REAL aexp, int level, int is){
// ----------------------------------------------------------//
/// The stars creation function.\n
/// Scan if cell is allowed to form star\n
/// If true, compute how many star are needed\n
/// and add them to the linked list\n
// ----------------------------------------------------------//

#ifdef GSLRAND
  const gsl_rng_type * T;
  gsl_rng * r;
  gsl_rng_env_setup();
  T = gsl_rng_default;
  r = gsl_rng_alloc (T);
  param->stars->rpoiss=r;
#endif

  if(cpu->rank == RANK_DISP) printf("STARS\n");
  setStarsState(param, cpu, level);

  REAL mmax = 0;
  REAL percentvol =0;

  int n_unit_stars = 0;
  int n_part_stars = 0;
  int nstarsmax_in_one_cell=0;
  int nstarsmin_in_one_cell=1e3;

  initThresh(param, aexp);
  REAL mstars_level = setmStar(param,level);

  int iOct;
  for(iOct=0; iOct<cpu->locNoct[level-1]; iOct++){
    struct OCT *curoct=cpu->octList[level-1][iOct];

    int icell;
    for(icell=0;icell<8;icell++) {
      struct CELL *curcell = &curoct->cell[icell];

      if( testCond(curcell, param, aexp, level) ) {
  REAL dx = POW(2.0,-level);
	REAL xc=curoct->x+( icell    & 1)*dx+dx*0.5;
	REAL yc=curoct->y+((icell>>1)& 1)*dx+dx*0.5;
	REAL zc=curoct->z+( icell>>2    )*dx+dx*0.5;

  percentvol += POW(dx,3);

	int N = getNstars2create(curcell, param, dt, aexp, level,mstars_level);
	nstarsmax_in_one_cell = FMAX(nstarsmax_in_one_cell,N);
	nstarsmin_in_one_cell = FMIN(nstarsmin_in_one_cell,N);

	if(N>0.2*param->npartmax){
    printf("You are about to create more stars than 20 percent of npartmax N=%d nmax=%d on proc %d\n",(int)N,param->npartmax,cpu->rank);
    if(N>param->npartmax){
      printf("You are about to create more stars than npartmax N=%d nmax=%d on proc %d--> ABORT\n",(int)N,param->npartmax,cpu->rank);
      abort();
    }
  }

	//	if(N) printf("N_Rho_Temp_Seuil_z\t%d\t%e\t%e\t%e\t%e\n", N, curcell->field.d, curcell->rfield.temp, param->stars->thresh,1.0/aexp - 1.0  );


#ifdef MULTIPLESTARS
  struct Wtype init_state=curcell->field;
	int ipart;
	for (ipart=0;ipart< N; ipart++){
    addStar(curcell, &init_state, level, xc, yc, zc, cpu, dt, param, aexp, is,n_part_stars++, mstars_level);
    n_unit_stars++;
  }
#else
#ifdef CONTINUOUSSTARS

  REAL m = getMstars2create(curcell, param, dt, aexp, level);
  //if(m>mstars_level)
  {
    addStar(curcell, &curcell->field, level, xc, yc, zc, cpu, dt, param, aexp, is,n_part_stars++, m);
    n_unit_stars++;
  }
#else
  if(N){
    addStar(curcell, &curcell->field, level, xc, yc, zc, cpu, dt, param, aexp, is,n_part_stars++, N*mstars_level);
    n_unit_stars++;
  }
#endif // CONTINUOUSSTARS
#endif // MULTIPLESTARS

/*
if (N){
printWtype(&init_state);
printWtype(&curcell->field);
}
*/
      }
      mmax = FMAX(curcell->field.d, mmax);
    }
  }

#ifdef WMPI
  MPI_Allreduce(MPI_IN_PLACE,&n_unit_stars,1,MPI_INT,MPI_SUM,cpu->comm);
  MPI_Allreduce(MPI_IN_PLACE,&n_part_stars,1,MPI_INT,MPI_SUM,cpu->comm);
  MPI_Allreduce(MPI_IN_PLACE,&mmax,1,MPI_REEL,MPI_MAX,cpu->comm);
  MPI_Allreduce(MPI_IN_PLACE,&percentvol,1,MPI_REEL,MPI_SUM,cpu->comm);
  MPI_Allreduce(MPI_IN_PLACE,&nstarsmax_in_one_cell,1,MPI_INT,MPI_MAX,cpu->comm);
  MPI_Allreduce(MPI_IN_PLACE,&nstarsmin_in_one_cell,1,MPI_INT,MPI_MIN,cpu->comm);
#endif

  param->stars->n += n_part_stars;
  if(cpu->rank==RANK_DISP) {
    printf("Mmax=%e\tthresh=%e\tvol=%e\n", mmax, param->stars->thresh, percentvol );
    if (n_unit_stars){
      printf("%d stars added in %d particles on level %d --> min=%d max=%d \n", n_unit_stars, n_part_stars, level,nstarsmin_in_one_cell,nstarsmax_in_one_cell);
      printf("%d stars particles in total\n",param->stars->n);
    }
    if(cpu->trigstar==0 && param->stars->n>0) printf("FIRST_STARS at z=%e\n",1./aexp-1.);
    if(param->stars->n>0) cpu->trigstar=1;
  }

#ifdef GSLRAND
  gsl_rng_free (r);
#endif

}
Beispiel #23
0
void miser(float (*func)(float []), float regn[], int ndim, unsigned long npts,
	float dith, float *ave, float *var)
{
	void ranpt(float pt[], float regn[], int n);
	float *regn_temp;
	unsigned long n,npre,nptl,nptr;
	int j,jb;
	float avel,varl;
	float fracl,fval;
	float rgl,rgm,rgr,s,sigl,siglb,sigr,sigrb;
	float sum,sumb,summ,summ2;
	float *fmaxl,*fmaxr,*fminl,*fminr;
	float *pt,*rmid;

	pt=vector(1,ndim);
	if (npts < MNBS) {
		summ=summ2=0.0;
		for (n=1;n<=npts;n++) {
			ranpt(pt,regn,ndim);
			fval=(*func)(pt);
			summ += fval;
			summ2 += fval * fval;
		}
		*ave=summ/npts;
		*var=FMAX(TINY,(summ2-summ*summ/npts)/(npts*npts));
	}
	else {
		rmid=vector(1,ndim);
		npre=LMAX((unsigned long)(npts*PFAC),MNPT);
		fmaxl=vector(1,ndim);
		fmaxr=vector(1,ndim);
		fminl=vector(1,ndim);
		fminr=vector(1,ndim);
		for (j=1;j<=ndim;j++) {
			iran=(iran*2661+36979) % 175000;
			s=SIGN(dith,(float)(iran-87500));
			rmid[j]=(0.5+s)*regn[j]+(0.5-s)*regn[ndim+j];
			fminl[j]=fminr[j]=BIG;
			fmaxl[j]=fmaxr[j] = -BIG;
		}
		for (n=1;n<=npre;n++) {
			ranpt(pt,regn,ndim);
			fval=(*func)(pt);
			for (j=1;j<=ndim;j++) {
				if (pt[j]<=rmid[j]) {
					fminl[j]=FMIN(fminl[j],fval);
					fmaxl[j]=FMAX(fmaxl[j],fval);
				}
				else {
					fminr[j]=FMIN(fminr[j],fval);
					fmaxr[j]=FMAX(fmaxr[j],fval);
				}
			}
		}
		sumb=BIG;
		jb=0;
		siglb=sigrb=1.0;
		for (j=1;j<=ndim;j++) {
			if (fmaxl[j] > fminl[j] && fmaxr[j] > fminr[j]) {
				sigl=FMAX(TINY,pow(fmaxl[j]-fminl[j],2.0/3.0));
				sigr=FMAX(TINY,pow(fmaxr[j]-fminr[j],2.0/3.0));
				sum=sigl+sigr;
				if (sum<=sumb) {
					sumb=sum;
					jb=j;
					siglb=sigl;
					sigrb=sigr;
				}
			}
		}
		free_vector(fminr,1,ndim);
		free_vector(fminl,1,ndim);
		free_vector(fmaxr,1,ndim);
		free_vector(fmaxl,1,ndim);
		if (!jb) jb=1+(ndim*iran)/175000;
		rgl=regn[jb];
		rgm=rmid[jb];
		rgr=regn[ndim+jb];
		fracl=fabs((rgm-rgl)/(rgr-rgl));
		nptl=(unsigned long)(MNPT+(npts-npre-2*MNPT)*fracl*siglb
			/(fracl*siglb+(1.0-fracl)*sigrb));
		nptr=npts-npre-nptl;
		regn_temp=vector(1,2*ndim);
		for (j=1;j<=ndim;j++) {
			regn_temp[j]=regn[j];
			regn_temp[ndim+j]=regn[ndim+j];
		}
		regn_temp[ndim+jb]=rmid[jb];
		miser(func,regn_temp,ndim,nptl,dith,&avel,&varl);
		regn_temp[jb]=rmid[jb];
		regn_temp[ndim+jb]=regn[ndim+jb];
		miser(func,regn_temp,ndim,nptr,dith,ave,var);
		free_vector(regn_temp,1,2*ndim);
		*ave=fracl*avel+(1-fracl)*(*ave);
		*var=fracl*fracl*varl+(1-fracl)*(1-fracl)*(*var);
		free_vector(rmid,1,ndim);
	}
	free_vector(pt,1,ndim);
}
void stifbs(float y[], float dydx[], int nv, float *xx, float htry, float eps,
	float yscal[], float *hdid, float *hnext,
	void (*derivs)(float, float [], float []))
{
	void jacobn(float x, float y[], float dfdx[], float **dfdy, int n);
	void simpr(float y[], float dydx[], float dfdx[], float **dfdy,
		int n, float xs, float htot, int nstep, float yout[],
		void (*derivs)(float, float [], float []));
	void pzextr(int iest, float xest, float yest[], float yz[], float dy[],
		int nv);
	int i,iq,k,kk,km;
	static int first=1,kmax,kopt,nvold = -1;
	static float epsold = -1.0,xnew;
	float eps1,errmax,fact,h,red,scale,work,wrkmin,xest;
	float *dfdx,**dfdy,*err,*yerr,*ysav,*yseq;
	static float a[IMAXX+1];
	static float alf[KMAXX+1][KMAXX+1];
	static int nseq[IMAXX+1]={0,2,6,10,14,22,34,50,70};
	int reduct,exitflag=0;

	d=matrix(1,nv,1,KMAXX);
	dfdx=vector(1,nv);
	dfdy=matrix(1,nv,1,nv);
	err=vector(1,KMAXX);
	x=vector(1,KMAXX);
	yerr=vector(1,nv);
	ysav=vector(1,nv);
	yseq=vector(1,nv);
	if(eps != epsold || nv != nvold) {
		*hnext = xnew = -1.0e29;
		eps1=SAFE1*eps;
		a[1]=nseq[1]+1;
		for (k=1;k<=KMAXX;k++) a[k+1]=a[k]+nseq[k+1];
		for (iq=2;iq<=KMAXX;iq++) {
			for (k=1;k<iq;k++)
				alf[k][iq]=pow(eps1,((a[k+1]-a[iq+1])/
					((a[iq+1]-a[1]+1.0)*(2*k+1))));
		}
		epsold=eps;
		nvold=nv;
		a[1] += nv;
		for (k=1;k<=KMAXX;k++) a[k+1]=a[k]+nseq[k+1];
		for (kopt=2;kopt<KMAXX;kopt++)
			if (a[kopt+1] > a[kopt]*alf[kopt-1][kopt]) break;
		kmax=kopt;
	}
	h=htry;
	for (i=1;i<=nv;i++) ysav[i]=y[i];
	jacobn(*xx,y,dfdx,dfdy,nv);
	if (*xx != xnew || h != (*hnext)) {
		first=1;
		kopt=kmax;
	}
	reduct=0;
	for (;;) {
		for (k=1;k<=kmax;k++) {
			xnew=(*xx)+h;
			if (xnew == (*xx)) nrerror("step size underflow in stifbs");
			simpr(ysav,dydx,dfdx,dfdy,nv,*xx,h,nseq[k],yseq,derivs);
			xest=SQR(h/nseq[k]);
			pzextr(k,xest,yseq,y,yerr,nv);
			if (k != 1) {
				errmax=TINY;
				for (i=1;i<=nv;i++) errmax=FMAX(errmax,fabs(yerr[i]/yscal[i]));
				errmax /= eps;
				km=k-1;
				err[km]=pow(errmax/SAFE1,1.0/(2*km+1));
			}
			if (k != 1 && (k >= kopt-1 || first)) {
				if (errmax < 1.0) {
					exitflag=1;
					break;
				}
				if (k == kmax || k == kopt+1) {
					red=SAFE2/err[km];
					break;
				}
				else if (k == kopt && alf[kopt-1][kopt] < err[km]) {
						red=1.0/err[km];
						break;
					}
				else if (kopt == kmax && alf[km][kmax-1] < err[km]) {
						red=alf[km][kmax-1]*SAFE2/err[km];
						break;
					}
				else if (alf[km][kopt] < err[km]) {
					red=alf[km][kopt-1]/err[km];
					break;
				}
			}
		}
		if (exitflag) break;
		red=FMIN(red,REDMIN);
		red=FMAX(red,REDMAX);
		h *= red;
		reduct=1;
	}
	*xx=xnew;
	*hdid=h;
	first=0;
	wrkmin=1.0e35;
	for (kk=1;kk<=km;kk++) {
		fact=FMAX(err[kk],SCALMX);
		work=fact*a[kk+1];
		if (work < wrkmin) {
			scale=fact;
			wrkmin=work;
			kopt=kk+1;
		}
	}
	*hnext=h/scale;
	if (kopt >= k && kopt != kmax && !reduct) {
		fact=FMAX(scale/alf[kopt-1][kopt],SCALMX);
		if (a[kopt+1]*fact <= wrkmin) {
			*hnext=h/fact;
			kopt++;
		}
	}
	free_vector(yseq,1,nv);
	free_vector(ysav,1,nv);
	free_vector(yerr,1,nv);
	free_vector(x,1,KMAXX);
	free_vector(err,1,KMAXX);
	free_matrix(dfdy,1,nv,1,nv);
	free_vector(dfdx,1,nv);
	free_matrix(d,1,nv,1,KMAXX);
}
Beispiel #25
0
void chemrad(struct RGRID *stencil, int nread, int stride, struct CPUINFO *cpu, REAL dxcur, REAL dtnew, struct RUNPARAMS *param, REAL aexporg, int chemonly)
{
  int i,icell,igrp;
  //int idloc=0;
  int nitcool=0;

  REAL hnu0=13.6*1.6022e-19,
    Cool,
    tcool,
    dtcool,
    tcool1,
    currentcool_t=0.,
    alpha,
    alphab,
    beta,
    tloc,
    xt,
    eintt,
    ai_tmp1=0.,
    et[NGRP],
    p[NGRP];

  REAL aexp;
  REAL ebkg[NGRP];
  REAL z=1./aexporg-1.;

  REAL c=param->clightorg*LIGHT_SPEED_IN_M_PER_S; 			// switch back to physical velocity m/s

  REAL hnu[NGRP];
  REAL alphae[NGRP];
  REAL alphai[NGRP];
  REAL factgrp[NGRP];

  for(igrp=0;igrp<NGRP;igrp++) {
    hnu[igrp]=param->atomic.hnu[igrp];
    alphae[igrp]=param->atomic.alphae[igrp];
    alphai[igrp]=param->atomic.alphai[igrp];
    factgrp[igrp]=param->atomic.factgrp[igrp];
  }

#ifdef S_X
  REAL E0overI[NGRP];
  REAL N2[NGRP];
  REAL F2[NGRP];
#endif

#define BLOCKCOOL 1 // KEPT FROM CUDATON FOR SIMPLICITY
#define idloc3 0 // KEPT FROM CUDATON FOR SIMPLICITY

  REAL
    egyloc[BLOCKCOOL*NGRP],
    floc[3*BLOCKCOOL*NGRP],
    srcloc[BLOCKCOOL*NGRP],
    x0[BLOCKCOOL],
    nH[BLOCKCOOL],
    eint[BLOCKCOOL];


  REAL dt=dtnew*param->unit.unit_t*POW(aexporg,2);

  REAL emin;
  struct Rtype R;
  REAL fudgecool=param->fudgecool;
  int ncvgcool=param->ncvgcool;
  REAL E0;
#ifdef SCHAYE
  REAL navg=(param->cosmo->ob/param->cosmo->om)/(PROTON_MASS*MOLECULAR_MU)*param->unit.unit_d;
#endif
  REAL xorg;
  for(i=0;i<nread;i++){  // we scan the octs
    for(icell=0;icell<8;icell++){ // we scan the cells

      if(stencil[i].oct[6].cell[icell].split) continue; // we dont treat split cells

      memcpy(&R,&stencil[i].New.cell[icell].rfieldnew,sizeof(struct Rtype));// We get the local physical quantities after transport update

#ifdef HOMOSOURCE
      // we override the value with the homogeneous source density
      R.src=param->bkg;
#endif


	  //if(eint[idloc]!=E0) printf("1!\n");
	  /// ==================== UV Background
#ifdef UVBKG
	  if(NGRP>1) printf("WARNING BAD BEHAVIOR FOR BKG with NGRP>1 !\n");
	  //for(igrp=0;igrp<NGRP;igrp++) ebkg[igrp]=3.6*(z<3?1.:4./(1+z))  ;  // Katz simple model

	  // Poor FIT to Haardt & MAdau 2012
  /*
	  for(igrp=0;igrp<NGRP;igrp++){
	    REAL amp=1.2e-16,sig=1.,zavg=2,mz=1e-18,pz=1.2e-17;
	    ebkg[igrp]=amp/(sig*SQRT(2*M_PI))*exp(-POW((z-zavg),2)/(2.*POW(sig,2)))+mz*z+pz; // comoving photons/s/m3
	  }
  */

#else
	  for(igrp=0;igrp<NGRP;igrp++) ebkg[igrp]=0.;
#endif

      // switch to physical units, chemistry remains unchanged with and without cosmo
      for (igrp=0;igrp<NGRP;igrp++)
	{
	  egyloc[idloc+igrp*BLOCKCOOL]   =R.e[igrp]/(aexporg*aexporg*aexporg)*param->unit.unit_N;//+ebkg[igrp];
	  floc[0+idloc3+igrp*BLOCKCOOL*3]=R.fx[igrp]/POW(aexporg,4)*param->unit.unit_l/param->unit.unit_t*param->unit.unit_N;
	  floc[1+idloc3+igrp*BLOCKCOOL*3]=R.fy[igrp]/POW(aexporg,4)*param->unit.unit_l/param->unit.unit_t*param->unit.unit_N;
	  floc[2+idloc3+igrp*BLOCKCOOL*3]=R.fz[igrp]/POW(aexporg,4)*param->unit.unit_l/param->unit.unit_t*param->unit.unit_N;
	}


      x0[idloc]=R.nhplus/R.nh;
      xorg= x0[idloc];
      nH[idloc]=R.nh/(aexporg*aexporg*aexporg)*param->unit.unit_N;


      eint[idloc]=R.eint/POW(aexporg,5)*param->unit.unit_n*param->unit.unit_d*POW(param->unit.unit_v,2);
      emin=PMIN/(GAMMA-1.)/POW(aexporg,5)*param->unit.unit_n*param->unit.unit_d*POW(param->unit.unit_v,2); // physical minimal pressure

      for (igrp=0;igrp<NGRP;igrp++){
      srcloc[idloc+igrp*BLOCKCOOL]=(R.src[igrp]*param->unit.unit_N/param->unit.unit_t/(aexporg*aexporg))/POW(aexporg,3); //phot/s/dv (physique)
      }
// R.src phot/unit_t/unit_dv (comobile)
      REAL eorg=eint[idloc];
      REAL etorg=egyloc[idloc];
      REAL torg=eint[idloc]/(1.5*nH[idloc]*KBOLTZ*(1.+x0[idloc]));

      //if(srcloc[0]>0) 	printf("nh=%e %e %e %e\n",R.nh,R.e[0],eint[idloc],3[idloc]);

      // at this stage we are ready to do the calculations

      // DEALING WITH CLUMPING ----------------------
#ifdef WCLUMP
      REAL CLUMPF2=FMIN(FMAX(POW(nH[idloc]/6.,0.7),1.),40.);
      REAL CLUMPI=1.;
#else
      REAL CLUMPF2=1.;
      REAL CLUMPI=1.;
#endif


      for(igrp=0;igrp<NGRP;igrp++)
	{
	  alphai[igrp] *= CLUMPI;
	  alphae[igrp] *= CLUMPI;
	}

      // -------------------------------------------------

      /// local cooling loop -------------------------------
      aexp=aexporg;
      fudgecool=param->fudgecool;
      currentcool_t=0.;
      nitcool=0.;
      REAL da;
      //printf("cpu=%d fudge=%e ncv=%d currentcool_t=%e dt=%e\n",cpu->rank,param->fudgecool,ncvgcool,currentcool_t,dt);

      // local cooling loop -------------------------------
      while(currentcool_t<dt)
	{


	  /// Cosmological Adiabatic expansion effects ==============
#ifdef TESTCOSMO
	  REAL hubblet=param->cosmo->H0*SQRT(param->cosmo->om/aexp+param->cosmo->ov*(aexp*aexp))/aexp*(1e3/(1e6*PARSEC)); // s-1 // SOMETHING TO CHECK HERE
#else
	  REAL hubblet=0.;
#endif


	  //if(eint[idloc]!=E0) printf("2!\n");
	  tloc=eint[idloc]/(1.5*nH[idloc]*KBOLTZ*(1.+x0[idloc]));

	  //== Getting a timestep
	  cuCompCooling(tloc,x0[idloc],nH[idloc],&Cool,&tcool1,aexp,CLUMPF2);
	  ai_tmp1=0.;

	  //if(eint[idloc]!=E0) printf("3!\n");

	  if(fudgecool<1e-20){
	    printf("eint=%e(%e<%e) nH=%e x0=%e(%e) T=%e(%e) N=%e(%e)\n",eint[idloc],eorg,emin,nH[idloc],x0[idloc],xorg,tloc,torg,et[0],etorg);
	    if(fudgecool<1e-20) abort();
	  }

	  for (igrp=0;igrp<NGRP;igrp++) ai_tmp1 += ((alphae[igrp])*hnu[igrp]-(alphai[igrp])*hnu0)*egyloc[idloc+igrp*BLOCKCOOL];
	  tcool=FABS(eint[idloc]/(nH[idloc]*(1.0-x0[idloc])*ai_tmp1*(!chemonly)-Cool));
	  ai_tmp1=0.;
	  dtcool=FMIN(fudgecool*tcool,dt-currentcool_t);

	  alpha=cucompute_alpha_a(tloc,1.,1.)*CLUMPF2;
	  alphab=cucompute_alpha_b(tloc,1.,1.)*CLUMPF2;
	  beta=cucompute_beta(tloc,1.,1.)*CLUMPF2;

	  //== Update

	  // ABSORPTION
	  int test = 0;
	  REAL factotsa[NGRP];
	  for(igrp=0;igrp<NGRP;igrp++)
	      {
#ifdef OTSA
		factotsa[igrp]=0;
		alpha=alphab; // recombination is limited to non ground state levels
#else
		factotsa[igrp]=(igrp==0);
#endif

		ai_tmp1 = alphai[igrp];
		if(chemonly){
		  et[igrp]=egyloc[idloc+igrp*BLOCKCOOL];
		}
		else{
		  et[igrp]=((alpha-alphab)*x0[idloc]*x0[idloc]*nH[idloc]*nH[idloc]*dtcool*factotsa[igrp]+egyloc[idloc+igrp*BLOCKCOOL]+srcloc[idloc+igrp*BLOCKCOOL]*dtcool*factgrp[igrp])/(1.+dtcool*(ai_tmp1*(1.-x0[idloc])*nH[idloc]));
		}

		if((et[igrp]<0)||(isnan(et[igrp]))){
		  test=1;
		  //printf("eint=%e nH=%e x0=%e T=%e N=%e\n",eint[idloc],nH[idloc],x0[idloc],tloc,et[0]);
		}
		p[igrp]=(1.+(alphai[igrp]*nH[idloc]*(1-x0[idloc]))*dtcool);
	      }

	  ai_tmp1=0.;


	  if(test)
	    {
	      fudgecool=fudgecool/10.;
	      continue;
	    }

	  // IONISATION
#ifndef S_X
#ifdef SEMI_IMPLICIT
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += alphai[igrp]*et[igrp]*(!chemonly);}
#else
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += alphai[igrp]*egyloc[idloc+igrp*BLOCKCOOL]*(!chemonly);}
#endif
#else
	  N2[0]=1.0;
	  REAL pp=(1.-POW(x0[idloc],0.4092));
	  if(pp<0.) pp=0.;

	  for(igrp=1;igrp<NGRP;igrp++){
	    N2[igrp]=1.0+0.3908*POW(pp,1.7592)*E0overI[igrp];
	    if(N2[igrp]<1.0) N2[igrp]=1.0;
	  }
#ifdef SEMI_IMPLICIT
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += alphai[igrp]*et[igrp]*N2[igrp]*(!chemonly);}
#else
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += alphai[igrp]*egyloc[idloc+igrp*BLOCKCOOL]*N2[igrp]*(!chemonly);}
#endif
#endif

	  xt=1.-(alpha*x0[idloc]*x0[idloc]*nH[idloc]*dtcool+(1. -x0[idloc]))/(1.+dtcool*(beta*x0[idloc]*nH[idloc]+ai_tmp1));
	  ai_tmp1=0.;


	  if(((xt>1.)||(xt<0.))||(isnan(xt)))
 	    {
	      //printf("XION ERR eintt=%e xt=%e et=%e\n",eintt,xt,et[0]);
	      fudgecool/=10.;
	      continue;
	    }

#ifdef SEMI_IMPLICIT
	  cuCompCooling(tloc,xt,nH[idloc],&Cool,&tcool1,aexp,CLUMPF2);
#else
	  cuCompCooling(tloc,x0[idloc],nH[idloc],&Cool,&tcool1,aexp,CLUMPF2);
#endif

#ifdef COOLING
	  // HEATING + COOLING

	  int compcool=1; // do we need to compute the cooling ?

#ifdef SCHAYE
	  if((nH[idloc]>1e6)&&(R.nh>(param->stars->overdensity_cond*navg))){
	    REAL tlocs;
	    tlocs=eintt/(1.5*nH[idloc]*KBOLTZ*(1.+xt));
	    if(tlocs<1e5){
	      eintt=(1.08e9*KBOLTZ)*POW(nH[idloc]/1e5,4./3.)/(GAMMA-1)/FSCHAYE; // polytropic EOS
	      compcool=0.; // cancel cooling calculation
	      fudgecool=FMIN(fudgecool*1.5,param->fudgecool);
	    }
	  }
#endif // SCHAYE

	  if(compcool){
	    REAL SN = 0;
#ifdef SUPERNOVAE
	    SN 	 = R.snfb;
	    if (R.snfb) Cool = 0; // Stop the cooling if supernovae
	    if (R.snfb) printf("dE\t%e\tE0\t%e\tdtcool\t%e\t",R.snfb*dtcool,eintt, dtcool);
#endif

#ifndef S_X
#ifdef SEMI_IMPLICIT
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += et[igrp]*(alphae[igrp]*hnu[igrp]-(alphai[igrp]*hnu0))*(!chemonly);}
	  eintt=(eint[idloc]+ dtcool*(nH[idloc]*(1.-xt)*(ai_tmp1)-Cool+SN));
// 	  if (R.snfb) printf("E0\t%e\n",eintt);
#else
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += egyloc[idloc+igrp*BLOCKCOOL]*(alphae[igrp]*hnu[igrp]-(alphai[igrp]*hnu0))*(!chemonly);}
	  eintt=(eint[idloc]+dtcool*(nH[idloc]*(1.-x0[idloc])*(ai_tmp1)-Cool+SN));
#endif //SEMI


#else
	  //===================================== X RAYS ==============================
	  REAL pp2;
	  F2[0]=1.0;

	  //if(eint[idloc]!=E0) printf("7!\n");

#ifdef SEMI_IMPLICIT
	  pp2=1.0-POW(xt,0.2663);
#else
	  pp2=1.0-POW(x0[idloc],0.2663);
#endif
	  if(pp2<0.) pp2=0.;
	  for(igrp=1;igrp<NGRP;igrp++){
	    F2[igrp]=1.0;
	    F2[igrp]=0.9971*(1.0-POW(pp2,1.3163));

	    if(F2[igrp]>1.0) F2[igrp]=1.0;
	    if(F2[igrp]<0.0) F2[igrp]=0.0;
	  }

#ifdef SEMI_IMPLICIT
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += et[igrp]*(alphae[igrp]*hnu[igrp]-(alphai[igrp]*hnu0))*F2[igrp]*(!chemonly);}
	  eintt=(eint[idloc]+dtcool*(nH[idloc]*(1.-xt)*(ai_tmp1)-Cool+SN));
#else
	  for(igrp=0;igrp<NGRP;igrp++) {ai_tmp1 += egyloc[idloc+igrp*BLOCKCOOL]*(alphae[igrp]*hnu[igrp]-(alphai[igrp]*hnu0))*F2[igrp]*(!chemonly);}
	  eintt=(eint[idloc]+dtcool*(nH[idloc]*(1.-x0[idloc])*(ai_tmp1)-Cool+SN));
#endif
	  //================================================================================
#endif //S_X

	  if(eintt<0.)
 	    {
	      //printf("E NEG eintt=%e xt=%e et=%e\n",eintt,xt,et[0]);
	      fudgecool=fudgecool/10.;
	      continue;
	    }

	  if(FABS(eintt-eint[idloc])>FRAC_VAR*eint[idloc])
	    {
	      //	      if(srcloc[idloc]==0.){
	      //printf("DELTA E eintt=%e xt=%e et=%e\n",eintt,xt,et[0]);
	      fudgecool=fudgecool/10.;

	      continue;
	      //}
	    }
  	  else{
 	    fudgecool=FMIN(fudgecool*1.5,param->fudgecool);
	  }

	  ai_tmp1=0;


	  eintt=FMAX(emin,eintt);
 	  }

#else
	  eintt=eint[idloc];
#endif

	  // inner update
	  REAL aold=aexp;
#ifdef TESTCOSMO
	  da=hubblet*dtcool*aexp;
	  aexp+=da;
#endif

	  for(igrp =0;igrp<NGRP;igrp++)
	    {
	      egyloc[idloc+igrp*BLOCKCOOL]=et[igrp]*POW(aold/aexp,3);
	      if(!chemonly){
		floc[0+idloc3+igrp*BLOCKCOOL*3]=floc[0+idloc3+igrp*BLOCKCOOL*3]/p[igrp]*POW(aold/aexp,4);
		floc[1+idloc3+igrp*BLOCKCOOL*3]=floc[1+idloc3+igrp*BLOCKCOOL*3]/p[igrp]*POW(aold/aexp,4);
		floc[2+idloc3+igrp*BLOCKCOOL*3]=floc[2+idloc3+igrp*BLOCKCOOL*3]/p[igrp]*POW(aold/aexp,4);
	      }
	    }

	  x0[idloc]=xt;
	  //printf("xt=%e\n",xt);
#ifdef COOLING
	  eint[idloc]=eintt*POW(aold/aexp,5);
#endif

	  currentcool_t+=dtcool;
	  fudgecool=param->fudgecool;
	  nitcool++;
	  if((nitcool==ncvgcool)&&(ncvgcool!=0)) break;
	}

      /// ====================== End of the cooling loop

      //aexp=aexporg;
      // FIlling the rad structure to send it back

      if(!chemonly){
	for(igrp=0;igrp<NGRP;igrp++)
	  {
	    R.e[igrp]=FMAX(egyloc[idloc+igrp*BLOCKCOOL]*POW(aexp,3),EMIN*factgrp[igrp])/param->unit.unit_N;
	    R.fx[igrp]=floc[0+idloc3+igrp*BLOCKCOOL*3]*POW(aexp,4)/param->unit.unit_l*param->unit.unit_t/param->unit.unit_N;
	    R.fy[igrp]=floc[1+idloc3+igrp*BLOCKCOOL*3]*POW(aexp,4)/param->unit.unit_l*param->unit.unit_t/param->unit.unit_N;
	    R.fz[igrp]=floc[2+idloc3+igrp*BLOCKCOOL*3]*POW(aexp,4)/param->unit.unit_l*param->unit.unit_t/param->unit.unit_N;
	  }
      }

      R.nhplus=x0[idloc]*R.nh;
      R.eint=eint[idloc]*POW(aexp,5)/param->unit.unit_n/param->unit.unit_d/POW(param->unit.unit_v,2);
      E2T(&R,aexp,param);
      memcpy(&stencil[i].New.cell[icell].rfieldnew,&R,sizeof(struct Rtype));

    }
  }
}
Beispiel #26
0
static void
generate_special_channels(const stp_vars_t *v)
{
  stpi_channel_group_t *cg = get_channel_group(v);
  int i, j;
  const unsigned short *input_cache = NULL;
  const unsigned short *output_cache = NULL;
  const unsigned short *input;
  unsigned short *output;
  int offset;
  int outbytes;
  if (!cg)
    return;
  input = cg->input_data;
  output = cg->multi_tmp;
  offset = (cg->black_channel >= 0 ? 0 : -1);
  outbytes = cg->aux_output_channels * sizeof(unsigned short);
  for (i = 0; i < cg->width;
       input += cg->input_channels, output += cg->aux_output_channels, i++)
    {
      if (input_cache && short_eq(input_cache, input, cg->input_channels))
	{
	  memcpy(output, output_cache, outbytes);
	}
      else
	{
	  int c = input[STP_ECOLOR_C + offset];
	  int m = input[STP_ECOLOR_M + offset];
	  int y = input[STP_ECOLOR_Y + offset];
	  int min = FMIN(c, FMIN(m, y));
	  int max = FMAX(c, FMAX(m, y));
	  if (max > min)	/* Otherwise it's gray, and we don't care */
	    {
	      double hue;
	      /*
	       * We're only interested in converting color components
	       * to special inks.  We want to compute the hue and
	       * luminosity to determine what we want to convert.
	       * Since we're eliminating all grayscale component, the
	       * computations become simpler.
	       */
	      c -= min;
	      m -= min;
	      y -= min;
	      max -= min;
	      if (offset == 0)
		output[STP_ECOLOR_K] = input[STP_ECOLOR_K];
	      hue = compute_hue(c, m, y, max);
	      for (j = 1; j < cg->aux_output_channels - offset; j++)
		{
		  stpi_channel_t *ch = &(cg->c[j]);
		  if (ch->hue_map)
		    output[j + offset] =
		      max * interpolate_value(ch->hue_map,
					      hue * ch->h_count / 6.0);
		  else
		    output[j + offset] = 0;
		}
	      output[STP_ECOLOR_C + offset] += min;
	      output[STP_ECOLOR_M + offset] += min;
	      output[STP_ECOLOR_Y + offset] += min;
	    }
	  else
	    {
	      for (j = 0; j < 4 + offset; j++)
		output[j] = input[j];
	      for (j = 4 + offset; j < cg->aux_output_channels; j++)
		output[j] = 0;
	    }
	}
      input_cache = input;
      output_cache = output;
    }
}
Beispiel #27
0
int main (int argc, char **argv)
{
  int n1,n2,n3,n1s,n2s,n3s,n1c,n2c,n3c,i1,i2,i3,i1c,i2c,i3c,
    i1beg,i1end,i2beg,i2end,i3beg,i3end,i1step,i2step,i3step,
    n1tic,n2tic,n3tic,grid1,grid2,grid3,nz,iz,
    verbose,faces,hls,bps,style=SEISMIC,bbox[4],
    legend,ugrid=SOLID,lstyle=VERTLEFT,lz,lbegsup=0,lendsup=0,ln=256,
    lbbox[4];
  float d1,d2,d3,d1s,d2s,d3s,f1,f2,f3,size1,size2,size3,xbox,ybox,angle,
    x1min,x1max,x2min,x2max,x3min,x3max,
    x1beg,x1end,x2beg,x2end,x3beg,x3end,
    d1num,f1num,d2num,f2num,d3num,f3num,
    p1beg,p1end,p2beg,p2end,p3beg,p3end,
    clip,bclip,wclip,perc,bperc,wperc,
    zscale,zoffset,zi,labelsize,titlesize,
    *z,*zfront,*zside,*ztop,*temp,matrix[6],colors[3][2],
    lwidth,lheight,lx,ly,lbeg,lend,
    lmin=(float)FLT_MAX,lmax=(float)-FLT_MAX,
    ldnum,lfnum,ld,lf=0,labmatrix[6];
  unsigned char *czfront,*czside,*cztop,
    *szfront,*szside,*sztop,*czp,
    *data_legend=NULL;
  char *label1="",*label2="",*label3="",*title="",
    *labelfont="Helvetica",*titlefont="Helvetica-Bold",
    *grid1s="none",*grid2s="none",*grid3s="none",
    *titlecolor="black",*axescolor="black",*gridcolor="black",
    *frontf,*sidef,*topf,
    *units="", *legendfont="times_roman10", *lstyles="vertleft",*lgrids="none";
  FILE *infp=stdin,*frontfp,*sidefp,*topfp;
  
  /* initialize getpar */
  initargs(argc,argv);
  requestdoc(1);
  
  /* get parameters describing 1st dimension sampling */
  if (!getparint("n1",&n1)) err("must specify n1!\n");
  if (!getparfloat("d1",&d1)) d1 = 1.0;
  if (!getparfloat("f1",&f1)) f1 = 0.0;
  
  /* get parameters describing 2nd dimension sampling */
  if (!getparint("n2",&n2)) err("must specify n2!\n");
  if (!getparfloat("d2",&d2)) d2 = 1.0;
  if (!getparfloat("f2",&f2)) f2 = 0.0;
  
  /* get parameters describing 3rd dimension sampling */
  if (!getparint("n3",&n3)) err("must specify n3!\n");
  if (!getparfloat("d3",&d3)) d3 = 1.0;
  if (!getparfloat("f3",&f3)) f3 = 0.0;
  
  /* determine input type */
  if (!getparint("faces",&faces)) faces = 0;
  
  /* read color parameters */
  bps = 8;
  hls = 0;
  colors[R][0] = colors[G][0] = colors[B][0] = 0.0;
  colors[R][1] = colors[G][1] = colors[B][1] = 1.0;
  if (countparval("brgb") || countparval("wrgb")) {
    float brgb[3],wrgb[3];
    brgb[R] = brgb[G] = brgb[B] = 0.0;
    wrgb[R] = wrgb[G] = wrgb[B] = 1.0;
    getparfloat("brgb",&brgb[0]);
    getparfloat("wrgb",&wrgb[0]);
    brgb[R] = MAX(0.0,MIN(1.0,brgb[R]));
    wrgb[R] = MAX(0.0,MIN(1.0,wrgb[R]));
    brgb[G] = MAX(0.0,MIN(1.0,brgb[G]));
    wrgb[G] = MAX(0.0,MIN(1.0,wrgb[G]));
    brgb[B] = MAX(0.0,MIN(1.0,brgb[B]));
    wrgb[B] = MAX(0.0,MIN(1.0,wrgb[B]));
    colors[R][0] = brgb[R];  colors[R][1] = wrgb[R];
    colors[G][0] = brgb[G];  colors[G][1] = wrgb[G];
    colors[B][0] = brgb[B];  colors[B][1] = wrgb[B];
		if (!getparint("bps",&bps)) bps = 12;
		if (bps!=12 && bps!=24)
		  err("bps must equal 12 or 24 for color plots!\n");
  } else if (countparval("bhls") || countparval("whls")) {
    float bhls[3],whls[3];
    hls = 1;
    bhls[H] = whls[H] = 0.0;
    bhls[L] = 0.0;  whls[L] = 1.0;
    bhls[S] = whls[S] = 0.0;
    getparfloat("bhls",&bhls[0]);
    getparfloat("whls",&whls[0]);
    bhls[L] = MAX(0.0,MIN(1.0,bhls[L]));
    whls[L] = MAX(0.0,MIN(1.0,whls[L]));
    bhls[S] = MAX(0.0,MIN(1.0,bhls[S]));
    whls[S] = MAX(0.0,MIN(1.0,whls[S]));
    colors[H][0] = bhls[0];  colors[H][1] = whls[0];
    colors[L][0] = bhls[1];  colors[L][1] = whls[1];
    colors[S][0] = bhls[2];  colors[S][1] = whls[2];
    if (!getparint("bps",&bps)) bps = 12;
    if (bps!=12 && bps!=24)
      err("bps must equal 12 or 24 for color plots!\n");
  }
  
  /* allocate space */
  nz = n1*n2+n1*n3+n2*n3;
  z = ealloc1float(nz);
  zfront = z;
  zside = zfront+n1*n2;
  ztop = zside+n1*n3;
  
  /* read data */
  if (getparstring("front",&frontf)
      && getparstring("side",&sidef)
      && getparstring("top",&topf)) {
    
    /* read face files */
    if ((frontfp = fopen(frontf,"r")) == NULL)
      err("error opening front file!\n");
    if (fread(zfront,sizeof(float),n1*n2,frontfp)!=n1*n2)
      err("error reading front file!\n");
    if ((sidefp = fopen(sidef,"r")) == NULL)
      err("error opening side file!\n");
    if (fread(zside,sizeof(float),n1*n3,sidefp)!=n1*n3)
      err("error reading side file!\n");
    if ((topfp = fopen(topf,"r")) == NULL)
      err("error opening top file!\n");
    if (fread(ztop,sizeof(float),n2*n3,topfp)!=n2*n3)
      err("error reading top file!\n");
    
  } else if (getparstring("front",&frontf)
	     || getparstring("side",&sidef)
	     || getparstring("top",&topf)) {
    
    err("must specify all or none of face, side, and top!\n");
    
  } else if (faces) {
    /* read faces from stdin */
    if (fread(zfront,sizeof(float),n1*n2,infp)!=n1*n2)
      err("error reading front from input!\n");
		if (fread(zside,sizeof(float),n1*n3, infp)!=n1*n3)
		  err("error reading side from input!\n");
		if (fread(ztop,sizeof(float),n2*n3, infp)!=n2*n3)
		  err("error reading top from input!\n");
  } else {
    /* read cube from stdin, pick off faces */
    temp = ealloc1float(n1);
    for (i3=0; i3<n3; i3++) {
      for (i2=0; i2<n2; i2++) {
	if (fread(temp,sizeof(float),n1,infp)!=n1)
	  err("error reading cube from input!\n");
	if (i3==0) 
	  for (i1=0; i1<n1; i1++)
	    zfront[i1+i2*n1] = temp[i1];
	if (i2==n2-1)
	  for (i1=0; i1<n1; i1++)
	    zside[i1+i3*n1] = temp[i1];
	ztop[i2+i3*n2] = temp[0];
      }
    }
    free1float(temp);
  }
  
  /* if necessary, determine clips from percentiles */
  if (getparfloat("clip",&clip)) {
    bclip = clip;
    wclip = -clip;
  }
  if ((!getparfloat("bclip",&bclip) || !getparfloat("wclip",&wclip)) &&
      !getparfloat("clip",&clip)) {
    perc = 100.0;  getparfloat("perc",&perc);
    temp = ealloc1float(nz);
    for (iz=0; iz<nz; iz++)
      temp[iz] = z[iz];
    if (!getparfloat("bclip",&bclip)) {
      bperc = perc;	getparfloat("bperc",&bperc);
      iz = (nz*bperc/100.0);
      if (iz<0) iz = 0;
      if (iz>nz-1) iz = nz-1;
      qkfind(iz,nz,temp);
      bclip = temp[iz];
    }
    if (!getparfloat("wclip",&wclip)) {
      wperc = 100.0-perc;  getparfloat("wperc",&wperc);
      iz = (nz*wperc/100.0);
      if (iz<0) iz = 0;
      if (iz>nz-1) iz = nz-1;
      qkfind(iz,nz,temp);
      wclip = temp[iz];
    }
    free1float(temp);
  }
  if (!getparint("verbose",&verbose)) verbose = 1;
  if (verbose) warn("bclip=%g wclip=%g",bclip,wclip);
  
  /* get scaled sampling intervals */
  if (!getparfloat("d1s",&d1s)) d1s = 1.0;
  if (!getparfloat("d2s",&d2s)) d2s = 1.0;
  if (!getparfloat("d3s",&d3s)) d3s = 1.0;
  d1s = fabs(d1s);  d1s *= d1;
  d2s = fabs(d2s);  d2s *= d2;
  d3s = fabs(d3s);  d3s *= d3;
  
  /* get projection angle, convert to radians */
  if(!getparfloat("angle",&angle)) angle = 45.0;
  angle = MAX(angle,0.00001);
  angle = MIN(angle,90.0);
  angle *= PI/180.0;
  
  /* get axes parameters */
  if(!getparfloat("size1",&size1)) size1 = 4.0;
  if(!getparfloat("size2",&size2)) size2 = 4.0;
  if(!getparfloat("size3",&size3)) size3 = 3.0;
  if (!getparfloat("xbox",&xbox)) xbox = 1.5;
  if (!getparfloat("ybox",&ybox)) ybox = 1.5;
 
  /* compute extreme values */
  x1min = (d1>0.0)?f1:f1+(n1-1)*d1;
  x1max = (d1<0.0)?f1:f1+(n1-1)*d1;
  x2min = (d2>0.0)?f2:f2+(n2-1)*d2;
  x2max = (d2<0.0)?f2:f2+(n2-1)*d2;
  x3min = (d3>0.0)?f3:f3+(n3-1)*d3;
  x3max = (d3<0.0)?f3:f3+(n3-1)*d3;
  
  /* get axis1 parameters */
  x1beg = x1min;
  x1end = x1max; getparfloat("x1end",&x1end);
  d1num = 0.0; getparfloat("d1num",&d1num);
  f1num = x1min; getparfloat("f1num",&f1num);
  n1tic = 1; getparint("n1tic",&n1tic);
  getparstring("grid1",&grid1s);
  if (STREQ("dot",grid1s)) grid1 = DOT;
  else if (STREQ("dash",grid1s)) grid1 = DASH;
  else if (STREQ("solid",grid1s)) grid1 = SOLID;
  else grid1 = NONE;
  getparstring("label1",&label1);
  
  /* get axis2 parameters */
  x2beg = x2min; getparfloat("x2beg",&x2beg);
  x2end = x2max; 
  d2num = 0.0; getparfloat("d2num",&d2num);
  f2num = x2min; getparfloat("f2num",&f2num);
  n2tic = 1; getparint("n2tic",&n2tic);
  getparstring("grid2",&grid2s);
  if (STREQ("dot",grid2s)) grid2 = DOT;
  else if (STREQ("dash",grid2s)) grid2 = DASH;
  else if (STREQ("solid",grid2s)) grid2 = SOLID;
  else grid2 = NONE;
  getparstring("label2",&label2);
  
  /* get axis3 parameters */
  x3beg = x3min; 
  x3end = x3max; getparfloat("x3end",&x3end);
  d3num = 0.0; getparfloat("d3num",&d3num);
  f3num = x3min; getparfloat("f3num",&f3num);
  n3tic = 1; getparint("n3tic",&n3tic);
  getparstring("grid3",&grid3s);
  if (STREQ("dot",grid3s)) grid3 = DOT;
  else if (STREQ("dash",grid3s)) grid3 = DASH;
  else if (STREQ("solid",grid3s)) grid3 = SOLID;
  else grid3 = NONE;
  getparstring("label3",&label3);
  
  /* get additional font parameters */
  getparstring("labelfont",&labelfont);
  labelsize = 18.0; getparfloat("labelsize",&labelsize);
  getparstring("title",&title);
  getparstring("titlefont",&titlefont);
  titlesize = 24.0; getparfloat("titlesize",&titlesize);
  getparstring("titlecolor",&titlecolor);
  getparstring("axescolor",&axescolor);
  getparstring("gridcolor",&gridcolor);
  style = SEISMIC;
  
 
  /* adjust x1beg and x1end to fall on sampled values */
  i1beg = NINT((x1beg-f1)/d1);
  i1beg = MAX(0,MIN(n1,i1beg));
  x1beg = f1+i1beg*d1;
  i1end = NINT((x1end-f1)/d1);
  i1end = MAX(0,MIN(n1-1,i1end));
  x1end = f1+i1end*d1;
  
  /* adjust x2beg and x2end to fall on sampled values */
  i2beg = NINT((x2beg-f2)/d2);
  i2beg = MAX(0,MIN(n2-1,i2beg));
  x2beg = f2+i2beg*d2;
  i2end = NINT((x2end-f2)/d2);
  i2end = MAX(0,MIN(n2-1,i2end));
  x2end = f2+i2end*d2;
  
  /* adjust x3beg and x3end to fall on sampled values */
  i3beg = NINT((x3beg-f3)/d3);
  i3beg = MAX(0,MIN(n3-1,i3beg));
  x3beg = f3+i3beg*d3;
  i3end = NINT((x3end-f3)/d3);
  i3end = MAX(0,MIN(n3-1,i3end));
  x3end = f3+i3end*d3;

  /* allocate space for image bytes */
  n1c = 1+abs(i1end-i1beg);
  n2c = 1+abs(i2end-i2beg);
  n3c = 1+abs(i3end-i3beg);
  czfront = ealloc1(n1c*n2c,sizeof(char));
  czside = ealloc1(n1c*n3c,sizeof(char));
  cztop = ealloc1(n2c*n3c,sizeof(char));
  
  /* compute conversion constants */
  zscale = (wclip!=bclip)?255.0/(wclip-bclip):1.0e10;
  zoffset = -bclip*zscale;
  i1step = (i1end>i1beg)?1:-1;
  i2step = (i2end>i2beg)?1:-1;
  i3step = (i3end>i3beg)?1:-1;
  
  /* convert front data to be imaged into unsigned characters */
  czp = czfront;
  for (i2c=0,i2=i2beg; i2c<n2c; i2c++,i2+=i2step) {
    for (i1c=0,i1=i1beg; i1c<n1c; i1c++,i1+=i1step) {
      zi = zoffset+zfront[i1+i2*n1]*zscale;
      if (zi<0.0) zi = 0.0;
      if (zi>255.0) zi = 255.0;
      *czp++ = (unsigned char)zi;
    }
  }
  
  /* convert side data to be imaged into unsigned characters */
  czp = czside;
  for (i3c=0,i3=i3beg; i3c<n3c; i3c++,i3+=i3step) {
    for (i1c=0,i1=i1beg; i1c<n1c; i1c++,i1+=i1step) {
      zi = zoffset+zside[i1+i3*n1]*zscale;
      if (zi<0.0) zi = 0.0;
      if (zi>255.0) zi = 255.0;
      *czp++ = (unsigned char)zi;
    }
  }

  /* convert top data to be imaged into unsigned characters */
  czp = cztop;
  for (i3c=0,i3=i3beg; i3c<n3c; i3c++,i3+=i3step) {
    for (i2c=0,i2=i2beg; i2c<n2c; i2c++,i2+=i2step) {
      zi = zoffset+ztop[i2+i3*n2]*zscale;
      if (zi<0.0) zi = 0.0;
      if (zi>255.0) zi = 255.0;
      *czp++ = (unsigned char)zi;
    }
  }
  free1float(z);
  
  /* determine sampling after scaling */
  n1s = MAX(1,NINT(1+(n1c-1)*d1/d1s));
  d1s = (n1s>1)?d1*(n1c-1)/(n1s-1):d1;
  n2s = MAX(1,NINT(1+(n2c-1)*d2/d2s));
  d2s = (n2s>1)?d2*(n2c-1)/(n2s-1):d2;
  n3s = MAX(1,NINT(1+(n3c-1)*d3/d3s));
  d3s = (n3s>1)?d3*(n3c-1)/(n3s-1):d3;
  
  /* if necessary, interpolate front to scaled sampling intervals */
  if (n1s!=n1c || n2s!=n2c) {
    szfront = ealloc1(n1s*n2s,sizeof(char));
    intl2b(n1c,d1,0.0,n2c,d2,0.0,czfront,
	   n1s,d1s,0.0,n2s,d2s,0.0,szfront);
    free1(czfront);
  } else {
    szfront = czfront;
  }
  
  /* if necessary, interpolate side to scaled sampling intervals */
  if (n1s!=n1c || n3s!=n3c) {
    szside = ealloc1(n1s*n3s,sizeof(char));
    intl2b(n1c,d1,0.0,n3c,d3,0.0,czside,
	   n1s,d1s,0.0,n3s,d3s,0.0,szside);
    free1(czside);
  } else {
    szside = czside;
  }
  
  /* if necessary, interpolate top to scaled sampling intervals */
  if (n2s!=n2c || n3s!=n3c) {
    sztop = ealloc1(n2s*n3s,sizeof(char));
    intl2b(n2c,d2,0.0,n3c,d3,0.0,cztop,
	   n2s,d2s,0.0,n3s,d3s,0.0,sztop);
    free1(cztop);
  } else {
    sztop = cztop;
  }
  
  /* determine axes pads */
  p1beg = (x1end>x1beg)?-fabs(d1s)/2:fabs(d1s)/2;
  p1end = (x1end>x1beg)?fabs(d1s)/2:-fabs(d1s)/2;
  p2beg = (x2end>x2beg)?-fabs(d2s)/2:fabs(d2s)/2;
  p2end = (x2end>x2beg)?fabs(d2s)/2:-fabs(d2s)/2;
  p3beg = (x3end>x3beg)?-fabs(d3s)/2:fabs(d3s)/2;
  p3end = (x3end>x3beg)?fabs(d3s)/2:-fabs(d3s)/2;
  
  /* get legend specs BEREND, Schoenfelder */
  legend = 0; getparint("legend", &legend); /* BEREND, Schoenfelder */
  getparstring("units", &units); /* BEREND, Schoenfelder */
  getparstring("legendfont", &legendfont);     /* BEREND, Schoenfelder */
  
  /* Get or calc legend parameters */
  /* Legend min and max: Calc from data read in */
  if (legend) {
    for (lz=0;lz<nz;lz++) {
      lmin=FMIN(lmin,z[lz]);
      lmax=FMAX(lmax,z[lz]);
    }
    if (verbose==2) warn("lmin=%g lmax=%g",lmin,lmax);
  
    lbeg = lmin; if (getparfloat("lbeg",&lbeg)) lbegsup=1;
    lend = lmax; if (getparfloat("lend",&lend)) lendsup=1;
    /* Change wclip,bclip to be inside legend range */
    wclip = FMAX(lbeg,wclip); /* [wclip,bclip] has to be in [lbeg,lend] */
    bclip = FMIN(lend,bclip);
    if (lbegsup!=1) { /* Add white and black areas to show possible clipping */ 
      float rangeperc=(bclip-wclip)/20.;
      lbeg=wclip-rangeperc;
    }
    if (lendsup!=1) {
      float rangeperc=(bclip-wclip)/20.;
      lend=bclip+rangeperc;
    }
    
    lfnum = lmin; getparfloat("lfnum",&lfnum);
    
    getparstring("lstyle",&lstyles);
    if (STREQ("vertright",lstyles))
      lstyle = VERTRIGHT;
    else if (STREQ("horibottom",lstyles))
      lstyle = HORIBOTTOM;
    /* legend dimensions (BEREND), Schoenfelder */
    lwidth = 0.1 ;lheight = size1+sin(angle)*size3/2;
    if (lstyle==HORIBOTTOM) {
      lwidth=size2+cos(angle)*size3/1.2 ;lheight = 0.24;
    }
    getparfloat("lwidth",&lwidth);
    getparfloat("lheight",&lheight);
    
    lx=.8;ly = ybox+(size1+sin(angle)*size3-lheight)/2;
    if (lstyle==VERTRIGHT) {
      lx=xbox+size2+cos(angle)*size3+0.1;
    } else if (lstyle==HORIBOTTOM) {
      lx=xbox+(size2+cos(angle)*size3-lwidth)/2.0;ly = 1.0;
    }
    getparfloat("lx",&lx);
    getparfloat("ly",&ly);
    
    getparstring("lgrid",&lgrids);
    if (STREQ("dot",lgrids))
      ugrid = DOT;
    else if (STREQ("dash",lgrids))
      ugrid = DASH;
    else if (STREQ("solid",lgrids))
      ugrid = SOLID;
    else
      ugrid = NONE;
  }
  

  if (legend) {
    /* Make legend color values */
    int lll=0,lcount,perc5=13,ilbeg,ilend; /* color scale */
    if (lbegsup!=1) {
      ln+=perc5; /* white area */
    }
    if (lendsup!=1) {
      ln+=perc5; /* black area */
    }
    data_legend = ealloc1(ln,sizeof(char));
    if (lbegsup!=1) {
      for (lll=0;lll<perc5;lll++) data_legend[lll]=(char) 255; /* white area */
    }
    for (lcount=255;lcount>=0;lcount--,lll++) data_legend[lll]=(char) lcount;
    if (lendsup!=1) {
      for (;lll<ln;lll++) data_legend[lll]=(char) 0; /* black area */
    }
    lf=lbeg;ld=(lend-lbeg)/(ln-1);
    if (!(getparfloat("ldnum",&ldnum)))	ldnum=0.0;
    
    /* adjust lbeg and lend to fall on sampled values */
    
    ilbeg = NINT((lbeg-lf)/ld);
    ilbeg = MAX(0,MIN(ln-1,ilbeg));
    lbeg = lf+ilbeg*ld;
    ilend = NINT((lend-lf)/ld);
    ilend = MAX(0,MIN(ln-1,ilend));
    lend = lf+ilend*ld;

    /* convert legend parameters to points */  
    lx *= 72.0; /* Schoenfelder */
    ly *= 72.0; /* Schoenfelder */
    lwidth *= 72.0; /* Schoenfelder */
    lheight *= 72.0; /* Schoenfelder */
  }

  /* convert axes parameters to points */  
  size1 *= 72;
  size2 *= 72;
  size3 *= 72;
  xbox *= 72;
  ybox *= 72;
  
  /* set bounding box */
  psAxesBBox(xbox,ybox,size2+cos(angle)*size3,size1+sin(angle)*size3,
	     labelfont,labelsize,titlefont,titlesize,style,bbox);
  if (legend) {
    psLegendBBox( /* Space for legend Schoenfelder */
		 lx,ly,lwidth,lheight,
		 labelfont,labelsize,
		 lstyle,lbbox);
    /* Include space for legend Schoenfelder */
    bbox[0]=MIN(bbox[0],lbbox[0]);
    bbox[1]=MIN(bbox[1],lbbox[1]);
    bbox[2]=MAX(bbox[2],lbbox[2]);
    bbox[3]=MAX(bbox[3],lbbox[3]);
  }
  boundingbox(bbox[0],bbox[1],bbox[2],bbox[3]);
  
  /* begin PostScript */
  begineps();
  
  /* save graphics state */
  gsave();
  
  /* translate coordinate system by box offset */
  translate(xbox,ybox);
  
  /* begin front */
  gsave();
  
  /* transform coordinates */
  translate(0,0);
  scale(size2,size1);
  
  /* determine image matrix */
  matrix[0] = 0;  matrix[1] = n2s;  matrix[2] = -n1s;
  matrix[3] = 0;  matrix[4] = n1s;  matrix[5] = 0;
  
  /* draw the image */
  drawimage(hls,colors,n1s,n2s,bps,matrix,szfront);
  
  /* end front */
  grestore();
  
  /* begin side */
  gsave();
  
  /* transform and skew coordinates */
  matrix[0] = 1;  matrix[1] = tan(angle);  matrix[2] = 0;
  matrix[3] = 1;  matrix[4] = 0;  matrix[5] = 0;
  translate(size2,0);
  concat(matrix);
  scale(size3*cos(angle),size1);
  
  /* determine image matrix */
  matrix[0] = 0;  matrix[1] = n3s;  matrix[2] = -n1s;
  matrix[3] = 0;  matrix[4] = n1s;  matrix[5] = 0;
  
  /* draw the image */
  drawimage(hls,colors,n1s,n3s,bps,matrix,szside);
  
  /* end side */
  grestore();
  
  /* begin top */
  gsave();
  
  
  /* transform and skew coordinates */
  matrix[0] = 1;  matrix[1] = 0;  matrix[2] = 1.0/tan(angle);
  matrix[3] = 1;  matrix[4] = 0;  matrix[5] = 0;
  translate(0,size1);
  concat(matrix);
  scale(size2,size3*sin(angle));
  
  /* determine image matrix */
  matrix[0] = n2s;  matrix[1] = 0;  matrix[2] = 0;
  matrix[3] = n3s;  matrix[4] = 0;  matrix[5] = 0;
  
  /* draw the image */
  drawimage(hls,colors,n2s,n3s,bps,matrix,sztop);
  
  /* end top */
  grestore();
  
  if (legend) {
    gsave();
  /* translate coordinate system by box offset */
  translate(-xbox,-ybox);
    translate(lx,ly);
    scale(lwidth,lheight);
    if ((lstyle==VERTLEFT) || (lstyle==VERTRIGHT)) {
      labmatrix[0] = 1;	 labmatrix[1] = 0;  labmatrix[2] = 0;
      labmatrix[3] = ln; labmatrix[4] = 0;  labmatrix[5] = 0;
      drawimage(hls,colors,1,ln,bps,labmatrix,data_legend);
    } else {
      labmatrix[0] = -1; labmatrix[1] = 0;  labmatrix[2] = 0;
      labmatrix[3] = ln; labmatrix[4] = 0;  labmatrix[5] = 0;
      rotate(-90);
      drawimage(hls,colors,1,ln,bps,labmatrix,data_legend);
      rotate(90);
    }
    grestore();
  }
  /* restore graphics state */
  grestore();
  
  psCubeAxesBox(xbox,ybox,size1,size2,size3,angle,
		x1beg,x1end,p1beg,p1end,
		d1num,f1num,n1tic,grid1,label1,
		x2beg,x2end,p2beg,p2end,
		d2num,f2num,n2tic,grid2,label2,
		x3beg,x3end,p3beg,p3end,
		d3num,f3num,n3tic,grid3,label3,
		labelfont,labelsize,
		title,titlefont,titlesize,
		titlecolor,axescolor,gridcolor);
  
	/* draw axes and title for legend Schoenfelder*/
	if (legend) {
	  float lpbeg,lpend;
	  int lntic=1;
	  gsave();
	  lpbeg = 0.0; /*(lend>lbeg)?-fabs(d1s)/2:fabs(d1s)/2;*/
	  lpend = 0.0; /*(lend>lbeg)?fabs(d1s)/2:-fabs(d1s)/2;*/
  
	  psLegendBox(
		    lx,ly,lwidth,lheight,
		    lbeg,lend,lpbeg,lpend,
		    ldnum,lf,lntic,ugrid,units,
		    labelfont,labelsize,
		    axescolor,gridcolor,
		    lstyle);
	  grestore();
	}
  /* end PostScript */
  showpage();
  endeps();
  
  return 0;
}
Beispiel #28
0
int 
main (int argc, char **argv)
{
	int n1,n2,n1tic,n2tic,nfloats,bbox[4],
	  i1,i2,grid1,grid2,style,
	  n1c,n2c,n1s,n2s,i1beg,i1end,i2beg,i2end,i1c,i2c,
	  nz,iz,i1step,i2step,verbose,hls,bps,
	  legend,ugrid=SOLID,lstyle=VERTLEFT,lz,lbegsup=0,lendsup=0,ln=256,
	  lbbox[4], threecolor=0; /* BEREND, Schoenfelder */
        int lnice; /* c liner */
	float labelsize,titlesize,perc,clip,bperc,wperc,bclip,wclip,
		d1,f1,d2,f2,*z,*temp,zscale,zoffset,zi,
		xbox,ybox,width,height,
		x1beg,x1end,x2beg,x2end,
		x1min,x1max,x2min,x2max,
		d1num,f1num,d2num,f2num,
		p1beg,p1end,p2beg,p2end,matrix[6],colors[3][3], /* for 3 color mode */
		d1s,d2s,
	  lwidth,lheight,lx,ly,lbeg,lend,lmin=(float) FLT_MAX,lmax=(float) -FLT_MAX,
	  ldnum,lfnum,ld,lf=0,labmatrix[6]; /* BEREND, Schoenfelder */
	float axeswidth, ticwidth, gridwidth;
	unsigned char *cz,*czp,*sz,*data_legend=NULL;
	char *label1="",*label2="",*title="",*units="",
	  *legendfont="times_roman10",
	  *labelfont="Helvetica",*titlefont="Helvetica-Bold",
	  *styles="seismic",*grid1s="none",*grid2s="none",
	  *titlecolor="black",*axescolor="black",*gridcolor="black",
	  *lstyles="vertleft",*lgrids="none";
	FILE *infp=stdin;

	float **x1curve=NULL,**x2curve=NULL,*curvewidth=NULL;
	int i,j,curve=0,*npair=NULL,ncurvecolor=0,ncurvewidth=0,ncurvedash=0,*curvedash=NULL;
	char **curvecolor=NULL,**curvefile=NULL;
	FILE *curvefp=NULL;
	cwp_Bool is_curve = cwp_false;

	/* initialize getpar */
	initargs(argc,argv);
	requestdoc(1);

	/* get parameters describing 1st dimension sampling */
	if (!getparint("n1",&n1)) err("must specify n1!\n");
	d1 = 1.0;  getparfloat("d1",&d1);
	f1 = 0.0;  getparfloat("f1",&f1);
	x1min = (d1>0.0)?f1:f1+(n1-1)*d1;
	x1max = (d1<0.0)?f1:f1+(n1-1)*d1;

	/* get parameters describing 2nd dimension sampling */
	if (!getparint("n2",&n2)) {
		if (efseeko(infp,(off_t) 0,SEEK_END)!=0)
			err("must specify n2 if in a pipe!\n");
		nfloats = (int) (eftello(infp)/((off_t) sizeof(float)));
		efseeko(infp,(off_t) 0,SEEK_SET);
		n2 = nfloats/n1;
	}
	d2 = 1.0;  getparfloat("d2",&d2);
	f2 = 0.0;  getparfloat("f2",&f2);
	x2min = (d2>0.0)?f2:f2+(n2-1)*d2;
	x2max = (d2<0.0)?f2:f2+(n2-1)*d2;

	/* read color parameters */
	if (!getparint("threecolor",&threecolor)) threecolor=1;
	bps = 8;
	hls = 0;
	/* color[][0] is black, color[][2] is white in 2 color mode */
	colors[R][0] = colors[G][0] = colors[B][0] = 0.0;
	colors[R][1] = colors[G][1] = colors[B][1] = 0.5;
	colors[R][2] = colors[G][2] = colors[B][2] = 1.0;
	if (countparval("brgb") || countparval("wrgb")) {
		float brgb[3],grgb[3],wrgb[3];
		brgb[R] = brgb[G] = brgb[B] = 0.0;
		wrgb[R] = wrgb[G] = wrgb[B] = 1.0;
		getparfloat("brgb",&brgb[0]);
		getparfloat("wrgb",&wrgb[0]);
		grgb[R] = (brgb[R] + wrgb[R])/2.;
		grgb[G] = (brgb[G] + wrgb[G])/2.;
		grgb[B] = (brgb[B] + wrgb[B])/2.;
		if (threecolor==1)
		  getparfloat("grgb",&grgb[0]);
		brgb[R] = MAX(0.0,MIN(1.0,brgb[R]));
		grgb[R] = MAX(0.0,MIN(1.0,grgb[R]));
		wrgb[R] = MAX(0.0,MIN(1.0,wrgb[R]));
		brgb[G] = MAX(0.0,MIN(1.0,brgb[G]));
		grgb[G] = MAX(0.0,MIN(1.0,grgb[G]));
		wrgb[G] = MAX(0.0,MIN(1.0,wrgb[G]));
		brgb[B] = MAX(0.0,MIN(1.0,brgb[B]));
		grgb[B] = MAX(0.0,MIN(1.0,grgb[B]));
		wrgb[B] = MAX(0.0,MIN(1.0,wrgb[B]));
		colors[R][0] = brgb[R];	 colors[R][1] = grgb[R];  colors[R][2] = wrgb[R];
		colors[G][0] = brgb[G];	 colors[G][1] = grgb[G];  colors[G][2] = wrgb[G];
		colors[B][0] = brgb[B];	 colors[B][1] = grgb[B];  colors[B][2] = wrgb[B];
		if (!getparint("bps",&bps)) bps = 12;
		if (bps!=12 && bps!=24)
			err("bps must equal 12 or 24 for color plots!\n");
	} else if (countparval("bhls") || countparval("whls")) {
		float bhls[3],ghls[3],whls[3];
		hls = 1;
		bhls[H] = ghls[H] = whls[H] = 0.0;
		bhls[L] = 0.0;	ghls[L] = 0.5;	whls[L] = 1.0;
		bhls[S] = ghls[S] = whls[S] = 0.0;
		getparfloat("bhls",&bhls[0]);
		getparfloat("whls",&whls[0]);
		ghls[H] = (bhls[H] + whls[H])/2.;
		ghls[L] = (bhls[L] + whls[L])/2.;
		ghls[S] = (bhls[S] + whls[S])/2.;
		if (threecolor==1)
		  getparfloat("ghls",&ghls[0]);
		bhls[L] = MAX(0.0,MIN(1.0,bhls[L]));
		ghls[L] = MAX(0.0,MIN(1.0,ghls[L]));
		whls[L] = MAX(0.0,MIN(1.0,whls[L]));
		bhls[S] = MAX(0.0,MIN(1.0,bhls[S]));
		ghls[S] = MAX(0.0,MIN(1.0,ghls[S]));
		whls[S] = MAX(0.0,MIN(1.0,whls[S]));
		colors[H][0] = bhls[0];	 colors[H][1] = ghls[0];  colors[H][2] = whls[0];
		colors[L][0] = bhls[1];	 colors[L][1] = ghls[1];  colors[L][2] = whls[1];
		colors[S][0] = bhls[2];	 colors[S][1] = ghls[2];  colors[S][2] = whls[2];
		if (!getparint("bps",&bps)) bps = 12;
		if (bps!=12 && bps!=24)
			err("bps must equal 12 or 24 for color plots!\n");
	}

	/* get legend specs BEREND, Schoenfelder */
	legend = 0; getparint("legend", &legend); /* BEREND, Schoenfelder */
	getparstring("units", &units); /* BEREND, Schoenfelder */
	getparstring("legendfont", &legendfont);     /* BEREND, Schoenfelder */

	/* set up curve plotting */
	if ((curve=countparval("curve"))!=0) {
		curvefile=(char**)ealloc1(curve,sizeof(void*));
		getparstringarray("curve",curvefile);
		if ((x1curve=(float**)malloc(curve*sizeof(void*)))==NULL)
			err("Could not allocate x1curve pointers\n");
		if ((x2curve=(float**)malloc(curve*sizeof(void*)))==NULL)
			err("Could not allocate x2curve pointers\n");
		npair=ealloc1int(curve);
		getparint("npair",npair);
		is_curve = cwp_true;
	} else {
		npair=(int *)NULL;
		curvefile=(char **)NULL;
		x1curve=(float **)NULL;
		x2curve=(float **)NULL;
		is_curve = cwp_false;
	}
	if (is_curve) {
	 if ((ncurvecolor=countparval("curvecolor"))<curve) {
		curvecolor=(char**)ealloc1(curve,sizeof(void*));
		if (!getparstringarray("curvecolor",curvecolor)) {
			curvecolor[0]=(char *)cwp_strdup("black\0");
			ncurvecolor=1;
		}
		for (i=ncurvecolor; i<curve; i++)
			curvecolor[i]=(char *)cwp_strdup(curvecolor[ncurvecolor-1]);
	 } else if (ncurvecolor) {
		curvecolor=(char**)ealloc1(ncurvecolor,sizeof(void*));
		getparstringarray("curvecolor",curvecolor);
	 }
	 for (j=0; j<curve; j++) {
		curvefp=efopen(curvefile[j],"r");
		x1curve[j]=ealloc1float(npair[j]);
		x2curve[j]=ealloc1float(npair[j]);
		for (i=0; i<npair[j]; i++) {
			fscanf(curvefp,"%f",&x1curve[j][i]);
			fscanf(curvefp,"%f",&x2curve[j][i]);
		}
		efclose(curvefp);
	 }
	}

	/* read binary data to be plotted */
	nz = n1*n2;
	z = ealloc1float(nz);
	if (fread(z,sizeof(float),nz,infp)!=nz)
		err("error reading input file!\n");

	/* if necessary, determine clips from percentiles */
	if (getparfloat("clip",&clip)) {
		bclip = clip;
		wclip = -clip;
	}
	if ((!getparfloat("bclip",&bclip) || !getparfloat("wclip",&wclip)) &&
		!getparfloat("clip",&clip)) {
		perc = 100.0;  getparfloat("perc",&perc);
		temp = ealloc1float(nz);
		for (iz=0; iz<nz; iz++)
			temp[iz] = z[iz];
		if (!getparfloat("bclip",&bclip)) {
			bperc = perc;	getparfloat("bperc",&bperc);
			iz = (nz*bperc/100.0);
			if (iz<0) iz = 0;
			if (iz>nz-1) iz = nz-1;
			qkfind(iz,nz,temp);
			bclip = temp[iz];
		}
		if (!getparfloat("wclip",&wclip)) {
			wperc = 100.0-perc;  getparfloat("wperc",&wperc);
			iz = (nz*wperc/100.0);
			if (iz<0) iz = 0;
			if (iz>nz-1) iz = nz-1;
			qkfind(iz,nz,temp);
			wclip = temp[iz];
		}
		free1float(temp);
	}
	verbose = 1;  getparint("verbose",&verbose);
	if (verbose) warn("bclip=%g wclip=%g",bclip,wclip);

	/* get scaled sampling intervals */
	d1s = 1.0;  getparfloat("d1s",&d1s);
	d2s = 1.0;  getparfloat("d2s",&d2s);
	d1s = fabs(d1s);  d1s *= d1;
	d2s = fabs(d2s);  d2s *= d2;

	/* get axes parameters */
	xbox = 1.5; getparfloat("xbox",&xbox); /* if psimage is called by ximage, it */
	ybox = 1.5; getparfloat("ybox",&ybox); /* will xbox=1.166 and ybox=1.167 */
	width = 6.0; getparfloat("wbox",&width); getparfloat("width",&width);
	height = 8.0;getparfloat("hbox",&height);getparfloat("height",&height);
         /* begin c liner */
	lnice = 0;  getparint("lnice",&lnice); 
        if (lnice==1) {
            ybox = 2.2;
            /* lx=8 is set below, after getpar on lx ... c liner */
            width = 5.4;
            height = 7.2;
        }
         /* end c liner */
	x1beg = x1min; getparfloat("x1beg",&x1beg);
	x1end = x1max; getparfloat("x1end",&x1end);
	d1num = 0.0; getparfloat("d1num",&d1num);
	f1num = x1min; getparfloat("f1num",&f1num);
	n1tic = 1; getparint("n1tic",&n1tic);
	getparstring("grid1",&grid1s);
	if (STREQ("dot",grid1s))
		grid1 = DOT;
	else if (STREQ("dash",grid1s))
		grid1 = DASH;
	else if (STREQ("solid",grid1s))
		grid1 = SOLID;
	else
		grid1 = NONE;
	getparstring("label1",&label1);
	x2beg = x2min; getparfloat("x2beg",&x2beg);
	x2end = x2max; getparfloat("x2end",&x2end);
	d2num = 0.0; getparfloat("d2num",&d2num);
	f2num = 0.0; getparfloat("f2num",&f2num);
	n2tic = 1; getparint("n2tic",&n2tic);
	getparstring("grid2",&grid2s);
	if (STREQ("dot",grid2s))
		grid2 = DOT;
	else if (STREQ("dash",grid2s))
		grid2 = DASH;
	else if (STREQ("solid",grid2s))
		grid2 = SOLID;
	else
		grid2 = NONE;
	getparstring("label2",&label2);
	getparstring("labelfont",&labelfont);
	labelsize = 18.0; getparfloat("labelsize",&labelsize);
	getparstring("title",&title);
	getparstring("titlefont",&titlefont);
	titlesize = 24.0; getparfloat("titlesize",&titlesize);
	getparstring("titlecolor",&titlecolor);
	getparstring("axescolor",&axescolor);
	getparstring("gridcolor",&gridcolor);

	/* axes and tic width */
        if(!getparfloat("axeswidth",&axeswidth)) axeswidth=1;
        if (!getparfloat("ticwidth",&ticwidth)) ticwidth=axeswidth;
        if(!getparfloat("gridwidth",&gridwidth)) gridwidth =axeswidth;

	if (is_curve) {
	 if ((ncurvewidth=countparval("curvewidth"))<curve) {
		curvewidth=ealloc1float(curve);
		if (!getparfloat("curvewidth",curvewidth)) {
			curvewidth[0]=axeswidth;
			ncurvewidth=1;
		}
		for (i=ncurvewidth; i<curve; i++)
			curvewidth[i]=curvewidth[ncurvewidth-1];
	 } else {
		curvewidth=ealloc1float(ncurvewidth);
		getparfloat("curvewidth",curvewidth);
	 }
	 if ((ncurvedash=countparval("curvedash"))<curve) {
		curvedash=ealloc1int(curve);
		if (!getparint("curvedash",curvedash)) {
		        curvedash[0]=0;
			ncurvedash=1;
		}
		for (i=ncurvedash; i<curve; i++)
			curvedash[i]=curvedash[ncurvedash-1];
	 } else {
		curvedash=ealloc1int(ncurvedash);
		getparint("curvedash",curvedash);
	 }
	}

	getparstring("style",&styles);

	if (STREQ("normal",styles))
		style = NORMAL;
	else
		style = SEISMIC;

	/* Get or calc legend parameters */
	/* Legend min and max: Calc from data read in */
	if (legend) {
	  for (lz=0;lz<nz;lz++) {
	    lmin=FMIN(lmin,z[lz]);
	    lmax=FMAX(lmax,z[lz]);
	  }
	  if (verbose==2) warn("lmin=%g lmax=%g",lmin,lmax);
	}

	if (legend) {
	  lbeg = lmin; if (getparfloat("lbeg",&lbeg)) lbegsup=1;
	  lend = lmax; if (getparfloat("lend",&lend)) lendsup=1;


	  /* Change wclip,bclip to be inside legend range */
	  wclip = FMAX(lbeg,wclip); /* [wclip,bclip] has to be in [lbeg,lend] */
	  bclip = FMIN(lend,bclip);
	  if (lbegsup!=1) { /* Add white and black areas to show possible clipping */ 
	    float rangeperc=(bclip-wclip)/20.;
	    lbeg=wclip-rangeperc;
	  }
	  if (lendsup!=1) {
	    float rangeperc=(bclip-wclip)/20.;
	    lend=bclip+rangeperc;
	  }
	  
	  lfnum = lmin; getparfloat("lfnum",&lfnum);
	
	  getparstring("lstyle",&lstyles);
	  if (STREQ("vertright",lstyles))
	    lstyle = VERTRIGHT;
	  else if (STREQ("horibottom",lstyles))
	    lstyle = HORIBOTTOM;

	  /* legend dimensions (BEREND), Schoenfelder */
	  lwidth = 0.1 ;lheight = height/2;
	  if (lstyle==HORIBOTTOM) {
	    lwidth=width/1.2 ;lheight = 0.24;
	  }
	  getparfloat("lwidth",&lwidth);
	  getparfloat("lheight",&lheight);
	  
	  lx=.8;ly = ybox+(height-lheight)/2;
	  if (lstyle==VERTRIGHT) {
	    lx=xbox+width+0.1;
	  } else if (lstyle==HORIBOTTOM) {
	    lx=xbox+(width-lwidth)/2.0;ly = 1.0;
	  }
	  getparfloat("lx",&lx);
          if (lnice==1) lx = 8;   /* c liner */
	  getparfloat("ly",&ly);
	  
	  getparstring("lgrid",&lgrids);
	  if (STREQ("dot",lgrids))
	    ugrid = DOT;
	  else if (STREQ("dash",lgrids))
	    ugrid = DASH;
	  else if (STREQ("solid",lgrids))
	    ugrid = SOLID;
	  else
	    ugrid = NONE;
	}

	/* adjust x1beg and x1end to fall on sampled values */
	/* This will not allow to display an area greater than the data supplied */
	i1beg = NINT((x1beg-f1)/d1);
	i1beg = MAX(0,MIN(n1-1,i1beg));
	x1beg = f1+i1beg*d1;
	i1end = NINT((x1end-f1)/d1);
	i1end = MAX(0,MIN(n1-1,i1end));
	x1end = f1+i1end*d1;

	/* adjust x2beg and x2end to fall on sampled values */
	i2beg = NINT((x2beg-f2)/d2);
	i2beg = MAX(0,MIN(n2-1,i2beg));
	x2beg = f2+i2beg*d2;
	i2end = NINT((x2end-f2)/d2);
	i2end = MAX(0,MIN(n2-1,i2end));
	x2end = f2+i2end*d2;

	if (legend) {
	  /* Make legend color values */
	  int lll=0,lcount,perc5=13,ilbeg,ilend; /* color scale */
	  if (lbegsup!=1) {
	    ln+=perc5; /* white area */
	  }
	  if (lendsup!=1) {
	    ln+=perc5; /* black area */
	  }
	  data_legend = ealloc1(ln,sizeof(char));
	  if (lbegsup!=1) {
	    for (lll=0;lll<perc5;lll++) data_legend[lll]=(char) 255; /* white area */
	  }
	  for (lcount=255;lcount>=0;lcount--,lll++) data_legend[lll]=(char) lcount;
	  if (lendsup!=1) {
	    for (;lll<ln;lll++) data_legend[lll]=(char) 0; /* black area */
	  }
	  lf=lbeg;ld=(lend-lbeg)/(ln-1);
	  if (!(getparfloat("ldnum",&ldnum)))	ldnum=0.0;

	  /* adjust lbeg and lend to fall on sampled values */
	  ilbeg = NINT((lbeg-lf)/ld);
	  ilbeg = MAX(0,MIN(ln-1,ilbeg));
	  lbeg = lf+ilbeg*ld;
	  ilend = NINT((lend-lf)/ld);
	  ilend = MAX(0,MIN(ln-1,ilend));
	  lend = lf+ilend*ld;
	}
	/* allocate space for image bytes */
	n1c = 1+abs(i1end-i1beg);
	n2c = 1+abs(i2end-i2beg);
	cz = ealloc1(n1c*n2c,sizeof(char));

	/* convert data to be imaged into unsigned characters */
	zscale = (wclip!=bclip)?255.0/(wclip-bclip):1.0e10;
	zoffset = -bclip*zscale;
	i1step = (i1end>i1beg)?1:-1;
	i2step = (i2end>i2beg)?1:-1;
	czp = cz;
	for (i1c=0,i1=i1beg; i1c<n1c; i1c++,i1+=i1step) {
		for (i2c=0,i2=i2beg; i2c<n2c; i2c++,i2+=i2step) {
			zi = zoffset+z[i1+i2*n1]*zscale;
			if (zi<0.0) zi = 0.0;
			if (zi>255.0) zi = 255.0;
			*czp++ = (unsigned char)zi;
		}
	}
	free1float(z);

	/* determine sampling after scaling */
	n1s = MAX(1,NINT(1+(n1c-1)*d1/d1s));
	d1s = (n1s>1)?d1*(n1c-1)/(n1s-1):d1;
	n2s = MAX(1,NINT(1+(n2c-1)*d2/d2s));
	d2s = (n2s>1)?d2*(n2c-1)/(n2s-1):d2;

	/* if necessary, interpolate to scaled sampling intervals */
	if (n1s!=n1c || n2s!=n2c) {
		sz = ealloc1(n1s*n2s,sizeof(char));
		intl2b(n2c,d2,0.0,n1c,d1,0.0,cz,n2s,d2s,0.0,n1s,d1s,0.0,sz); /* Interpol array */
		free1(cz);
	} else {
		sz = cz;
	}

	/* determine axes pads */
	p1beg = (x1end>x1beg)?-fabs(d1s)/2:fabs(d1s)/2;
	p1end = (x1end>x1beg)?fabs(d1s)/2:-fabs(d1s)/2;
	p2beg = (x2end>x2beg)?-fabs(d2s)/2:fabs(d2s)/2;
	p2end = (x2end>x2beg)?fabs(d2s)/2:-fabs(d2s)/2;

	/* convert axes box parameters from inches to points */
	xbox *= 72.0;
	ybox *= 72.0;
	width *= 72.0;
	height *= 72.0;
	if (legend) {
	  lx *= 72.0; /* Schoenfelder */
	  ly *= 72.0; /* Schoenfelder */
	  lwidth *= 72.0; /* Schoenfelder */
	  lheight *= 72.0; /* Schoenfelder */
	}

	/* set bounding box */
	psAxesBBox(
		   xbox,ybox,width,height,
		   labelfont,labelsize,
		   titlefont,titlesize,
		   style,bbox);
	if (legend) {
	  psLegendBBox( /* Space for legend Schoenfelder */
			lx,ly,lwidth,lheight,
			labelfont,labelsize,
			lstyle,lbbox);
	  /* Include space for legend Schoenfelder */
	  bbox[0]=MIN(bbox[0],lbbox[0]);
	  bbox[1]=MIN(bbox[1],lbbox[1]);
	  bbox[2]=MAX(bbox[2],lbbox[2]);
	  bbox[3]=MAX(bbox[3],lbbox[3]);
	}
	boundingbox(bbox[0],bbox[1],bbox[2],bbox[3]);
	/* begin PostScript */
	begineps();

	/* save graphics state */
	gsave();

	/* translate coordinate system by box offset */
	translate(xbox,ybox);

	/* determine image matrix */
	if (style==NORMAL) {
		matrix[0] = 0;	matrix[1] = n1s;  matrix[2] = n2s;
		matrix[3] = 0;	matrix[4] = 0;	matrix[5] = 0;
	} else {
		matrix[0] = n2s;  matrix[1] = 0;  matrix[2] = 0;
		matrix[3] = -n1s;  matrix[4] = 0;  matrix[5] = n1s;
	}

	scale(width,height);

	/* draw the image (before axes so grid lines are visible) */
	drawimage(hls,colors,n2s,n1s,bps,matrix,sz);
	/***************************/
	/* main image has been drawn, restore graphics state */
	grestore();

	/* *********************************/
	/* draw the colorbar (before axes so grid lines are visible) Schoenfelder*/
	if (legend) {
	  gsave();
	  translate(lx,ly);
	  scale(lwidth,lheight);
	  if ((lstyle==VERTLEFT) || (lstyle==VERTRIGHT)) {
	    labmatrix[0] = 1;	 labmatrix[1] = 0;  labmatrix[2] = 0;
	    labmatrix[3] = ln; labmatrix[4] = 0;  labmatrix[5] = 0;
	    drawimage(hls,colors,1,ln,bps,labmatrix,data_legend);
	  } else {
	    labmatrix[0] = -1;	 labmatrix[1] = 0;  labmatrix[2] = 0;
	    labmatrix[3] = ln; labmatrix[4] = 0;  labmatrix[5] = 0;
	    rotate(-90);
	    drawimage(hls,colors,1,ln,bps,labmatrix,data_legend);
	    rotate(90);
	  }
	  
	  grestore();
	}

	/* draw curve */
	for (i=0; i<curve; i++) {
		gsave();
		psDrawCurve(
			xbox,ybox,width,height,
			x1beg,x1end,p1beg,p1end, 
			x2beg,x2end,p2beg,p2end,
			x1curve[i],x2curve[i],npair[i],
			curvecolor[i],curvewidth[i],curvedash[i],style);
		grestore();
	}


	gsave();
	/* draw axes and title */
	psAxesBox(
		  xbox,ybox,width,height,
		  x1beg,x1end,p1beg,p1end,
		  d1num,f1num,n1tic,grid1,label1,
		  x2beg,x2end,p2beg,p2end,
		  d2num,f2num,n2tic,grid2,label2,
		  labelfont,labelsize,
		  title,titlefont,titlesize,
		  titlecolor,axescolor,gridcolor,
		  ticwidth,axeswidth,gridwidth,
		  style);
	/* restore graphics state */
	grestore();

	/* draw axes and title for legend Schoenfelder*/
	if (legend) {
	  float lpbeg,lpend;
	  int lntic=1;
	  gsave();
	  lpbeg = 0.0; /*(lend>lbeg)?-fabs(d1s)/2:fabs(d1s)/2;*/
	  lpend = 0.0; /*(lend>lbeg)?fabs(d1s)/2:-fabs(d1s)/2;*/
	  
	  psLegendBox(
		    lx,ly,lwidth,lheight,
		    lbeg,lend,lpbeg,lpend,
		    ldnum,lf,lntic,ugrid,units,
		    labelfont,labelsize,
		    axescolor,gridcolor,
		    lstyle);
	  grestore();
	}

	/* end PostScript */
	showpage();
	endeps();

	if (curve) {
		free1int(npair);
		for (i=0; i<curve; i++) {
			free1float(x1curve[i]);
			free1float(x2curve[i]);
		}
		free1float(curvewidth);
		free1int(curvedash);
		free((void**)x1curve);
		free((void**)x2curve);
		free((void**)curvefile);
		free((void**)curvecolor);
	}

	return 0;
}