예제 #1
0
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       = &phi;
  this->rho       = &rho;
  this->r         = &r;
  this->NPade     = NPade;
  this->theta     = theta;
  this->k         = k;
  this->keps      = keps;
}
예제 #2
0
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);
  }
}
예제 #3
0
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));
  }
}
예제 #4
0
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;
}