void
MeshFunctionSolutionTransfer::transfer(const Variable & from_var, const Variable & to_var)
{
  // This only works when transferring to a Lagrange variable
  libmesh_assert(to_var.type().family == LAGRANGE);

  unsigned int to_var_num = to_var.number();

  System * from_sys = from_var.system();
  System * to_sys = to_var.system();

  // Only works with a serialized mesh to transfer from!
  libmesh_assert(from_sys->get_mesh().is_serial());

  unsigned int to_sys_num = to_sys->number();

  EquationSystems & from_es = from_sys->get_equation_systems();

  //Create a serialized version of the solution vector
  NumericVector<Number> * serialized_solution = NumericVector<Number>::build(from_sys->get_mesh().comm()).release();
  serialized_solution->init(from_sys->n_dofs(), false, SERIAL);

  // Need to pull down a full copy of this vector on every processor
  // so we can get values in parallel
  from_sys->solution->localize(*serialized_solution);

  MeshFunction from_func(from_es, *serialized_solution, from_sys->get_dof_map(), to_var_num);
  from_func.init();

  MeshBase::const_node_iterator nd     = to_sys->get_mesh().local_nodes_begin();
  MeshBase::const_node_iterator nd_end = to_sys->get_mesh().local_nodes_end();

  // Now loop over the nodes of the 'To' mesh setting values for each variable.
  for(;nd != nd_end; ++nd)
    // 0 is for the value component
    to_sys->solution->set((*nd)->dof_number(to_sys_num, to_var_num, 0), from_func(**nd));

  to_sys->solution->close();
  to_sys->update();

  delete serialized_solution;
}
Ejemplo n.º 2
0
void
MultiAppProjectionTransfer::assembleL2To(EquationSystems & es, const std::string & system_name)
{
  unsigned int app = es.parameters.get<unsigned int>("app");

  FEProblem & from_problem = *_multi_app->problem();
  EquationSystems & from_es = from_problem.es();

  MooseVariable & from_var = from_problem.getVariable(0, _from_var_name);
  System & from_sys = from_var.sys().system();
  unsigned int from_var_num = from_sys.variable_number(from_var.name());

  NumericVector<Number> * serialized_from_solution = NumericVector<Number>::build(from_sys.comm()).release();
  serialized_from_solution->init(from_sys.n_dofs(), false, SERIAL);
  // Need to pull down a full copy of this vector on every processor so we can get values in parallel
  from_sys.solution->localize(*serialized_from_solution);

  MeshFunction from_func(from_es, *serialized_from_solution, from_sys.get_dof_map(), from_var_num);
  from_func.init(Trees::ELEMENTS);
  from_func.enable_out_of_mesh_mode(0.);


  const MeshBase& mesh = es.get_mesh();
  const unsigned int dim = mesh.mesh_dimension();

  LinearImplicitSystem & system = es.get_system<LinearImplicitSystem>(system_name);

  FEType fe_type = system.variable_type(0);
  AutoPtr<FEBase> fe(FEBase::build(dim, fe_type));
  QGauss qrule(dim, fe_type.default_quadrature_order());
  fe->attach_quadrature_rule(&qrule);
  const std::vector<Real> & JxW = fe->get_JxW();
  const std::vector<std::vector<Real> > & phi = fe->get_phi();
  const std::vector<Point> & xyz = fe->get_xyz();

  const DofMap& dof_map = system.get_dof_map();
  DenseMatrix<Number> Ke;
  DenseVector<Number> Fe;
  std::vector<dof_id_type> dof_indices;

  MeshBase::const_element_iterator       el     = mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();
  for ( ; el != end_el; ++el)
  {
    const Elem* elem = *el;

    fe->reinit (elem);

    dof_map.dof_indices (elem, dof_indices);
    Ke.resize (dof_indices.size(), dof_indices.size());
    Fe.resize (dof_indices.size());

    for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
    {
      Point qpt = xyz[qp];
      Point pt = qpt + _multi_app->position(app);
      Real f = from_func(pt);

      // Now compute the element matrix and RHS contributions.
      for (unsigned int i=0; i<phi.size(); i++)
      {
        // RHS
        Fe(i) += JxW[qp] * (f * phi[i][qp]);

        if (_compute_matrix)
          for (unsigned int j = 0; j < phi.size(); j++)
          {
            // The matrix contribution
            Ke(i,j) += JxW[qp] * (phi[i][qp] * phi[j][qp]);
          }
      }
      dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices);

      if (_compute_matrix)
        system.matrix->add_matrix(Ke, dof_indices);
      system.rhs->add_vector(Fe, dof_indices);
    }
  }
}
Ejemplo n.º 3
0
void
MultiAppMeshFunctionTransfer::execute()
{
    Moose::out << "Beginning MeshFunctionTransfer " << _name << std::endl;

    switch(_direction)
    {
    case TO_MULTIAPP:
    {
        FEProblem & from_problem = *_multi_app->problem();
        MooseVariable & from_var = from_problem.getVariable(0, _from_var_name);
        SystemBase & from_system_base = from_var.sys();

        System & from_sys = from_system_base.system();

        // Only works with a serialized mesh to transfer from!
        mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!");

        unsigned int from_var_num = from_sys.variable_number(from_var.name());

        EquationSystems & from_es = from_sys.get_equation_systems();

        //Create a serialized version of the solution vector
        NumericVector<Number> * serialized_solution = NumericVector<Number>::build().release();
        serialized_solution->init(from_sys.n_dofs(), false, SERIAL);

        // Need to pull down a full copy of this vector on every processor so we can get values in parallel
        from_sys.solution->localize(*serialized_solution);

        MeshFunction from_func(from_es, *serialized_solution, from_sys.get_dof_map(), from_var_num);
        from_func.init(Trees::ELEMENTS);
        from_func.enable_out_of_mesh_mode(NOTFOUND);

        for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++)
        {
            if (_multi_app->hasLocalApp(i))
            {
                MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm());

                // Loop over the master nodes and set the value of the variable
                System * to_sys = find_sys(_multi_app->appProblem(i)->es(), _to_var_name);

                if (!to_sys)
                    mooseError("Cannot find variable "<<_to_var_name<<" for "<<_name<<" Transfer");

                unsigned int sys_num = to_sys->number();
                unsigned int var_num = to_sys->variable_number(_to_var_name);
                NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name);

                MeshBase & mesh = _multi_app->appProblem(i)->mesh().getMesh();
                bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE;

                if (is_nodal)
                {
                    MeshBase::const_node_iterator node_it = mesh.local_nodes_begin();
                    MeshBase::const_node_iterator node_end = mesh.local_nodes_end();

                    for(; node_it != node_end; ++node_it)
                    {
                        Node * node = *node_it;

                        if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node
                        {
                            // The zero only works for LAGRANGE!
                            dof_id_type dof = node->dof_number(sys_num, var_num, 0);

                            // Swap back
                            Moose::swapLibMeshComm(swapped);
                            Real from_value = from_func(*node+_multi_app->position(i));
                            // Swap again
                            swapped = Moose::swapLibMeshComm(_multi_app->comm());

                            if (from_value != NOTFOUND)
                                solution.set(dof, from_value);
                            else if (_error_on_miss)
                                mooseError("Point not found! " << *node+_multi_app->position(i) << std::endl);
                        }
                    }
                }
                else // Elemental
                {
                    MeshBase::const_element_iterator elem_it = mesh.local_elements_begin();
                    MeshBase::const_element_iterator elem_end = mesh.local_elements_end();

                    for(; elem_it != elem_end; ++elem_it)
                    {
                        Elem * elem = *elem_it;

                        Point centroid = elem->centroid();

                        if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem
                        {
                            // The zero only works for LAGRANGE!
                            dof_id_type dof = elem->dof_number(sys_num, var_num, 0);

                            // Swap back
                            Moose::swapLibMeshComm(swapped);
                            Real from_value = from_func(centroid+_multi_app->position(i));
                            // Swap again
                            swapped = Moose::swapLibMeshComm(_multi_app->comm());

                            if (from_value != NOTFOUND)
                                solution.set(dof, from_value);
                            else if (_error_on_miss)
                                mooseError("Point not found! " << centroid+_multi_app->position(i) << std::endl);
                        }
                    }
                }

                solution.close();
                to_sys->update();

                // Swap back
                Moose::swapLibMeshComm(swapped);
            }
        }

        delete serialized_solution;

        break;
    }
    case FROM_MULTIAPP:
    {
        FEProblem & to_problem = *_multi_app->problem();
        MooseVariable & to_var = to_problem.getVariable(0, _to_var_name);
        SystemBase & to_system_base = to_var.sys();

        System & to_sys = to_system_base.system();

        unsigned int to_sys_num = to_sys.number();

        // Only works with a serialized mesh to transfer to!
        mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!");

        unsigned int to_var_num = to_sys.variable_number(to_var.name());

        EquationSystems & to_es = to_sys.get_equation_systems();

        NumericVector<Number> * to_solution = to_sys.solution.get();

        MeshBase & to_mesh = to_es.get_mesh();

        bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE;

        for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++)
        {
            if (!_multi_app->hasLocalApp(i))
                continue;

            MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm());
            FEProblem & from_problem = *_multi_app->appProblem(i);
            MooseVariable & from_var = from_problem.getVariable(0, _from_var_name);
            SystemBase & from_system_base = from_var.sys();

            System & from_sys = from_system_base.system();

            // Only works with a serialized mesh to transfer from!
            mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!");

            unsigned int from_var_num = from_sys.variable_number(from_var.name());

            EquationSystems & from_es = from_sys.get_equation_systems();

            //Create a serialized version of the solution vector
            NumericVector<Number> * serialized_from_solution = NumericVector<Number>::build().release();
            serialized_from_solution->init(from_sys.n_dofs(), false, SERIAL);

            // Need to pull down a full copy of this vector on every processor so we can get values in parallel
            from_sys.solution->localize(*serialized_from_solution);

            MeshBase & from_mesh = from_es.get_mesh();
            MeshTools::BoundingBox app_box = MeshTools::processor_bounding_box(from_mesh, libMesh::processor_id());
            Point app_position = _multi_app->position(i);

            MeshFunction from_func(from_es, *serialized_from_solution, from_sys.get_dof_map(), from_var_num);
            from_func.init(Trees::ELEMENTS);
            from_func.enable_out_of_mesh_mode(NOTFOUND);
            Moose::swapLibMeshComm(swapped);

            if (is_nodal)
            {
                MeshBase::const_node_iterator node_it = to_mesh.nodes_begin();
                MeshBase::const_node_iterator node_end = to_mesh.nodes_end();

                for(; node_it != node_end; ++node_it)
                {
                    Node * node = *node_it;

                    if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node
                    {
                        // See if this node falls in this bounding box
                        if (app_box.contains_point(*node-app_position))
                        {
                            // The zero only works for LAGRANGE!
                            dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);

                            MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm());
                            Real from_value = from_func(*node-app_position);
                            Moose::swapLibMeshComm(swapped);

                            if (from_value != NOTFOUND)
                                to_solution->set(dof, from_value);
                            else if (_error_on_miss)
                                mooseError("Point not found! " << *node-app_position <<std::endl);
                        }
                    }
                }
            }
            else // Elemental
            {
                MeshBase::const_element_iterator elem_it = to_mesh.elements_begin();
                MeshBase::const_element_iterator elem_end = to_mesh.elements_end();

                for(; elem_it != elem_end; ++elem_it)
                {
                    Elem * elem = *elem_it;

                    if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem
                    {
                        Point centroid = elem->centroid();

                        // See if this elem falls in this bounding box
                        if (app_box.contains_point(centroid-app_position))
                        {
                            // The zero only works for LAGRANGE!
                            dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0);

                            MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm());
                            Real from_value = from_func(centroid-app_position);
                            Moose::swapLibMeshComm(swapped);

                            if (from_value != NOTFOUND)
                                to_solution->set(dof, from_value);
                            else if (_error_on_miss)
                                mooseError("Point not found! " << centroid-app_position << std::endl);
                        }
                    }
                }
            }
            delete serialized_from_solution;
        }

        to_solution->close();
        to_sys.update();

        break;
    }
    }

    Moose::out << "Finished MeshFunctionTransfer " << _name << std::endl;
}