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)); }
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); }