Ejemplo n.º 1
0
int main(int argc, char** argv)
{
  MPI::Init(argc, argv);
  MPI::Comm& comm = MPI::COMM_WORLD;
  int myrank = comm.Get_rank();

  Config conf;
  if (myrank == 0) {
    if (argc != 2) {
      std::cout << "usage: " << argv[0] << " configfile" << std::endl;
      comm.Abort(EX_USAGE);
    }

    std::cout << "# of MPI processes = " << comm.Get_size() << std::endl;
#ifdef _OPENMP
    std::cout << "# of OpenMP threads = " << omp_get_max_threads() << std::endl;
#endif

    std::cout <<  std::endl << "Configuration file: " << argv[1] << std::endl;
  }

  conf.load(argv[1]);
  if (myrank == 0) conf.print();

  RootGrid* rootGrid = new RootGrid(1, 1, 1);

  Divider* divider;
  if (conf.treeType == "flat") {
    divider = new FlatDivider(rootGrid, conf.maxLevel);
  }
  else if (conf.treeType == "simple") {
    divider = new SimpleDivider(rootGrid, conf.minLevel, conf.maxLevel);
  }
  else {
    exit(EX_READ_CONFIG);
  }

  BCMOctree::Ordering ordering;
  if (conf.ordering == "Z") {
    ordering = BCMOctree::Z;
  }
  else if (conf.ordering == "Hilbert") {
    ordering = BCMOctree::HILBERT;
  }
  else if (conf.ordering == "random") {
    ordering = BCMOctree::RANDOM;
  }
  else {
    exit(EX_READ_CONFIG);
  }

  BCMOctree* tree = new BCMOctree(rootGrid, divider, ordering);

  int numLeafNode = tree->getNumLeafNode();

  std::vector<Node*>& leafNodeArray = tree->getLeafNodeArray();

  Partition* partition = new Partition(comm.Get_size(), numLeafNode);

  if (myrank == 0) {
    std::cout << std::endl << "Partitioning" << std::endl;
    partition->print();
  }

  // ブロック内のセル数
  Vec3i size(conf.size, conf.size, conf.size);

  BoundaryConditionSetter* boundaryConditionSetter = new BoundaryConditionSetter(&conf);

  BlockFactory* blockFactory = new BlockFactory(tree, partition, boundaryConditionSetter, size);

  BlockManager& blockManager = BlockManager::getInstance();

  for (int id = partition->getStart(myrank); id < partition->getEnd(myrank); id++) {
    Node* node = leafNodeArray[id];
    Block* block = blockFactory->makeBlock(node);
    blockManager.registerBlock(block);
  }

  blockManager.endRegisterBlock();

  blockManager.printBlockLayoutInfo();

  delete tree;
  delete partition;
  delete boundaryConditionSetter;

  std::vector<double> boundaryValue(1);
  boundaryValue[0] = 0.0;

  Solver solver(conf, boundaryValue);

  Timing::start(INIT);
  solver.initialize();
  Timing::stop(INIT);

  Timing::start(RUN);
  solver.run();
  Timing::stop(RUN);

  solver.checkResult(conf.verbose);

  if (myrank == 0) {
    std::cout << std::endl << "Timings" << std::endl;
    Timing::print(INIT,     "  Solver::initialize           ");
    Timing::print(RUN,      "  Solver::run                  ");
#ifdef TIMING
    Timing::print(SOR,      "  SOR in block                 ");
    Timing::print(VCUPDATE, "  VCUpdate + BC                ");
    Timing::print(BC,       "  BC                           ");
#endif
  }

  MPI::Finalize();

  return EX_SUCCESS;
}
Ejemplo n.º 2
0
void RBEC::stepForward()
{
    int i, j, k, l;
    int n_dof = fem_space.n_dof();
    int n_total_dof = 2 * n_dof;

    mat_RBEC.reinit(sp_RBEC);
    mat_rere.reinit(sp_rere);
    mat_reim.reinit(sp_reim);
    mat_imre.reinit(sp_imre);
    mat_imim.reinit(sp_imim);

    Vector<double> phi(n_total_dof);
    FEMFunction <double, DIM> phi_star(fem_space);
    Vector<double> rhs(n_total_dof);
    Potential V(gamma_x, gamma_y);

/// 准备一个遍历全部单元的迭代器.
    FEMSpace<double, DIM>::ElementIterator the_element = fem_space.beginElement();
    FEMSpace<double, DIM>::ElementIterator end_element = fem_space.endElement();

/// 循环遍历全部单元, 只是为了统计每一行的非零元个数.
    for (; the_element != end_element; ++the_element)
    {
/// 当前单元信息.
	double volume = the_element->templateElement().volume();
	const QuadratureInfo<DIM>& quad_info = the_element->findQuadratureInfo(6);
	std::vector<double> jacobian = the_element->local_to_global_jacobian(quad_info.quadraturePoint());
	int n_quadrature_point = quad_info.n_quadraturePoint();
	std::vector<AFEPack::Point<DIM> > q_point = the_element->local_to_global(quad_info.quadraturePoint());
/// 单元信息.
	std::vector<std::vector<std::vector<double> > > basis_gradient = the_element->basis_function_gradient(q_point);
	std::vector<std::vector<double> >  basis_value = the_element->basis_function_value(q_point);
	std::vector<double> phi_re_value = phi_re.value(q_point, *the_element);
	std::vector<double> phi_im_value = phi_im.value(q_point, *the_element);
	const std::vector<int>& element_dof = the_element->dof();
	int n_element_dof = the_element->n_dof();
/// 实际拼装.
	for (l = 0; l < n_quadrature_point; ++l)
	{
	    double Jxw = quad_info.weight(l) * jacobian[l] * volume;
	    for (j = 0; j < n_element_dof; ++j)
	    {
		for (k = 0; k < n_element_dof; ++k)
		{

		    double cont = Jxw * ((1 / dt) * basis_value[j][l] * basis_value[k][l]
					 + 0.5 * innerProduct(basis_gradient[j][l], basis_gradient[k][l])
					 + V.value(q_point[l]) * basis_value[j][l] * basis_value[k][l]
					 + beta * (phi_re_value[l] * phi_re_value[l]  + phi_im_value[l] * phi_im_value[l]) * basis_value[j][l] * basis_value[k][l]);

		    mat_RBEC.add(element_dof[j], element_dof[k], cont);
		    mat_RBEC.add(element_dof[j] + n_dof, element_dof[k] + n_dof, cont);
		}
		rhs(element_dof[j]) += Jxw * phi_re_value[l] * basis_value[j][l] / dt;
		rhs(element_dof[j] + n_dof) += Jxw * phi_im_value[l] * basis_value[j][l] / dt;
	    }
	}
    }

    FEMFunction<double, DIM> _phi_re(phi_re);
    FEMFunction<double, DIM> _phi_im(phi_im);

    boundaryValue(phi, rhs, mat_RBEC);

//    AMGSolver solver(mat_RBEC);
//    solver.solve(phi, rhs);

    dealii::SolverControl solver_control(4000, 1e-15);
    SolverGMRES<Vector<double> >::AdditionalData para(500, false, true);
    SolverGMRES<Vector<double> > gmres(solver_control, para);
    gmres.solve(mat_RBEC, phi, rhs, PreconditionIdentity());

    for (int i = 0; i < n_dof; ++i)
    {
         phi_re(i) = phi(i);
         phi_im(i) = phi(n_dof + i);
    }
	
    for (int i = 0; i < n_dof; ++i)
        phi_star(i) = sqrt(phi_re(i) * phi_re(i) + phi_im(i) * phi_im(i));

    double L2Phi = Functional::L2Norm(phi_re, 6);

    std::cout << "L2 norm = " << L2Phi << std::endl;
       
    for (int i = 0; i < n_dof; ++i)
    {
	phi_re(i) /= L2Phi;
	phi_im(i) /= L2Phi;
    }

    double e = energy(phi_re, phi_im, 6);
    std::cout << "Energy = " << e << std::endl;

    
    t += dt;
};