PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
Loading...
Searching...
No Matches
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
24namespace pism {
25namespace 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
77
81
82void 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
95void IPTwoBlockVec::scatter(Vec ab, Vec a, Vec b) {
96 this->scatterToA(ab,a);
97 this->scatterToB(ab,b);
98}
99
100void 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
109void IPTwoBlockVec::scatterToA(Vec ab, Vec a) {
110 scatter_begin_end(m_scatter_a, ab, a, SCATTER_FORWARD);
111}
112
113void IPTwoBlockVec::scatterToB(Vec ab, Vec b) {
114 scatter_begin_end(m_scatter_b, ab, b, SCATTER_FORWARD);
115}
116
117void 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
130void IPTwoBlockVec::gather(Vec a, Vec b, Vec ab) {
131 this->gatherFromA(a,ab);
132 this->gatherFromB(b,ab);
133}
134
135void IPTwoBlockVec::gatherFromA(Vec a, Vec ab) {
136 scatter_begin_end(m_scatter_a, a, ab, SCATTER_REVERSE);
137}
138
139void 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_begin_end(VecScatter s, Vec a, Vec b, ScatterMode m)
#define PISM_CHK(errcode, name)