petsc_auto_fieldsplit.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
19 
20 #ifdef LIBMESH_HAVE_PETSC
21 
22 #include <petscksp.h>
23 
24 // Local includes
25 #include "libmesh/dof_map.h"
26 #include "libmesh/system.h"
27 
28 #if !PETSC_VERSION_LESS_THAN(3,2,0)
29 
30 // C++ includes
31 
32 namespace {
33 using namespace libMesh;
34 
35 void indices_to_fieldsplit (const Parallel::Communicator & comm,
36  const std::vector<dof_id_type> & indices,
37  PC my_pc,
38  const std::string & field_name)
39 {
40  const PetscInt * idx = PETSC_NULL;
41  if (!indices.empty())
42  idx = reinterpret_cast<const PetscInt *>(&indices[0]);
43 
44  IS is;
45  int ierr = ISCreateLibMesh(comm.get(), indices.size(),
46  idx, PETSC_COPY_VALUES, &is);
47  CHKERRABORT(comm.get(), ierr);
48 
49  ierr = PCFieldSplitSetIS(my_pc, field_name.c_str(), is);
50  CHKERRABORT(comm.get(), ierr);
51 }
52 
53 }
54 
55 namespace libMesh
56 {
57 
58 void petsc_auto_fieldsplit (PC my_pc,
59  const System & sys)
60 {
61  std::string sys_prefix = "--solver_group_";
62 
63  if (libMesh::on_command_line("--solver_system_names"))
64  {
65  sys_prefix = sys_prefix + sys.name() + "_";
66  }
67 
68  std::map<std::string, std::vector<dof_id_type> > group_indices;
69 
70  if (libMesh::on_command_line("--solver_variable_names"))
71  {
72  for (unsigned int v = 0; v != sys.n_vars(); ++v)
73  {
74  const std::string & var_name = sys.variable_name(v);
75 
76  std::vector<dof_id_type> var_idx;
78  (var_idx, sys.get_mesh(), v);
79 
80  std::string group_command = sys_prefix + var_name;
81 
82  const std::string empty_string;
83 
84  std::string group_name = libMesh::command_line_value
85  (group_command, empty_string);
86 
87  if (group_name != empty_string)
88  {
89  std::vector<dof_id_type> & indices =
90  group_indices[group_name];
91  const bool prior_indices = !indices.empty();
92  indices.insert(indices.end(), var_idx.begin(),
93  var_idx.end());
94  if (prior_indices)
95  std::sort(indices.begin(), indices.end());
96  }
97  else
98  {
99  indices_to_fieldsplit (sys.comm(), var_idx, my_pc, var_name);
100  }
101  }
102  }
103 
104  for (std::map<std::string, std::vector<dof_id_type> >::const_iterator
105  i = group_indices.begin(); i != group_indices.end(); ++i)
106  {
107  indices_to_fieldsplit(sys.comm(), i->second, my_pc, i->first);
108  }
109 }
110 
111 } // namespace libMesh
112 
113 
114 #else // #PETSC_VERSION < 3.2.0
115 
116 namespace libMesh
117 {
118 void petsc_auto_fieldsplit (PC /* my_pc */,
119  const System & /* sys */)
120 {
121  if (libMesh::on_command_line("--solver_variable_names"))
122  {
123  libmesh_do_once(
124  libMesh::out << "WARNING: libMesh does not support setting field splits" <<
125  std::endl << "with PETSc "
126  << LIBMESH_DETECTED_PETSC_VERSION_MAJOR << '.'
127  << LIBMESH_DETECTED_PETSC_VERSION_MINOR << '.'
128  << LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR << std::endl;);
129  }
130 }
131 }
132 
133 #endif // #PETSC_VERSION > 3.2.0
134 #endif // #ifdef LIBMESH_HAVE_PETSC
void petsc_auto_fieldsplit(PC my_pc, const System &sys)
const std::string & variable_name(const unsigned int i) const
Definition: system.h:2123
ImplicitSystem & sys
void local_variable_indices(std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
Definition: dof_map.C:1110
const std::string & name() const
Definition: system.h:1987
const MeshBase & get_mesh() const
Definition: system.h:2003
const DofMap & get_dof_map() const
Definition: system.h:2019
PetscErrorCode ierr
bool on_command_line(const std::string &arg)
Definition: libmesh.C:914
const Parallel::Communicator & comm() const
unsigned int n_vars() const
Definition: system.h:2075
T command_line_value(const std::string &name, T value)
Definition: libmesh.C:925
OStreamProxy out(std::cout)
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)