Esempio n. 1
0
int TowersLibFree(TowersLib* api)
{
   DEBUG_FUNC_NAME;

   struct Towers* pT = *api;

   ClearUndos(*api);
   ClearRedos(*api);
   ClearSolution(*api);

   free(pT->m_pBoard->m_pItems);
   pT->m_pBoard->m_pItems = NULL;

   free(pT->m_pBoard);
   pT->m_pBoard = NULL;
   free(pT);
   pT = NULL;

   *api = NULL;
   return TOWERSLIB_OK;
}
Esempio n. 2
0
int SPB::BandSolver::GetApproximateFrequencies(
	double lower, double upper,
	double tol,
	std::list<ApproximateFrequency> &freqs
){
	SPB_VERB(1, "Getting approximate frequencies in [%.14g, %.14g]\n", lower, upper);
	ClearSolution();
	PrepareOperator();
	interval_solver.SetInterval(lower, upper);
	interval_solver.SetTolerance(tol);
	interval_solver.SolveCold(this);
	
	freqs.clear();
	SPB::IntervalEigensolver::interval_list_t f = interval_solver.GetIntervals();
	for(SPB::IntervalEigensolver::interval_list_t::const_iterator i = f.begin(); i != f.end(); ++i){
		ApproximateFrequency t;
		t.lower = i->a;
		t.upper = i->b;
		t.n = i->n;
		freqs.push_back(t);
	}
}
Esempio n. 3
0
SPB::BandSolver::~BandSolver(){
	ClearSolution();
}
Esempio n. 4
0
int SPB::BandSolver_Ez::SolveK(const double *k){
	SPB_VERB(1, "Solving k-point (%.14g, %.14g)\n", k[0], k[1]);
	ClearSolution();
	
	last_k[0] = k[0];
	last_k[1] = k[1];

	// Prepare the indexing
	const size_t Ngrid = res[0] * res[1];
	
	if(impl->structure_changed_since_last_solve){
		free(impl->ind);
		impl->ind = (int*)malloc(sizeof(int) * 2*Ngrid);

		fftw_free(impl->eps_z_fft);
		impl->eps_z_fft = (complex_t*)fftw_malloc(sizeof(complex_t)*Ngrid);
		
		size_t next_index = 0;
		for(int i = 0; i < res[0]; ++i){
			const double fi = ((double)i/(double)res[0]) - 0.5;
			for(int j = 0; j < res[1]; ++j){
				const double fj = ((double)j/(double)res[1]) - 0.5;
				impl->ind[2*IDX(i,j)+0] = 4*Ngrid+next_index;
				
				// get material of this cell (simple pointwise check)
				int tag, num_poles;
				//if(2 == dim){
					double p[2] = {
						L.Lr[0]*fi + L.Lr[2]*fj,
						L.Lr[1]*fi + L.Lr[3]*fj
					};
					if(!shapeset.QueryPt(p, &tag)){
						tag = -1;
					}
				/*}else{
					double p[3] = {
						L.Lr[0]*fi + L.Lr[3]*fj + L.Lr[6]*fk,
						L.Lr[1]*fi + L.Lr[4]*fj + L.Lr[7]*fk,
						L.Lr[2]*fi + L.Lr[5]*fj + L.Lr[8]*fk
					};
					if(ShapeSet3_query_pt(shapeset.d3, p, NULL, &tag)){
					}else{
						tag = -1;
					}
				}*/
				if(-1 == tag){
					num_poles = 0;
					impl->eps_z_fft[IDX(i,j)] = 1.;
				}else{
					num_poles = material[tag].poles.size();
					impl->eps_z_fft[IDX(i,j)] = material[tag].eps_inf.value[8];
std::cout << i << "\t" << j << "\t" << impl->eps_z_fft[IDX(i,j)] << "\t" << num_poles << std::endl;
				}
				impl->ind[2*IDX(i,j)+1] = tag;
				// update next index
				next_index += 2*num_poles;
			}
		}
		//impl->N = 4*Ngrid + 3*zero_constraint + next_index;
		impl->N = 4*Ngrid + next_index;


		/*
		switch(pol){
		case 1:
			// Hx,Hy,Ez, divH
			N = (3+1)*Ngrid + 3*zero_constraint + next_index;
			break;
		case 2:
			// Hz,Ex,Ey (Hz is already div-free)
			N = (3+0)*Ngrid + 3*zero_constraint + next_index;
			break;
		default:
			// Hx,Hy,Hz,Ex,Ey,Ez, divH
			N = (6+1)*Ngrid + 6*zero_constraint + next_index;
			break;
		}*/
		
		fftw_plan plan_eps = fftw_plan_many_dft(
			2/*rank*/, res, 1 /*howmany*/,
			(fftw_complex*)impl->eps_z_fft, NULL/*inembed*/,
			1/*istride*/, Ngrid/*idist*/,
			(fftw_complex*)impl->eps_z_fft, NULL/*onembed*/,
			1/*ostride*/, Ngrid/*odist*/,
			FFTW_BACKWARD, FFTW_ESTIMATE);
		fftw_execute(plan_eps);
		fftw_destroy_plan(plan_eps);
		impl->structure_changed_since_last_solve = false;
	}
	
	sparse_t::entry_map_t Amap;
	sparse_t::entry_map_t Bmap;
	
	{
		const double Lrl[2] = {
			hypot(L.Lr[0], L.Lr[1]),
			hypot(L.Lr[2], L.Lr[3])
		};
		const double idr[2] = {
			(double)res[0] / Lrl[0],
			(double)res[1] / Lrl[1]
		};
				
		const complex_t Bloch[2] = {
			complex_t(cos(k[0]*2*M_PI), sin(k[0]*2*M_PI)),
			complex_t(cos(k[1]*2*M_PI), sin(k[1]*2*M_PI))
		};
		for(int i = 0; i < res[0]; ++i){
			for(int j = 0; j < res[1]; ++j){
				size_t row, col;
				complex_t coeff;
				
				const int curmat = impl->ind[2*IDX(i,j)+1];
				complex_t eps_z(1.);
				if(curmat >= 0){
					eps_z = material[curmat].eps_inf.value[8];
				}
				
#define ASET(ROW,COL,COEFF) Amap[sparse_t::index_t((ROW),(COL))] = (COEFF)
#define BSET(ROW,COL,COEFF) Bmap[sparse_t::index_t((ROW),(COL))] = (COEFF)
				// divH ~ dx Hx + dy Hy + dz Hz
				// E ~ -i wp V
				// V ~ +i wp E - i G V - i w0 P
				// P ~ +i w0 V
			
				//for(size_t idbg=0;idbg<ne+nh+1;++idbg){
					//ASET(row0+idbg,row0+idbg,1); // for debugging
				//}
			
				// Hx ~ -i dy Ez
				// Hy ~ +i dx Ez
				// Ez ~ -i dy Hx + i dx Hy

				// Hx = complex_t(0,-idr[1]) * (Ez[i,j+1,k] - Ez[i,j,k])
				row = HX_OFF + IDX(i,j);
				coeff = complex_t(0,-idr[1]);
				col = EZ_OFF + IDX(i,j); // Ez
				ASET(row,col, -coeff);
				if(j+1 == res[1]){
					col = EZ_OFF + IDX(i,0); // Ez
					ASET(row,col, coeff/Bloch[1]);
				}else{
					col = EZ_OFF + IDX(i,j+1); // Ez
					ASET(row,col, coeff);
				}
				BSET(row,row, 1);
				
				// Hy = complex_t(0, idr[0]) * (Ez[i+1,j,k] - Ez[i,j,k])
				row = HY_OFF + IDX(i,j);
				coeff = complex_t(0, idr[0]);
				col = EZ_OFF + IDX(i,j); // Ez
				ASET(row,col, -coeff);
				if(i+1 == res[0]){
					col = EZ_OFF + IDX(0,j); // Ez
					ASET(row,col, coeff/Bloch[0]);
				}else{
					col = EZ_OFF + IDX(i+1,j); // Ez
					ASET(row,col, coeff);
				}
				BSET(row,row, 1);
				
				// divH = idr[0] * (Hx[i+1,j,k] - Hx[i,j,k])
				//      + idr[1] * (Hy[i,j+1,k] - Hx[i,j,k])
				row = DIVH_OFF + IDX(i,j);
				coeff = complex_t(0,idr[0]);
				col = HX_OFF + IDX(i,j); // Hx
				ASET(row,col, -coeff);
				ASET(col,row, -std::conj(coeff));
				if(i+1 == res[0]){
					col = HX_OFF + IDX(0,j); // Hx
					ASET(row,col, coeff/Bloch[0]);
					ASET(col,row, std::conj(coeff/Bloch[0]));
				}else{
					col = HX_OFF + IDX(i+1,j); // Hx
					ASET(row,col, coeff);
					ASET(col,row, std::conj(coeff));
				}
				
				coeff = complex_t(0,idr[1]);
				col = HY_OFF + IDX(i,j); // Hy
				ASET(row,col, -coeff);
				ASET(col,row, -std::conj(coeff));
				if(j+1 == res[1]){
					col = HY_OFF + IDX(i,0); // Hy
					ASET(row,col, coeff/Bloch[1]);
					ASET(col,row, std::conj(coeff/Bloch[1]));
				}else{
					col = HY_OFF + IDX(i,j+1); // Hy
					ASET(row,col, coeff);
					ASET(col,row, std::conj(coeff));
				}
				BSET(row,row, 0);

				// Ez = complex_t(0,-idr[1]) * (Hx[i,j,k] - Hx[i,j-1,k])
				//    + complex_t(0, idr[0]) * (Hy[i,j,k] - Hy[i-1,j,k])
				row = EZ_OFF + IDX(i,j);
				
				coeff = complex_t(0,-idr[1]);
				col = HX_OFF + IDX(i,j); // Hx
				ASET(row,col, coeff);
				if(0 == j){
					col = HX_OFF + IDX(i,res[1]-1); // Hx
					ASET(row,col, -coeff*Bloch[1]);
				}else{
					col = HX_OFF + IDX(i,j-1); // Hx
					ASET(row,col, -coeff);
				}
				
				coeff = complex_t(0, idr[0]);
				col = HY_OFF + IDX(i,j); // Hy
				ASET(row,col, coeff);
				if(0 == i){
					col = HY_OFF + IDX(res[0]-1,j); // Hy
					ASET(row,col, -coeff*Bloch[0]);
				}else{
					col = HY_OFF + IDX(i-1,j); // Hy
					ASET(row,col, -coeff);
				}
				BSET(row,row, eps_z);
				
				if(curmat >= 0){
					const int row0 = impl->ind[2*IDX(i,j)+0];
					const Material &m = material[curmat];
					const size_t np = m.poles.size();
					for(size_t p = 0; p < np; ++p){
						row = row0 + 2*p + 0; // V_p
						coeff = complex_t(0, m.poles[p].omega_p) * eps_z;
						col = EZ_OFF + IDX(i,j); // E
						ASET(row,col, coeff);
						ASET(col,row, std::conj(coeff));
						
						if(0 != m.poles[p].Gamma){
							coeff = complex_t(0,-m.poles[p].Gamma) * eps_z;
							ASET(row,row, coeff);
						}
						BSET(row,row, 1);
						
						
						coeff = complex_t(0, -m.poles[p].omega_0) * eps_z;
						col = row0 + 2*p + 1; // P
						ASET(row,col, coeff);
						ASET(col,row, std::conj(coeff));
						BSET(col,col, 1);
					}
				}
				
				/*
				}else if(2 == pol){
					// Hz ~ +i dy Ex - i dx Ey
					// Ex ~ +i dy Hz
					// Ey ~ -i dx Hz
				}else{
					// Hx ~ +i dz Ey - i dy Ez
					// Hy ~ -i dz Ex + i dx Ez
					// Hz ~ +i dy Ex - i dx Ey
					// Ex ~ -i dz Hy + i dy Hz
					// Ey ~ +i dz Hx - i dx Hz
					// Ez ~ -i dy Hx + i dx Hy
				}*/
			}
		}
	}
	impl->A = new sparse_t(impl->N,impl->N, Amap);
	impl->B = new sparse_t(impl->N,impl->N, Bmap);
	
	if(0){
		std::cout << "A="; RNP::Sparse::PrintSparseMatrix(*(impl->A)) << ";" << std::endl;
		std::cout << "B="; RNP::Sparse::PrintSparseMatrix(*(impl->B)) << ";" << std::endl;
		exit(0);
	}
	/*
	complex_t *tmp = new complex_t[4*Ngrid];
	complex_t *tmp2 = new complex_t[16*Ngrid*Ngrid];
	for(size_t i = 0; i < res[0]; ++i){
		for(size_t j = 0; j < res[1]; ++j){
			tmp[IDX(i,j)] = 0;
		}
	}
	for(size_t i = 0; i < res[0]; ++i){
		for(size_t j = 0; j < res[1]; ++j){
			tmp[IDX(i,j)] = 1;
			Precond(tmp, &tmp2[0+IDX(i,j)*Ngrid]);
			tmp[IDX(i,j)] = 0;
		}
	}
	delete [] tmp2;
	delete [] tmp;
	*/
	return solver->Solve();
	/*
	{
		const size_t n = 4*Ngrid;
		complex_t *x = (complex_t*)fftw_malloc(sizeof(complex_t)*n);
		complex_t *y = (complex_t*)fftw_malloc(sizeof(complex_t)*n);
		complex_t *z = (complex_t*)fftw_malloc(sizeof(complex_t)*n);
		const double theta = 0.6;
		
		memset(x, 0, sizeof(complex_t)*n);
		for(int i = 0; i < n; ++i){
			x[i] = frand();
		}
		std::cout << "x = "; RNP::IO::PrintVector(n, x, 1) << std::endl;
		
		Aop(x, y);
		Bop(x, z);
		RNP::TBLAS::Axpy(n, -theta, z,1, y,1);
		// At this point y = A*x-theta*B*x
		std::cout << "y = "; RNP::IO::PrintVector(n, y, 1) << std::endl;
		
		Op(n, theta, y, z);
		// At this point z should be the same as x
		
		std::cout << "z = "; RNP::IO::PrintVector(n, z, 1) << std::endl;
		
		RNP::TBLAS::Axpy(n, -1., x,1,z,1);
		std::cout << "diff = "; RNP::IO::PrintVector(n, z, 1) << std::endl;
		
		fftw_free(z);
		fftw_free(y);
		fftw_free(x);
	}*/
	
	
	/*
	size_t n_wanted = 10;
	size_t ncv = 2*n_wanted+1;
	SPB::complex_t *w = new SPB::complex_t[n_wanted+ncv*4*Ngrid];
	SPB::complex_t *v = w+n_wanted;
	int nconv = RNP::IRA::ShiftInvert(
		4*Ngrid, 0.0, &op_, &bv_,
		n_wanted, ncv, &RNP::IRA::LargestMagnitude,
		w, v, 4*Ngrid,
		NULL,
		NULL,
		(void*)this,
		(void*)this);
	for(size_t i = 0; i < n_wanted;++i){
		std::cout << w[i] << std::endl;
	}
	*/
}