PetIBM 0.5.4
Toolbox and applications of the immersed-boundary method for distributed-memory architectures
createbn.cpp
Go to the documentation of this file.
1
8// STL
9#include <cmath>
10
11// here goes PETSc headers
12#include <petscmat.h>
13
14namespace petibm
15{
16namespace operators
17{
18// implementation of createBnHead
19PetscErrorCode createBnHead(const Mat &Op, const PetscReal &dt,
20 const PetscReal &coeff, const PetscInt &n,
21 Mat &BnHead)
22{
23 PetscFunctionBeginUser;
24
25 PetscErrorCode ierr;
26
27 if (n < 1)
28 SETERRQ(PETSC_COMM_WORLD, 56,
29 "The order of Bn can not be smaller than 1.");
30
31 // a lazy and slow way to create BnHead. But we don't have to extract
32 // parallel distribution information.
33 ierr = MatDuplicate(Op, MAT_DO_NOT_COPY_VALUES, &BnHead); CHKERRQ(ierr);
34 ierr = MatSetOption(BnHead, MAT_KEEP_NONZERO_PATTERN, PETSC_FALSE);
35 CHKERRQ(ierr);
36 ierr = MatSetOption(BnHead, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE);
37 CHKERRQ(ierr);
38
39 // assume the BnHead is a diagonal matrix, which is only true for 1st order
40 // so if the order is not 1, this will be inefficient
41 ierr = MatSeqAIJSetPreallocation(BnHead, 1, nullptr); CHKERRQ(ierr);
42 ierr = MatMPIAIJSetPreallocation(BnHead, 1, nullptr, 0, nullptr);
43 CHKERRQ(ierr);
44
45 // the first term; only diagonal values exist, and the value is dt
46 // this one works only if the original diagonal is zero. Be careful.
47 ierr = MatAssemblyBegin(BnHead, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
48 ierr = MatAssemblyEnd(BnHead, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
49 ierr = MatShift(BnHead, dt); CHKERRQ(ierr);
50
51 // if the order is not greater than 1, exit this function. No need to go
52 // through the following codes and save temporary memory usage.
53 if (n == 1) PetscFunctionReturn(0);
54
55 // the following code calculates each term, and add back to BnHead
56 Mat rightMat, tempResult;
57
58 // calculate the matrix for each term if order > 1, and add back to BnHead
59 for (PetscInt term = 2; term <= n; ++term)
60 {
61 // the most right matrix of successive mat-mat-multiplication
62 ierr = MatDuplicate(Op, MAT_COPY_VALUES, &rightMat); CHKERRQ(ierr);
63
64 // successive mat-mat-multiplications
65 for (PetscInt c = 2; c < term; ++c)
66 {
67 // do tempResult = Op * rightMat once
68 ierr = MatMatMult(Op, rightMat, MAT_INITIAL_MATRIX, PETSC_DEFAULT,
69 &tempResult); CHKERRQ(ierr);
70
71 // release the memory space where rightMat is pointing to
72 ierr = MatDestroy(&rightMat); CHKERRQ(ierr);
73
74 // make the pointer (Mat is actually a pointer) rightMat point
75 // to the same memory space pointed by tempResult
76 rightMat = tempResult;
77 }
78
79 // the coefficient of this term
80 PetscReal a = std::pow(dt, term) * std::pow(coeff, term - 1);
81
82 // BnHead = BnHead + a * rightMat
83 ierr = MatAXPY(BnHead, a, rightMat, DIFFERENT_NONZERO_PATTERN);
84 CHKERRQ(ierr);
85
86 // assemble matrix
87 ierr = MatAssemblyBegin(BnHead, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
88 ierr = MatAssemblyEnd(BnHead, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
89
90 // release the memory space pointed by rightMat (and also by tempResult)
91 ierr = MatDestroy(&rightMat); CHKERRQ(ierr);
92 }
93
94 PetscFunctionReturn(0);
95} // createBnHead
96
97// implementation of createBn
98PetscErrorCode createBn(const Mat &Op, const Mat &R, const Mat &MHead,
99 const PetscReal &dt, const PetscReal &coeff,
100 const PetscInt &n, Mat &Bn)
101{
102 PetscFunctionBeginUser;
103
104 PetscErrorCode ierr;
105
106 // get BnHead first
107 ierr = createBnHead(Op, dt, coeff, n, Bn); CHKERRQ(ierr);
108
109 Vec RDiag, MHeadDiagInv;
110
111 // get the diagonal values of MHead^(-1)
112 ierr = MatCreateVecs(MHead, nullptr, &MHeadDiagInv); CHKERRQ(ierr);
113 ierr = MatGetDiagonal(MHead, MHeadDiagInv); CHKERRQ(ierr);
114 ierr = VecReciprocal(MHeadDiagInv); CHKERRQ(ierr);
115
116 // get the diagonal values of R
117 ierr = MatCreateVecs(R, nullptr, &RDiag); CHKERRQ(ierr);
118 ierr = MatGetDiagonal(R, RDiag); CHKERRQ(ierr);
119
120 // get Bn using Bn = R * BnHead * MHead^(-1)
121 ierr = MatDiagonalScale(Bn, RDiag, MHeadDiagInv); CHKERRQ(ierr);
122
123 // release memory space
124 ierr = VecDestroy(&RDiag); CHKERRQ(ierr);
125 ierr = VecDestroy(&MHeadDiagInv); CHKERRQ(ierr);
126
127 PetscFunctionReturn(0);
128} // createBn
129
130// implementation of createBn
131PetscErrorCode createBn(const Mat &Op, const Mat &M, const PetscReal &dt,
132 const PetscReal &coeff, const PetscInt &n, Mat &Bn)
133{
134 PetscFunctionBeginUser;
135
136 PetscErrorCode ierr;
137
138 Vec MDiagInv;
139
140 if (n < 1)
141 SETERRQ(PETSC_COMM_WORLD, 56,
142 "The order of Bn can not be smaller than 1.");
143
144 // a lazy and slow way to create Bn. But we don't have to extract
145 // parallel distribution information.
146 ierr = MatDuplicate(Op, MAT_DO_NOT_COPY_VALUES, &Bn); CHKERRQ(ierr);
147 ierr = MatSetOption(Bn, MAT_KEEP_NONZERO_PATTERN, PETSC_FALSE);
148 CHKERRQ(ierr);
149 ierr = MatSetOption(Bn, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE);
150 CHKERRQ(ierr);
151
152 // assume the Bn is a diagonal matrix, which is only true for 1st order
153 // so if the order is not 1, this will be inefficient
154 ierr = MatSeqAIJSetPreallocation(Bn, 1, nullptr); CHKERRQ(ierr);
155 ierr = MatMPIAIJSetPreallocation(Bn, 1, nullptr, 0, nullptr);
156 CHKERRQ(ierr);
157
158 // the first term; only diagonal values exist, and the value is dt
159 // this one works only if the original diagonal is zero. Be careful.
160 ierr = MatCreateVecs(M, nullptr, &MDiagInv); CHKERRQ(ierr);
161 ierr = MatGetDiagonal(M, MDiagInv); CHKERRQ(ierr);
162 ierr = VecReciprocal(MDiagInv); CHKERRQ(ierr);
163 ierr = MatDiagonalSet(Bn, MDiagInv, INSERT_VALUES); CHKERRQ(ierr);
164 ierr = MatScale(Bn, dt); CHKERRQ(ierr);
165
166 // if the order is not greater than 1, exit this function. No need to go
167 // through the following codes and save temporary memory usage.
168 if (n == 1) PetscFunctionReturn(0);
169
170 // the following code calculates each term, and add back to Bn
171 Mat leftMat, rightMat, tempResult;
172
173 // the left matrix we need for mat-mat-multiplication
174 ierr = MatDuplicate(Op, MAT_COPY_VALUES, &leftMat); CHKERRQ(ierr);
175 ierr = MatDiagonalScale(leftMat, MDiagInv, nullptr); CHKERRQ(ierr);
176
177 for (PetscInt term = 2; term <= n; ++term)
178 {
179 // the most right matrix of successive mat-mat-multiplication
180 ierr = MatDuplicate(leftMat, MAT_COPY_VALUES, &rightMat);
181 CHKERRQ(ierr);
182
183 // successive mat-mat-multiplications
184 for (PetscInt c = 2; c < term; ++c)
185 {
186 // do tempResult = Op * rightMat once
187 ierr = MatMatMult(leftMat, rightMat, MAT_INITIAL_MATRIX,
188 PETSC_DEFAULT, &tempResult); CHKERRQ(ierr);
189
190 // release the memory space where rightMat is pointing to
191 ierr = MatDestroy(&rightMat); CHKERRQ(ierr);
192
193 // make the pointer (Mat is actually a pointer) rightMat point
194 // to the same memory space pointed by tempResult
195 rightMat = tempResult;
196 }
197
198 // do a final diagonal scaling on the right
199 ierr = MatDiagonalScale(rightMat, nullptr, MDiagInv); CHKERRQ(ierr);
200
201 // the coefficient of this term
202 PetscReal a = std::pow(dt, term) * std::pow(coeff, term - 1);
203
204 // Bn = Bn + a * rightMat
205 ierr = MatAXPY(Bn, a, rightMat, DIFFERENT_NONZERO_PATTERN);
206 CHKERRQ(ierr);
207
208 // assemble matrix
209 ierr = MatAssemblyBegin(Bn, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
210 ierr = MatAssemblyEnd(Bn, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
211
212 // release the memory space pointed by rightMat (and also by tempResult)
213 ierr = MatDestroy(&rightMat); CHKERRQ(ierr);
214 }
215
216 // release the memory space
217 ierr = MatDestroy(&leftMat); CHKERRQ(ierr);
218
219 PetscFunctionReturn(0);
220} // createBn
221
222} // end of namespace operators
223} // end of namespace petibm
PetscErrorCode createBn(const Mat &Op, const Mat &R, const Mat &MHead, const PetscReal &dt, const PetscReal &coeff, const PetscInt &n, Mat &Bn)
Create normalized matrix of approximated , .
Definition: createbn.cpp:98
PetscErrorCode createBnHead(const Mat &Op, const PetscReal &dt, const PetscReal &coeff, const PetscInt &n, Mat &BnHead)
Create non-normalized matrix of approximated , .
Definition: createbn.cpp:19
A toolbox for building flow solvers.
Definition: bodypack.h:52