13 #include <sys/types.h> 15 #include "MiscTools.hpp" 19 PETSC_EXTERN int64_t ipow(int64_t base, uint8_t exp) {
20 static const uint8_t highest_bit_set[] = {
21 0, 1, 2, 2, 3, 3, 3, 3,
22 4, 4, 4, 4, 4, 4, 4, 4,
23 5, 5, 5, 5, 5, 5, 5, 5,
24 5, 5, 5, 5, 5, 5, 5, 5,
25 6, 6, 6, 6, 6, 6, 6, 6,
26 6, 6, 6, 6, 6, 6, 6, 6,
27 6, 6, 6, 6, 6, 6, 6, 6,
28 6, 6, 6, 6, 6, 6, 6, 255,
29 255, 255, 255, 255, 255, 255, 255, 255,
30 255, 255, 255, 255, 255, 255, 255, 255,
31 255, 255, 255, 255, 255, 255, 255, 255,
32 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255,
34 255, 255, 255, 255, 255, 255, 255, 255,
35 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255,
44 255, 255, 255, 255, 255, 255, 255, 255,
45 255, 255, 255, 255, 255, 255, 255, 255,
46 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255,
57 switch (highest_bit_set[exp]) {
64 return 1 - 2 * (exp & 1);
69 if (exp & 1) result *= base;
73 if (exp & 1) result *= base;
77 if (exp & 1) result *= base;
81 if (exp & 1) result *= base;
85 if (exp & 1) result *= base;
89 if (exp & 1) result *= base;
96 PetscErrorCode PreSplitOwnership(
const MPI_Comm comm,
const PetscInt N, PetscInt& locrows, PetscInt& Istart)
98 PetscErrorCode ierr = 0;
103 PetscInt Lrows = PETSC_DECIDE;
104 ierr = PetscSplitOwnership(comm, &Lrows, &Nsize); CHKERRQ(ierr);
106 ierr = MPI_Exscan(&Lrows, &Istart, 1, MPIU_INT, MPI_SUM, comm); CHKERRQ(ierr);
110 PetscMPIInt nprocs,rank;
111 ierr = MPI_Comm_size(comm, &nprocs); CHKERRQ(ierr);
112 ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr);
113 const PetscInt remrows = N % nprocs;
114 locrows = N / nprocs + PetscInt(rank < remrows);
115 Istart = N / nprocs * rank + (rank < remrows ? rank : remrows);
122 PetscErrorCode SplitOwnership(
123 const PetscMPIInt& rank,
124 const PetscMPIInt& nprocs ,
129 const PetscInt remrows = N % nprocs;
130 locrows = N / nprocs + PetscInt(rank < remrows);
131 Istart = N / nprocs * rank + (rank < remrows ? rank : remrows);
136 PETSC_EXTERN PetscErrorCode InitSingleSiteOperator(
const MPI_Comm& comm,
const PetscInt dim, Mat* mat)
138 PetscErrorCode ierr = 0;
140 if(*mat) SETERRQ(comm, 1,
"Matrix was previously initialized. First, destroy the matrix and set to NULL.");
142 ierr = MatCreate(comm, mat); CHKERRQ(ierr);
143 ierr = MatSetSizes(*mat, PETSC_DECIDE, PETSC_DECIDE, dim, dim); CHKERRQ(ierr);
144 ierr = MatSetType(*mat, MATMPIAIJ); CHKERRQ(ierr);
145 ierr = MatSetFromOptions(*mat); CHKERRQ(ierr);
146 ierr = MatSetUp(*mat); CHKERRQ(ierr);
148 ierr = MatSetOption(*mat, MAT_NO_OFF_PROC_ENTRIES , PETSC_TRUE);
149 ierr = MatSetOption(*mat, MAT_NO_OFF_PROC_ZERO_ROWS , PETSC_TRUE);
150 ierr = MatSetOption(*mat, MAT_IGNORE_OFF_PROC_ENTRIES , PETSC_TRUE);
151 ierr = MatSetOption(*mat, MAT_IGNORE_ZERO_ENTRIES , PETSC_TRUE);
157 PETSC_EXTERN PetscErrorCode MatSetOption_MultipleMats(
158 const std::vector<Mat>& matrices,
159 const std::vector<MatOption>& options,
160 const std::vector<PetscBool>& flgs)
162 PetscErrorCode ierr = 0;
166 for(
const Mat& mat: matrices){
167 for(
const MatOption& op: options){
168 ierr = MatSetOption(mat, op, flgs[0]); CHKERRQ(ierr);
172 else if(flgs.size() == options.size())
174 for(
const Mat& mat: matrices){
176 for(
const MatOption& op: options){
177 ierr = MatSetOption(mat, op, flgs[i++]); CHKERRQ(ierr);
183 SETERRQ(PETSC_COMM_WORLD, 1,
"Incorrect input. Either flgs.size() == 1 or flgs.size() == options.size()");
190 PETSC_EXTERN PetscErrorCode MatSetOption_MultipleMatGroups(
191 const std::vector<std::vector<Mat>>& matgroups,
192 const std::vector<MatOption>& options,
193 const std::vector<PetscBool>& flgs)
195 PetscErrorCode ierr = 0;
197 for(
const std::vector<Mat>& matrices: matgroups){
198 ierr = MatSetOption_MultipleMats(matrices, options, flgs); CHKERRQ(ierr);
207 PETSC_EXTERN PetscErrorCode MatSpinOneHalfSzCreate(
const MPI_Comm& comm, Mat& Sz)
209 PetscErrorCode ierr = 0;
211 PetscInt loc_dim = 2;
212 ierr = InitSingleSiteOperator(comm, loc_dim, &Sz); CHKERRQ(ierr);
214 PetscInt locrows = 0, Istart = 0;
215 ierr = PreSplitOwnership(comm, loc_dim, locrows, Istart); CHKERRQ(ierr);
216 PetscInt Iend = Istart + locrows;
218 if (Istart <= 0 && 0 < Iend){
219 ierr = MatSetValue(Sz, 0, 0, +0.5, INSERT_VALUES); CHKERRQ(ierr);
221 if (Istart <= 1 && 1 < Iend){
222 ierr = MatSetValue(Sz, 1, 1, -0.5, INSERT_VALUES); CHKERRQ(ierr);
225 ierr = MatAssemblyBegin(Sz, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
226 ierr = MatAssemblyEnd(Sz, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
231 PETSC_EXTERN PetscErrorCode MatSpinOneHalfSpCreate(
const MPI_Comm& comm, Mat& Sp)
233 PetscErrorCode ierr = 0;
235 PetscInt loc_dim = 2;
236 ierr = InitSingleSiteOperator(comm, loc_dim, &Sp); CHKERRQ(ierr);
238 PetscInt locrows = 0, Istart = 0;
239 ierr = PreSplitOwnership(comm, loc_dim, locrows, Istart); CHKERRQ(ierr);
240 PetscInt Iend = Istart + locrows;
242 if (Istart <= 0 && 0 < Iend){
243 ierr = MatSetValue(Sp, 0, 1, +1.0, INSERT_VALUES); CHKERRQ(ierr);
246 ierr = MatAssemblyBegin(Sp, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
247 ierr = MatAssemblyEnd(Sp, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
252 PETSC_EXTERN PetscErrorCode MatEnsureAssembled(
const Mat& matin)
254 PetscErrorCode ierr = 0;
257 ierr = MatAssembled(matin, &assembled); CHKERRQ(ierr);
260 ierr = MatAssemblyBegin(matin, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
261 ierr = MatAssemblyEnd(matin, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
267 PETSC_EXTERN PetscErrorCode MatEnsureAssembled_MultipleMats(
const std::vector<Mat>& matrices)
269 PetscErrorCode ierr = 0;
271 for(
const Mat& mat: matrices){
272 ierr = MatEnsureAssembled(mat); CHKERRQ(ierr);
279 PETSC_EXTERN PetscErrorCode MatEnsureAssembled_MultipleMatGroups(
const std::vector<std::vector<Mat>>& matgroups)
281 PetscErrorCode ierr = 0;
283 for(
const std::vector<Mat>& matrices: matgroups){
284 ierr = MatEnsureAssembled_MultipleMats(matrices); CHKERRQ(ierr);
291 PETSC_EXTERN PetscErrorCode MatEyeCreate(
const MPI_Comm& comm,
const PetscInt& dim, Mat& eye)
293 PetscErrorCode ierr = 0;
295 ierr = InitSingleSiteOperator(comm, dim, &eye); CHKERRQ(ierr);
296 ierr = MatEnsureAssembled(eye); CHKERRQ(ierr);
297 ierr = MatShift(eye, 1.00); CHKERRQ(ierr);
298 ierr = MatEnsureAssembled(eye); CHKERRQ(ierr);
306 PETSC_EXTERN PetscErrorCode
Makedir(
const std::string& dir_name)
309 DIR *dir = opendir(dir_name.c_str());
312 ierr = mkdir(dir_name.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
314 DIR *dir = opendir(dir_name.c_str());
316 if(ierr) PetscPrintf(PETSC_COMM_SELF,
"mkdir error code: %d for dir: %s\n",
317 ierr, dir_name.c_str());
331 const std::string& filename
335 PetscMPIInt mpi_rank;
336 ierr = MPI_Comm_rank(mpi_comm, &mpi_rank); CHKERRQ(ierr);
337 std::map< std::string, std::string > infomap;
338 ierr = RetrieveInfoFile<std::string>(mpi_comm,filename,infomap); CHKERRQ(ierr);
339 for(
auto it: infomap) {
340 ierr = PetscOptionsSetValue(NULL,(it.first).c_str(),(it.second).c_str()); CHKERRQ(ierr);
343 std::cout <<
"-----------------------------------------" << std::endl;
344 std::cout <<
"WARNING:\n" 345 "The following directives from " << filename <<
"\n" <<
346 "will override command-line arguments:" << std::endl;
347 for(
auto it: infomap)
348 std::cout <<
" " << std::setw(20) << it.first <<
" " << it.second << std::endl;
PETSC_EXTERN PetscErrorCode Makedir(const std::string &dir_name)
Creates a directory named dir_name.