Exemplo n.º 1
0
void compute(const Options& option){
  // Get Domains //
  Mesh msh(option.getValue("-msh")[1]);
  GroupOfElement    volume = msh.getFromPhysical(7);
  GroupOfElement boundary0 = msh.getFromPhysical(6);
  GroupOfElement boundary1 = msh.getFromPhysical(5);

  // Full Domain //
  vector<const GroupOfElement*> domain(3);
  domain[0] = &volume;
  domain[1] = &boundary0;
  domain[2] = &boundary1;

  // Get Order //
  size_t order = atoi(option.getValue("-o")[1].c_str());

  // Function Space //
  FunctionSpaceScalar fs(domain, order);

  // Compute //
  FormulationPoisson poisson(volume, fs, fSource, fMaterial);

  System<double> sysPoisson;
  sysPoisson.addFormulation(poisson);

  SystemHelper<double>::dirichlet(sysPoisson, fs, boundary0, fDirichlet0);
  SystemHelper<double>::dirichlet(sysPoisson, fs, boundary1, fDirichlet1);

  cout << "Poisson -- Order " << order
       << ": " << sysPoisson.getSize()
       << endl << flush;

  sysPoisson.assemble();
  sysPoisson.solve();

  // Write Sol //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    FEMSolution<double> feSol;
    sysPoisson.getSolution(feSol, fs, volume);
    feSol.write("poisson");
  }
}
Exemplo n.º 2
0
void fem(fullVector<double> (*f)(fullVector<double>& xyz),
         GroupOfElement& domain,
         size_t order,
         const fullMatrix<double>& point,
         fullMatrix<double>& sol,
         bool nopos){
  // Projection //
  stringstream stream;

  FunctionSpaceVector fSpace(domain, order);
  FormulationProjection<double> projection(domain, fSpace, f);
  System<double> sysProj;

  sysProj.addFormulation(projection);

  // Assemble and Solve //
  sysProj.assemble();
  sysProj.solve();

  // Get Dofs //
  set<Dof> dof;
  fSpace.getKeys(domain, dof);

  set<Dof>::iterator    end = dof.end();
  set<Dof>::iterator     it = dof.begin();
  map<Dof, double>   sysSol;

  for(; it != end; it++)
    sysSol.insert(pair<Dof, double>(*it, 0));

  // Get Solution //
  sysProj.getSolution(sysSol, 0);

  // Interpolate on Ref Points //
  Interpolator<double>::interpolate(domain, fSpace, sysSol, point, sol);

  // Post-processing //
  if(!nopos){
    FEMSolution<double> feSol;
    stream << "projection_Mesh" << domain.getNumber() << "_Order" << order;

    sysProj.getSolution(feSol, fSpace, domain);
    feSol.write(stream.str());
  }
}
Exemplo n.º 3
0
void compute(const Options& option){
  // Timers
  Timer full;
  Timer timer;

  // Get Domains //
  full.start();
  timer.start();
  cout << "Reading... " << flush;

  Mesh msh(option.getValue("-msh")[1]);

  GroupOfElement PMLxyz   = msh.getFromPhysical(1000);
  GroupOfElement PMLxz    = msh.getFromPhysical(1001);
  GroupOfElement PMLyz    = msh.getFromPhysical(1002);
  GroupOfElement PMLxy    = msh.getFromPhysical(1003);
  GroupOfElement PMLz     = msh.getFromPhysical(1004);
  GroupOfElement PMLy     = msh.getFromPhysical(1005);
  GroupOfElement PMLx     = msh.getFromPhysical(1006);
  GroupOfElement Scat_In  = msh.getFromPhysical(1008);
  GroupOfElement Scat_Out = msh.getFromPhysical(1007);

  // Full Domain
  vector<const GroupOfElement*> All_domains(9);
  All_domains[0] = &Scat_In;
  All_domains[1] = &Scat_Out;
  All_domains[2] = &PMLxyz;
  All_domains[3] = &PMLxz;
  All_domains[4] = &PMLyz;
  All_domains[5] = &PMLxy;
  All_domains[6] = &PMLz;
  All_domains[7] = &PMLy;
  All_domains[8] = &PMLx;

  // Full Domain (for Visu)
  GroupOfElement All_domains_visu(msh);
  All_domains_visu.add(Scat_In);
  All_domains_visu.add(Scat_Out);
  All_domains_visu.add(PMLxyz);
  All_domains_visu.add(PMLxz);
  All_domains_visu.add(PMLyz);
  All_domains_visu.add(PMLxy);
  All_domains_visu.add(PMLz);
  All_domains_visu.add(PMLy);
  All_domains_visu.add(PMLx);

  timer.stop();
  cout << "done in " << timer.time() << "[" << timer.unit() << "]! "
       << endl << flush;

  // FunctionSpace //
  const size_t order = atoi(option.getValue("-o")[1].c_str());
  FunctionSpaceVector fs(All_domains, order);

  // Formulation //
  const double k = (Constant::omega0 / Constant::cel);

  timer.start();
  cout << "Assembling... " << flush;

  FormulationSteadyWave<Complex> in(Scat_In, fs, k,
                                    Material::In::Nu,
                                    Material::In::Epsilon,
                                    Signal::In::source);

  FormulationSteadyWave<Complex> out(Scat_Out, fs, k,
                                     Material::Out::Nu,
                                     Material::Out::Epsilon,
                                     Signal::Out::source);

  FormulationSteadyWave<Complex> xyz(PMLxyz, fs, k,
                                     Material::XYZ::Nu,
                                     Material::XYZ::Epsilon,
                                     Signal::PML::source);

  FormulationSteadyWave<Complex> xz(PMLxz, fs, k,
                                    Material::XZ::Nu,
                                    Material::XZ::Epsilon,
                                    Signal::PML::source);

  FormulationSteadyWave<Complex> yz(PMLyz, fs, k,
                                    Material::YZ::Nu,
                                    Material::YZ::Epsilon,
                                    Signal::PML::source);

  FormulationSteadyWave<Complex> xy(PMLxy, fs, k,
                                    Material::XY::Nu,
                                    Material::XY::Epsilon,
                                    Signal::PML::source);

  FormulationSteadyWave<Complex> x(PMLx, fs, k,
                                   Material::X::Nu,
                                   Material::X::Epsilon,
                                   Signal::PML::source);

  FormulationSteadyWave<Complex> y(PMLy, fs, k,
                                   Material::Y::Nu,
                                   Material::Y::Epsilon,
                                   Signal::PML::source);

  FormulationSteadyWave<Complex> z(PMLz, fs, k,
                                   Material::Z::Nu,
                                   Material::Z::Epsilon,
                                   Signal::PML::source);
  // System //
  System<Complex> sys;

  sys.addFormulation(in);
  sys.addFormulation(out);
  sys.addFormulation(xyz);
  sys.addFormulation(xz);
  sys.addFormulation(yz);
  sys.addFormulation(xy);
  sys.addFormulation(x);
  sys.addFormulation(y);
  sys.addFormulation(z);

  sys.assemble();

  timer.stop();
  cout << "done in " << timer.time() << "[" << timer.unit() << "]! "
       << endl << flush;

  timer.start();
  cout << "Solving: " << sys.getSize() << "... " << flush;

  sys.solve();

  timer.stop();
  cout << "done in " << timer.time() << "[" << timer.unit() << "]! "
       << endl << flush;

  // Post-Pro //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    timer.start();
    cout << "Drawing... " << flush;

    FEMSolution<Complex> feSol;
    sys.getSolution(feSol, fs, All_domains_visu);
    feSol.write("scat");

    timer.stop();
    cout << "done in " << timer.time() << "[" << timer.unit() << "]! "
         << endl << flush;
  }

  // Full time
  full.stop();
  cout << "Elapsed time: " << full.time() << "[" << full.unit() << "]"
       << endl << flush;
}
Exemplo n.º 4
0
// Compute //
void compute(const Options& option){
  // MPI //
  int nProcs;
  int myProc;
  MPIOStream cout(0, std::cout);

  MPI_Comm_size(MPI_COMM_WORLD,&nProcs);
  MPI_Comm_rank(MPI_COMM_WORLD,&myProc);

  // Get parameters //
  // Wavenumber
  double f  = atof(option.getValue("-f")[1].c_str());
  Omega0    = 2 * Pi * f;
  double  k = Omega0 / C0;

  // FEM orders
  const int orderVol = atoi(option.getValue("-ov")[1].c_str());
  const int orderSur = atoi(option.getValue("-ob")[1].c_str());

  // OSRC
  double    ck = 0;
  int    NPade = 4;
  Complex keps = k + Complex(0, k * ck);

  // Get Domains //
  cout << "Reading domain... " << endl << flush;
  Mesh msh(option.getValue("-msh")[1]);

  GroupOfElement         air(msh.getFromPhysical(1007,   myProc + 1));
  GroupOfElement         rod(msh.getFromPhysical(1008,   myProc + 1));
  GroupOfElement         src(msh.getFromPhysical(1009,   myProc + 1));
  GroupOfElement    infinity(msh.getFromPhysical(1010,   myProc + 1));
  GroupOfElement ddmBoundary(msh.getFromPhysical(40000 + myProc + 1));

  // Full domain
  vector<const GroupOfElement*> domain(5);
  domain[0] = &air;
  domain[1] = &rod;
  domain[2] = &src;
  domain[3] = &infinity;
  domain[4] = &ddmBoundary;

  // Dirichlet boundary container
  vector<const GroupOfElement*> dirichlet(1);
  dirichlet[0] = &src;

  // DDM boundary container
  vector<const GroupOfElement*> ddmBoundaryDomain(1);
  ddmBoundaryDomain[0] = &ddmBoundary;

  // Function space //
  FunctionSpaceVector fs(           domain, orderVol);
  FunctionSpaceVector fG(ddmBoundaryDomain, orderSur);

  vector<const FunctionSpaceVector*> OsrcPhi(NPade, NULL);
  vector<const FunctionSpaceScalar*> OsrcRho(NPade, NULL);
  FunctionSpaceVector                OsrcR(ddmBoundaryDomain, orderVol);

  for(int j = 0; j < NPade; j++){
    OsrcPhi[j] = new FunctionSpaceVector(ddmBoundaryDomain, orderVol);

    if(orderVol == 0)
      OsrcRho[j] = new FunctionSpaceScalar(ddmBoundaryDomain, 1);
    else
      OsrcRho[j] = new FunctionSpaceScalar(ddmBoundaryDomain, orderVol);
  }

  // Formulations //
  cout << "FEM terms... " << endl << flush;

  // Waves
  FormulationSteadyWave<Complex>   waveAir(air, fs, k);
  FormulationSteadyWave<Complex>   waveRod(rod, fs, k, nuRRod, epsRRod, sVol);
  FormulationSilverMuller        radiation(infinity, fs, k);

  // Ddm context
  map<Dof, Complex> ddmG;
  map<Dof, Complex> rhsG;
  FormulationHelper::initDofMap(fG, ddmBoundary, ddmG);
  FormulationHelper::initDofMap(fG, ddmBoundary, rhsG);


  DDMContextOSRCVector context(ddmBoundary, dirichlet,
                               fs, fG, OsrcPhi, OsrcRho, OsrcR,
                               k, keps, NPade, Pi / 2);
  context.setDDMDofs(ddmG);

  // Ddm
  FormulationOSRCVector         ddm(context);
  FormulationUpdateOSRCVector upDdm(context);

  // Dummy
  FormulationDummy<Complex> dummy;

  // Container
  FormulationContainer<Complex> allFem;
  allFem.addFormulation(waveAir);
  allFem.addFormulation(waveRod);
  allFem.addFormulation(radiation);

  // Solve non-homogenous problem //
  cout << "Solving non homogenous problem" << endl << flush;

  System<Complex>* nonHomogenous = new System<Complex>;
  nonHomogenous->addFormulation(allFem);
  nonHomogenous->addFormulation(ddm);

  SystemHelper<Complex>::dirichlet(*nonHomogenous, fs, src, fSrc);

  nonHomogenous->assemble();
  nonHomogenous->solve();

  // Solve non-homogenous DDM problem //
  cout << "Computing right hand side" << endl << flush;

  context.setSystem(*nonHomogenous);
  upDdm.update(); // update volume solution (at DDM border)

  System<Complex>* nonHomogenousDDM = new System<Complex>;
  nonHomogenousDDM->addFormulation(upDdm);

  nonHomogenousDDM->assemble();
  nonHomogenousDDM->solve();
  nonHomogenousDDM->getSolution(rhsG, 0);

  // Clear Systems //
  delete nonHomogenous;
  delete nonHomogenousDDM;

  // DDM Solver //
  cout << "Solving DDM problem" << endl << flush;
  SolverDDM* solver = new SolverDDM(allFem, dummy, context, ddm, upDdm, rhsG);

  // Solve
  int maxIt = 1000;
  solver->setMaximumIteration(maxIt);
  solver->setRestart(maxIt); // No restart!
  cout << " ! Warning: no restart ! " << endl;
  solver->solve();

  // Get Solution
  solver->getSolution(ddmG);
  context.setDDMDofs(ddmG);

  // Clear DDM
  delete solver;

  // Full Problem //
  cout << "Solving full problem" << endl << flush;
  ddm.update();

  System<Complex> full;
  full.addFormulation(allFem);
  full.addFormulation(ddm);

  SystemHelper<Complex>::dirichlet(full, fs, src, fSrc);

  full.assemble();
  full.solve();

  // Draw Solution //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    cout << "Writing full problem" << endl << flush;

    FEMSolution<Complex> feSol;
    full.getSolution(feSol, fs, domain);

    feSol.setSaveMesh(false);
    feSol.setBinaryFormat(true);
    feSol.setParition(myProc + 1);
    feSol.write("boubouchon");
  }

  // Give peak virtual memory //
  double  myVmPeak = getPeakMemory();
  double* alVmPeak = new double[nProcs];

  MPI_Allgather(&myVmPeak,1,MPI_DOUBLE, alVmPeak,1,MPI_DOUBLE, MPI_COMM_WORLD);

  cout << "Peak VM:" << endl << flush;
  for(int i = 0; i < nProcs; i++)
    cout << " ** Process " << i << ": " << alVmPeak[i] << " MB"
         << endl << flush;

  // Give max peak VMem accross all processes //
  int maxIdx = 0;
  for(int i = 1; i < nProcs; i++)
    if(alVmPeak[maxIdx] < alVmPeak[i])
      maxIdx = i;

  cout << "Maximum Peak VM accross MPI processes:" << endl
       << " ** Process " << maxIdx << ": " << alVmPeak[maxIdx] << " MB"
       << endl << flush;

  // Give systems sizes //
  int  mySize = full.getSize();
  int* alSize = new int[nProcs];

  MPI_Allgather(&mySize, 1, MPI_INT, alSize, 1, MPI_INT, MPI_COMM_WORLD);

  cout << "Volume system size:" << endl << flush;
  for(int i = 0; i < nProcs; i++)
    cout << " ** Process " << i << ": " << alSize[i] << " unknowns"
         << endl << flush;

  // Clear //
  for(int j = 0; j < NPade; j++){
    delete OsrcPhi[j];
    delete OsrcRho[j];
  }

  delete[] alVmPeak;
  delete[] alSize;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
void compute(const Options& option){
  // Start Timer //
  Timer timer, assemble, solve;
  timer.start();

  // Get Domains //
  Mesh msh(option.getValue("-msh")[1]);
  GroupOfElement volume     = msh.getFromPhysical(7);
  GroupOfElement source     = msh.getFromPhysical(5);
  GroupOfElement freeSpace  = msh.getFromPhysical(6);

  // Full Domain //
  vector<const GroupOfElement*> domain(3);
  domain[0] = &volume;
  domain[1] = &source;
  domain[2] = &freeSpace;

  // Get Parameters //
  const double k     = atof(option.getValue("-k")[1].c_str());
  const size_t order = atoi(option.getValue("-o")[1].c_str());

  // Formulation //
  assemble.start();
  FunctionSpaceScalar fs(domain, order);
  FunctionSpaceScalar lfs(domain, order);

  FormulationSteadyWave<complex<double> > wave(volume, fs, k);
  FormulationSilverMuller         silverMuller(freeSpace, fs, k);
  FormulationLagrange  lagrange(source, fs, lfs, fSourceReal);

  // System //
  System<complex<double> > sys;
  sys.addFormulation(wave);
  sys.addFormulation(silverMuller);
  sys.addFormulation(lagrange);

  cout << "Free Space Lagrange contrainted (Order: "  << order
       << " --- Wavenumber: "                         << k
       << "): " << sys.getSize() << endl;

  // Assemble //
  sys.assemble();
  assemble.stop();

  cout << "Assembled: " << assemble.time() << assemble.unit()
       << endl << flush;

  // Solve //
  solve.start();
  sys.solve();
  solve.stop();

  cout << "Solved: " << solve.time() << solve.unit()
       << endl << flush;

  // Write Sol //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    FEMSolution<complex<double> > feSolVol;
    FEMSolution<complex<double> > feSolSrc;
    FEMSolution<complex<double> > feSolMul;

    sys.getSolution(feSolVol, fs,  volume);
    sys.getSolution(feSolSrc, fs,  source);
    sys.getSolution(feSolMul, lfs, source);

    feSolVol.write("lagrVol");
    feSolSrc.write("lagrSrc");
    feSolMul.write("lagrMul");
  }

  // Timer -- Finalize -- Return //
  timer.stop();

  cout << "Elapsed Time: " << timer.time()
       << " s"             << endl;
}
Exemplo n.º 7
0
void compute(const Options& option){
  // Start Timer //
  Timer timer, assemble, solve;
  timer.start();

  // Get Domains //
  Mesh msh(option.getValue("-msh")[1]);
  GroupOfElement volume = msh.getFromPhysical(7);
  GroupOfElement source = msh.getFromPhysical(5);
  GroupOfElement wall   = msh.getFromPhysical(6);

  // Full Domain //
  vector<const GroupOfElement*> domain(3);
  domain[0] = &volume;
  domain[1] = &source;
  domain[2] = &wall;

  // Get Parameters //
  const double k     = atof(option.getValue("-k")[1].c_str());
  const size_t order = atoi(option.getValue("-o")[1].c_str());

  // Get Type //
  size_t type;

  if(option.getValue("-type")[1].compare("scalar") == 0){
    type = scal;
    cout << "Scalar ";
  }

  else if(option.getValue("-type")[1].compare("vector") == 0){
    type = vect;
    cout << "Vectorial ";
  }

  else
    throw Exception("Bad -type: %s", option.getValue("-type")[1].c_str());

  // Function Space //
  assemble.start();
  FunctionSpace* fs = NULL;

  if(type == scal)
    fs = new FunctionSpaceScalar(domain, order);
  else
    fs = new FunctionSpaceVector(domain, order);

  // Formulation & System //
  FormulationSteadyWave<double> wave(volume, *fs, k);
  System<double> sys;
  sys.addFormulation(wave);

  // Dirichlet //
  if(type == scal){
    SystemHelper<double>::dirichlet(sys, *fs, source, fSourceScal);
    SystemHelper<double>::dirichlet(sys, *fs, wall,   fWallScal);
  }

  else{
    SystemHelper<double>::dirichlet(sys, *fs, source, fSourceVec);
    SystemHelper<double>::dirichlet(sys, *fs, wall,   fWallVec);
  }

  cout << "Steady Wave (Order: " << order
       << " --- Wavenumber: "    << k << ")" << endl;

  // Assemble and solve //
  sys.assemble();
  assemble.stop();
  cout << "Assembled: " << sys.getSize() << " "
       << "(" << assemble.time() << assemble.unit() << ")" << endl << flush;

  solve.start();
  sys.solve();
  solve.stop();
  cout << "Solved (" << solve.time() << solve.unit() << ")" << endl << flush;

  // Write Sol //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    FEMSolution<double> feSol;
    sys.getSolution(feSol, *fs, volume);
    feSol.write("swave");
  }

  // Clean //
  delete fs;

  // Timer -- Finalize -- Return //
  timer.stop();

  cout << "Elapsed Time: " << timer.time() << timer.unit() << endl;
}
Exemplo n.º 8
0
void compute(const Options& option){
  // MPI std::cout //
  MPIOStream cout(0, std::cout);
  int        myProc;
  int        nProcs;

  MPI_Comm_rank(MPI_COMM_WORLD, &myProc);
  MPI_Comm_size(MPI_COMM_WORLD, &nProcs);

  // Get PML Data //
  cout << "Reading PML... " << endl << flush;
  PML::read(option.getValue("-pml")[1]);

  // Get Domains //
  cout << "Reading domain... " << endl << flush;
  Mesh msh(option.getValue("-msh")[1]);

  GroupOfElement* Air;
  GroupOfElement* PMLx;
  GroupOfElement* PMLxy;
  GroupOfElement* PMLy;
  GroupOfElement* Mirror;
  GroupOfElement* Frame;
  GroupOfElement* LineOY;
  GroupOfElement* OutPML;

  if(nProcs != 1){
    Air    = new GroupOfElement(msh.getFromPhysical(4000, myProc + 1));
    PMLx   = new GroupOfElement(msh.getFromPhysical(1000, myProc + 1));
    PMLxy  = new GroupOfElement(msh.getFromPhysical(2000, myProc + 1));
    PMLy   = new GroupOfElement(msh.getFromPhysical(3000, myProc + 1));
    Mirror = new GroupOfElement(msh.getFromPhysical( 103, myProc + 1));
    Frame  = new GroupOfElement(msh.getFromPhysical( 105, myProc + 1));
    LineOY = new GroupOfElement(msh.getFromPhysical( 101, myProc + 1));
    OutPML = new GroupOfElement(msh.getFromPhysical( 104, myProc + 1));
  }

  else{
    Air    = new GroupOfElement(msh.getFromPhysical(4000));
    PMLx   = new GroupOfElement(msh.getFromPhysical(1000));
    PMLxy  = new GroupOfElement(msh.getFromPhysical(2000));
    PMLy   = new GroupOfElement(msh.getFromPhysical(3000));
    Mirror = new GroupOfElement(msh.getFromPhysical( 103));
    Frame  = new GroupOfElement(msh.getFromPhysical( 105));
    LineOY = new GroupOfElement(msh.getFromPhysical( 101));
    OutPML = new GroupOfElement(msh.getFromPhysical( 104));
  }

  // Full Domain
  vector<const GroupOfElement*> All_domains(8);
  All_domains[0] = Air;
  All_domains[1] = PMLx;
  All_domains[2] = PMLxy;
  All_domains[3] = PMLy;
  All_domains[4] = Mirror;
  All_domains[5] = Frame;
  All_domains[6] = LineOY;
  All_domains[7] = OutPML;

  // FunctionSpace //
  cout << "FunctionSpace... " << endl << flush;
  const size_t order = atoi(option.getValue("-o")[1].c_str());
  FunctionSpaceVector fs(All_domains, order);

  // Formulations //
  // Volume
  cout << "Formulations... " << endl << flush;
  Formulation<Complex>* stifAir;
  Formulation<Complex>* stifXY;
  Formulation<Complex>* stifX;
  Formulation<Complex>* stifY;

  Formulation<Complex>* massAir;
  Formulation<Complex>* massXY;
  Formulation<Complex>* massX;
  Formulation<Complex>* massY;
  /*
  stifAir = new FStif(*Air,   fs, fs, Material::Air::Nu);
  stifXY  = new FStif(*PMLxy, fs, fs,  Material::XY::Nu);
  stifX   = new FStif(*PMLx,  fs, fs,   Material::X::Nu);
  stifY   = new FStif(*PMLy,  fs, fs,   Material::Y::Nu);

  massAir = new FMass(*Air,   fs, fs, Material::Air::Epsilon);
  massXY  = new FMass(*PMLxy, fs, fs,  Material::XY::Epsilon);
  massX   = new FMass(*PMLx,  fs, fs,   Material::X::Epsilon);
  massY   = new FMass(*PMLy,  fs, fs,   Material::Y::Epsilon);
  */

  stifAir = new FStif(*Air,   fs, fs,Material::Air::OverMuEps);
  stifXY  = new FStif(*PMLxy, fs, fs, Material::XY::OverMuEps);
  stifX   = new FStif(*PMLx,  fs, fs,  Material::X::OverMuEps);
  stifY   = new FStif(*PMLy,  fs, fs,  Material::Y::OverMuEps);

  massAir = new FMass(*Air,   fs, fs);
  massXY  = new FMass(*PMLxy, fs, fs);
  massX   = new FMass(*PMLx,  fs, fs);
  massY   = new FMass(*PMLy,  fs, fs);

  // Impedance boundary condition
  Formulation<Complex>* impedance = new FMass(*Frame, fs, fs, fImpedance);

  // System //
  cout << "System... " << endl << flush;
  SystemEigen sys;

  sys.addFormulation(*stifAir);
  sys.addFormulation(*stifXY);
  sys.addFormulation(*stifX);
  sys.addFormulation(*stifY);

  sys.addFormulationB(*massAir);
  sys.addFormulationB(*massXY);
  sys.addFormulationB(*massX);
  sys.addFormulationB(*massY);

  sys.addFormulationB(*impedance);

  // Dirichlet //
  cout << "Dirichlet... " << endl << flush;
  SystemHelper<Complex>::dirichlet(sys, fs, *Mirror, fZero);
  //SystemHelper<Complex>::dirichlet(sys, fs, *Frame , fZero);
  SystemHelper<Complex>::dirichlet(sys, fs, *LineOY, fZero);
  SystemHelper<Complex>::dirichlet(sys, fs, *OutPML, fZero);

  // Assemble //
  cout << "True assembling... " << endl << flush;
  sys.assemble();

  // Free formulations //
  delete stifAir;
  delete stifXY;
  delete stifX;
  delete stifY;

  delete massAir;
  delete massXY;
  delete massX;
  delete massY;

  delete impedance;

  // Solve //
  // Set number of eigenvalue (if any, else default)
  try{
    sys.setNumberOfEigenValues(atoi(option.getValue("-n")[1].c_str()));
  }

  catch(...){
  }

  // Set shift (if any, else default)
  try{
    const double shift = atof(option.getValue("-shift")[1].c_str());

    sys.setWhichEigenpairs("target_magnitude");
    sys.setTarget(Complex(shift, 0));
  }

  catch(...){
  }

  // Set tolerance (if any, else default)
  try{
    sys.setTolerance(atof(option.getValue("-tol")[1].c_str()));
  }

  catch(...){
  }

  // Set maximun iteration number (if any, else default)
  try{
    sys.setMaxIteration(atoi(option.getValue("-maxit")[1].c_str()));
  }

  catch(...){
  }

  // Do what you have to do !
  //sys.setProblem("pos_gen_non_hermitian");
  sys.setProblem("gen_non_hermitian");

  cout << "Solving: " << sys.getSize() << "..." << endl << flush;
  sys.solve();

  // Post-Pro //
  if(myProc == 0){
    // Display
    cout << "Post Pro" << endl << flush;
    const size_t nEigenValue = sys.getNComputedSolution();
    fullVector<Complex> eigenValue;

    sys.getEigenValues(eigenValue);

    cout << "Number of found Eigenvalues: " << nEigenValue
         << endl
         << endl
         << "Number\tEigen Value" << endl;

    for(size_t i = 0; i < nEigenValue; i++)
      cout << "#" << i + 1  << "\t"
           << std::scientific
           << eigenValue(i) << endl;

    // Dump on disk
    dump("harocheValues.txt", eigenValue);
  }

  // Draw
  try{
    option.getValue("-nopos");
  }

  catch(...){
    FEMSolution<Complex> feSol;
    sys.getSolution(feSol, fs, All_domains);

    //feSol.setSaveMesh(false);
    feSol.setBinaryFormat(true);
    if(nProcs != 1)
      feSol.setParition(myProc + 1);

    feSol.write("harocheModes");
  }

  // Game over! //
  delete Air;
  delete PMLx;
  delete PMLxy;
  delete PMLy;
  delete Mirror;
  delete Frame;
  delete LineOY;
  delete OutPML;

  // Give peak virtual memory //
  cout << "Process " << myProc << " peak VM: " << getPeakMemory() << endl;
}
Exemplo n.º 9
0
void compute(const Options& option){
  // Start Timer //
  Timer timer, assemble, solve;
  timer.start();

  // Get Domains //
  Mesh msh(option.getValue("-msh")[1]);
  GroupOfElement volume = msh.getFromPhysical(7);
  GroupOfElement source = msh.getFromPhysical(5);
  GroupOfElement wall   = msh.getFromPhysical(6);

  // Full Domain //
  vector<const GroupOfElement*> domain(3);
  domain[0] = &volume;
  domain[1] = &source;
  domain[2] = &wall;

  // Get Parameters //
  const double k     = atof(option.getValue("-k")[1].c_str());
  const size_t order = atoi(option.getValue("-o")[1].c_str());

  // Function Space //
  assemble.start();
  FunctionSpaceVector fs(domain, order);

  // Formulation & System //
  FormulationSteadySlow<double> wave(volume, fs, k);
  System<double> sys;
  sys.addFormulation(wave);

  // Dirichlet //
  SystemHelper<double>::dirichlet(sys, fs, source, fSourceVec);
  SystemHelper<double>::dirichlet(sys, fs, wall,   fWallVec);

  cout << "Slow Vectorial "
       << "Steady Wave (Order: " << order
       << " --- Wavenumber: "    << k << ")" << endl;

  // Assemble and solve //
  sys.assemble();
  assemble.stop();
  cout << "Assembled: " << sys.getSize() << " "
       << "(" << assemble.time() << assemble.unit() << ")" << endl << flush;

  solve.start();
  sys.solve();
  solve.stop();
  cout << "Solved (" << solve.time() << solve.unit() << ")" << endl << flush;

  // Write Sol //
  try{
    option.getValue("-nopos");
  }
  catch(...){
    FEMSolution<double> feSol;
    sys.getSolution(feSol, fs, volume);
    feSol.write("slow");
  }

  // Timer -- Finalize -- Return //
  timer.stop();

  cout << "Elapsed Time: " << timer.time() << timer.unit() << endl;
}