static PyObject *
complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
{
	Py_complex p;
	Py_complex exponent;
	long int_exponent;

 	if ((PyObject *)z!=Py_None) {
		PyErr_SetString(PyExc_ValueError, "complex modulo");
		return NULL;
	}
	PyFPE_START_PROTECT("complex_pow", return 0)
	errno = 0;
	exponent = ((PyComplexObject*)w)->cval;
	int_exponent = (long)exponent.real;
	if (exponent.imag == 0. && exponent.real == int_exponent)
		p = c_powi(v->cval,int_exponent);
	else
		p = c_pow(v->cval,exponent);

	PyFPE_END_PROTECT(p)
	if (errno == ERANGE) {
		PyErr_SetString(PyExc_ValueError,
				"0.0 to a negative or complex power");
		return NULL;
	}
	return PyComplex_FromCComplex(p);
}
static Py_complex c_powi(Py_complex x, long n)
{
	Py_complex cn;

	if (n > 100 || n < -100) {
		cn.real = (double) n;
		cn.imag = 0.;
		return c_pow(x,cn);
	}
	else if (n > 0)
		return c_powu(x,n);
	else
		return c_quot(c_1,c_powu(x,-n));

}
Beispiel #3
0
static PyObject *
complex_pow(PyObject *v, PyObject *w, PyObject *z)
{
	Py_complex p;
	Py_complex exponent;
	long int_exponent;
	Py_complex a, b;
	TO_COMPLEX(v, a);
	TO_COMPLEX(w, b);

 	if (z!=Py_None) {
		PyErr_SetString(PyExc_ValueError, "complex modulo");
		return NULL;
	}
	PyFPE_START_PROTECT("complex_pow", return 0)
	errno = 0;
	exponent = b;
	int_exponent = (long)exponent.real;
	if (exponent.imag == 0. && exponent.real == int_exponent)
		p = c_powi(a,int_exponent);
	else
		p = c_pow(a,exponent);

	PyFPE_END_PROTECT(p)
	Py_ADJUST_ERANGE2(p.real, p.imag);
	if (errno == EDOM) {
		PyErr_SetString(PyExc_ZeroDivisionError,
				"0.0 to a negative or complex power");
		return NULL;
	}
	else if (errno == ERANGE) {
		PyErr_SetString(PyExc_OverflowError,
				"complex exponentiation");
		return NULL;
	}
	return PyComplex_FromCComplex(p);
}
void * do_time_step(void * input)
{

chunk_info_t * info = (chunk_info_t*)input;
if (info == NULL) pthread_exit(NULL);

int freq_start = nfreqs*info->tid/NUM_THREADS;
int freq_end = nfreqs*(info->tid+1)/NUM_THREADS-1;

//for Hx update iz runs from 0 to zsteps-2 - total of zsteps -1 elements to update
int z_start_hx = (zsteps - 1)*info->tid/NUM_THREADS;
int z_end_hx = (zsteps - 1)*(info->tid+1)/NUM_THREADS-1;	
//for Ey update iz runs from 1 to zsteps-1 - total of zsteps -1 elements to update
int z_start_ey = z_start_hx + 1;
int z_end_ey = z_end_hx + 1;

int do_ey_source = (zsource <= z_end_ey)&&(zsource >= z_start_ey);
int do_hx_source = ( (zsource -1) <= z_end_hx)&&( (zsource-1) >= z_start_hx);

if (info->tid == NUM_THREADS-1)
{
	z_end_hx = zsteps-2;
	z_end_ey = zsteps-1;
}

int t;
for ( t=0; t<tsteps; t++)
{
	
	int iz;
//========update Hx========================
	for(iz=z_start_hx;iz<=z_end_hx;iz++)
	{	
		Hx[iz]+=up_hx[iz]*(Ey[iz+1]-Ey[iz]);			
	}
//	hx boundary condition - right boundary
	if (z_end_hx == zsteps-2)
	{
		Hx[zsteps-1]+=up_hx[zsteps-1]*(e3-Ey[zsteps-1]);
	}
//collect data needed for ey boundary condition
	if (z_start_hx == 0)
	{
		h3 = h2;
		h2 = h1;
		h1 = Hx[0];
	}
//	TF/SF source correction		
	if (do_hx_source)
	{
		Hx[zsource-1] -= up_hx[zsource-1]*Ey_source[t];
	}
//wait for all threads done with Hx
	pthread_barrier_wait(&time_step_barrier);

//===========update Ey=====================
//      ey boundary condition
	if (z_start_ey == 1)
	{
		Ey[0]+=up_ey[0]*(Hx[0]-h3);
	}

	for(iz=z_start_ey;iz<=z_end_ey;iz++)
	{
		Ey[iz]+=up_ey[iz]*(Hx[iz]-Hx[iz-1]);
	}
//collect data needed for ey boundary condition
	if(z_end_ey == zsteps-1)
	{
		e3 = e2;
		e2 = e1;
		e1 = Ey[zsteps-1];
	}
//	TF/SF source correction
	if (do_ey_source)
	{
		Ey[zsource]-=up_ey[zsource]*Hx_source[t];
	}
//wait all threads done wuth Ey
	pthread_barrier_wait(&time_step_barrier);

//perform Fourier transform

	complex double tmp;
	for(iz=freq_start;iz<=freq_end; iz++){
		tmp = c_pow(K[iz],t);
		ref[iz]+= Ey[0]*tmp;
		trans[iz]+=Ey[zsteps-1]*tmp;
		norm_src[iz]+=Ey_source[t]*tmp;		
	}
	if (info->tid == NUM_THREADS-1)
		Ey_time[t] = Ey[zsteps-1];

#ifdef GNUPLOT_PIPING
	if ( (N>Nspace)&&(info->tid == 0) )
	{			
		fprintf(gnuplotPipe,"plot '-' with lines\n");
		for(iz=0;iz<zsteps;iz++)
		{
			fprintf(gnuplotPipe, "%d %e\n",
				iz,
				Ey[iz]
			);
		}
		fprintf(gnuplotPipe,"e\n");
		N = 0;		
		usleep(1000000);
		
	}
	N++;
#endif

}

pthread_exit(NULL);

}