DDMContextOSRCVector:: DDMContextOSRCVector(const GroupOfElement& domain, vector<const GroupOfElement*>& dirichlet, const FunctionSpace& fSpace, const FunctionSpace& fSpaceG, const vector<const FunctionSpaceVector*>& phi, const vector<const FunctionSpaceScalar*>& rho, const FunctionSpaceVector& r, double k, Complex keps, int NPade, double theta){ // Check if vector // if(fSpace.isScalar()) throw Exception("DDMContextOSRCVector: need a vector function space"); // Data for OSRCVector // this->domain = &domain; this->fSpace = &fSpace; this->fSpaceG = &fSpaceG; this->dirichlet = dirichlet; this->phi = φ this->rho = ρ this->r = &r; this->NPade = NPade; this->theta = theta; this->k = k; this->keps = keps; }
void Interpolator<double>:: interpolate(const MElement& element, const FunctionSpace& fs, const std::vector<double>& coef, const fullVector<double>& xyz, fullVector<double>& value){ // Scalar or Vector ? const bool isScalar = fs.isScalar(); if(isScalar){ // Function Space Scalar const FunctionSpaceScalar* fsScalar = static_cast<const FunctionSpaceScalar*>(&fs); // Alloc value value.resize(1); // Interpolate value(0) = fsScalar->interpolate(element, coef, xyz); } else{ // Function Space Vector const FunctionSpaceVector* fsVector = static_cast<const FunctionSpaceVector*>(&fs); // Alloc & Interpolate value = fsVector->interpolate(element, coef, xyz); } }
void Interpolator<Complex>:: interpolate(const MElement& element, const FunctionSpace& fs, const std::vector<Complex>& coef, const fullVector<double>& xyz, fullVector<Complex>& value){ // Real & Imaginary // const size_t size = coef.size(); vector<double> coefReal(size); vector<double> coefImag(size); for(size_t i = 0; i < size; i++) coefReal[i] = coef[i].real(); for(size_t i = 0; i < size; i++) coefImag[i] = coef[i].imag(); // Scalar or Vector ? const bool isScalar = fs.isScalar(); if(isScalar){ // Function Space Scalar const FunctionSpaceScalar* fsScalar = static_cast<const FunctionSpaceScalar*>(&fs); // Alloc value value.resize(1); // Interpolate double real = fsScalar->interpolate(element, coefReal, xyz); double imag = fsScalar->interpolate(element, coefImag, xyz); // Complex value(0) = Complex(real, imag); } else{ // Function Space Vector const FunctionSpaceVector* fsVector = static_cast<const FunctionSpaceVector*>(&fs); // Alloc value value.resize(3); // Interpolate fullVector<double> real = fsVector->interpolate(element, coefReal, xyz); fullVector<double> imag = fsVector->interpolate(element, coefImag, xyz); // Complex value(0) = Complex(real(0), imag(0)); value(1) = Complex(real(1), imag(1)); value(2) = Complex(real(2), imag(2)); } }
void compute(const Options& option){ // Get Type // int type; if(option.getValue("-type")[1].compare("scalar") == 0){ cout << "Scalar Waveguide" << endl << flush; type = scal; } else if(option.getValue("-type")[1].compare("vector") == 0){ cout << "Vetorial Waveguide" << endl << flush; type = vect; } else throw Exception("Bad -type: %s", option.getValue("-type")[1].c_str()); // Get Parameters // const size_t nDom = atoi(option.getValue("-n")[1].c_str()); k = atof(option.getValue("-k")[1].c_str()); const size_t order = atoi(option.getValue("-o")[1].c_str()); const double sigma = atof(option.getValue("-sigma")[1].c_str()); cout << "Wavenumber: " << k << endl << "Order: " << order << endl << "# Domain: " << nDom << endl << flush; // Get Domains // Mesh msh(option.getValue("-msh")[1]); GroupOfElement source(msh.getFromPhysical(1 * nDom + 1)); GroupOfElement zero(msh.getFromPhysical(2 * nDom + 2)); GroupOfElement infinity(msh.getFromPhysical(2 * nDom + 1)); GroupOfElement volume(msh); vector<GroupOfElement*> perVolume(nDom); for(size_t i = 0; i < nDom; i++){ perVolume[i] = new GroupOfElement(msh.getFromPhysical(i + 1)); volume.add(*perVolume[i]); } // Full Domain // vector<const GroupOfElement*> domain(4); domain[0] = &volume; domain[1] = &source; domain[2] = &zero; domain[3] = &infinity; // Function Space // FunctionSpace* fs = NULL; if(type == scal) fs = new FunctionSpaceScalar(domain, order); else fs = new FunctionSpaceVector(domain, order); // Steady Wave Formulation // const double Z0 = 119.9169832 * M_PI; const Complex epsr(1, 1 / k * Z0 * sigma); const Complex mur(1, 0); FormulationSteadyWave<Complex> wave(volume, *fs, k); FormulationImpedance impedance(infinity, *fs, k, epsr, mur); // Solve // System<Complex> system; system.addFormulation(wave); system.addFormulation(impedance); // Constraint if(fs->isScalar()){ SystemHelper<Complex>::dirichlet(system, *fs, zero , fZeroScal); SystemHelper<Complex>::dirichlet(system, *fs, source, fSourceScal); } else{ SystemHelper<Complex>::dirichlet(system, *fs, zero , fZeroVect); SystemHelper<Complex>::dirichlet(system, *fs, source, fSourceVect); } // Assemble system.assemble(); cout << "Assembled: " << system.getSize() << endl << flush; // Sove system.solve(); cout << "Solved!" << endl << flush; // Draw Solution // try{ option.getValue("-nopos"); } catch(...){ cout << "Writing solution..." << endl << flush; stringstream stream; try{ vector<string> name = option.getValue("-name"); stream << name[1]; } catch(...){ stream << "waveguide"; } try{ // Get Visu Mesh // vector<string> visuStr = option.getValue("-interp"); Mesh visuMsh(visuStr[1]); // Get Solution // map<Dof, Complex> sol; FormulationHelper::initDofMap(*fs, volume, sol); system.getSolution(sol, 0); // Interoplate // for(size_t i = 0; i < nDom; i++){ // GroupOfElement to interoplate on GroupOfElement visuGoe(visuMsh.getFromPhysical(i + 1)); // Interpolation stringstream name; name << stream.str() << i << ".dat"; map<const MVertex*, vector<Complex> > map; Interpolator<Complex>::interpolate(*perVolume[i], visuGoe, *fs,sol,map); Interpolator<Complex>::write(name.str(), map); } } catch(...){ FEMSolution<Complex> feSol; system.getSolution(feSol, *fs, volume); feSol.write(stream.str()); } } // Clean // for(size_t i = 0; i < nDom; i++) delete perVolume[i]; delete fs; }