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; }
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); } }
SPB::BandSolver::~BandSolver(){ ClearSolution(); }
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; } */ }