PISM, A Parallel Ice Sheet Model  stable v2.1.1 committed by Constantine Khrulev on 2024-12-04 13:36:58 -0900
IPTwoBlockVec.cc
Go to the documentation of this file.
1 // Copyright (C) 2012, 2014, 2015, 2017, 2023 David Maxwell and Constantine Khroulev
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #include <cassert>
20 
21 #include "pism/inverse/IPTwoBlockVec.hh"
22 #include "pism/util/error_handling.hh"
23 
24 namespace pism {
25 namespace inverse {
26 
28  PetscErrorCode ierr;
29 
30  MPI_Comm comm, comm_b;
31  ierr = PetscObjectGetComm((PetscObject)a, &comm); PISM_CHK(ierr, "PetscObjectGetComm");
32  ierr = PetscObjectGetComm((PetscObject)b, &comm_b); PISM_CHK(ierr, "PetscObjectGetComm");
33  assert(comm == comm_b);
34 
35  // These have to be PetscInt because of PETSc calls below
36  PetscInt lo_a, hi_a;
37  ierr = VecGetOwnershipRange(a, &lo_a, &hi_a); PISM_CHK(ierr, "VecGetOwnershipRange");
38  ierr = VecGetSize(a, &m_na_global); PISM_CHK(ierr, "VecGetSize");
39  m_na_local = hi_a - lo_a;
40 
41  // These have to be PetscInt because of PETSc calls below
42  PetscInt lo_b, hi_b;
43  ierr = VecGetOwnershipRange(b, &lo_b, &hi_b); PISM_CHK(ierr, "VecGetOwnershipRange");
44  ierr = VecGetSize(b, &m_nb_global); PISM_CHK(ierr, "VecGetSize");
45  m_nb_local = hi_b - lo_b;
46 
47  petsc::IS is_a, is_b;
48  // a in a
49  ierr = ISCreateStride(comm, m_na_local, lo_a, 1,
50  is_a.rawptr()); PISM_CHK(ierr, "ISCreateStride");
51  // a in ab
52  ierr = ISCreateStride(comm, m_na_local, lo_a + lo_b, 1,
53  m_a_in_ab.rawptr()); PISM_CHK(ierr, "ISCreateStride");
54 
55  // b in b
56  ierr = ISCreateStride(comm, m_nb_local, lo_b, 1,
57  is_b.rawptr()); PISM_CHK(ierr, "ISCreateStride");
58  // b in ab
59  ierr = ISCreateStride(comm, m_nb_local, lo_a + lo_b + m_na_local, 1,
60  m_b_in_ab.rawptr()); PISM_CHK(ierr, "ISCreateStride");
61 
62  ierr = VecCreate(comm, m_ab.rawptr()); PISM_CHK(ierr, "VecCreate");
63 
64  ierr = VecSetType(m_ab, "mpi"); PISM_CHK(ierr, "VecSetType");
65  ierr = VecSetSizes(m_ab, m_na_local + m_nb_local, m_na_global + m_nb_global);
66  PISM_CHK(ierr, "VecSetSizes");
67 
68  ierr = VecScatterCreate(m_ab, m_a_in_ab, a, is_a,
69  m_scatter_a.rawptr()); PISM_CHK(ierr, "VecScatterCreate");
70  ierr = VecScatterCreate(m_ab, m_b_in_ab, b, is_b,
71  m_scatter_b.rawptr()); PISM_CHK(ierr, "VecScatterCreate");
72 }
73 
75  return m_a_in_ab;
76 }
77 
79  return m_b_in_ab;
80 }
81 
82 void IPTwoBlockVec::scatter(Vec a, Vec b) {
83  this->scatterToA(m_ab,a);
84  this->scatterToB(m_ab,b);
85 }
86 
88  this->scatterToA(m_ab,a);
89 }
90 
92  this->scatterToB(m_ab,b);
93 }
94 
95 void IPTwoBlockVec::scatter(Vec ab, Vec a, Vec b) {
96  this->scatterToA(ab,a);
97  this->scatterToB(ab,b);
98 }
99 
100 void IPTwoBlockVec::scatter_begin_end(VecScatter s, Vec a, Vec b, ScatterMode m) {
101  PetscErrorCode ierr;
102  ierr = VecScatterBegin(s, a, b, INSERT_VALUES, m);
103  PISM_CHK(ierr, "VecScatterBegin");
104 
105  ierr = VecScatterEnd(s, a, b, INSERT_VALUES, m);
106  PISM_CHK(ierr, "VecScatterEnd");
107 }
108 
109 void IPTwoBlockVec::scatterToA(Vec ab, Vec a) {
110  scatter_begin_end(m_scatter_a, ab, a, SCATTER_FORWARD);
111 }
112 
113 void IPTwoBlockVec::scatterToB(Vec ab, Vec b) {
114  scatter_begin_end(m_scatter_b, ab, b, SCATTER_FORWARD);
115 }
116 
117 void IPTwoBlockVec::gather(Vec a, Vec b) {
118  this->gatherFromA(a,m_ab);
119  this->gatherFromB(b,m_ab);
120 }
121 
123  this->gatherFromA(a,m_ab);
124 }
125 
127  this->gatherFromA(b,m_ab);
128 }
129 
130 void IPTwoBlockVec::gather(Vec a, Vec b, Vec ab) {
131  this->gatherFromA(a,ab);
132  this->gatherFromB(b,ab);
133 }
134 
135 void IPTwoBlockVec::gatherFromA(Vec a, Vec ab) {
136  scatter_begin_end(m_scatter_a, a, ab, SCATTER_REVERSE);
137 }
138 
139 void IPTwoBlockVec::gatherFromB(Vec b, Vec ab) {
140  scatter_begin_end(m_scatter_b, b, ab, SCATTER_REVERSE);
141 }
142 
143 } // end of namespace inverse
144 } // end of namespace pism
T * rawptr()
Definition: Wrapper.hh:39
petsc::VecScatter m_scatter_a
petsc::VecScatter m_scatter_b
void scatter(Vec a, Vec b)
void scatter_begin_end(VecScatter s, Vec a, Vec b, ScatterMode m)
#define PISM_CHK(errcode, name)