petsc_auto_fieldsplit.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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.data());
43 
44  IS is;
45  int ierr = ISCreateLibMesh(comm.get(), cast_int<PetscInt>(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 (const auto & pr : group_indices)
105  indices_to_fieldsplit(sys.comm(), pr.second, my_pc, pr.first);
106 }
107 
108 } // namespace libMesh
109 
110 
111 #else // #PETSC_VERSION < 3.2.0
112 
113 namespace libMesh
114 {
115 void petsc_auto_fieldsplit (PC /* my_pc */,
116  const System & /* sys */)
117 {
118  if (libMesh::on_command_line("--solver-variable-names"))
119  {
120  libmesh_do_once(
121  libMesh::out << "WARNING: libMesh does not support setting field splits" <<
122  std::endl << "with PETSc "
123  << LIBMESH_DETECTED_PETSC_VERSION_MAJOR << '.'
124  << LIBMESH_DETECTED_PETSC_VERSION_MINOR << '.'
125  << LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR << std::endl;);
126  }
127 }
128 }
129 
130 #endif // #PETSC_VERSION > 3.2.0
131 #endif // #ifdef LIBMESH_HAVE_PETSC
void local_variable_indices(std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
Definition: dof_map.C:1076
void petsc_auto_fieldsplit(PC my_pc, const System &sys)
const Parallel::Communicator & comm() const
const MeshBase & get_mesh() const
Definition: system.h:2033
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:92
const std::string & variable_name(const unsigned int i) const
Definition: system.h:2153
PetscErrorCode ierr
bool on_command_line(std::string arg)
Definition: libmesh.C:876
const std::string & name() const
Definition: system.h:2017
T command_line_value(const std::string &name, T value)
Definition: libmesh.C:909
unsigned int n_vars() const
Definition: system.h:2105
OStreamProxy out(std::cout)
const DofMap & get_dof_map() const
Definition: system.h:2049
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)