QuantumNumbers.cpp
1 #include "QuantumNumbers.hpp"
2 #include <algorithm>
3 
4 /* Internal macro for checking the initialization state of the qn object */
5 #define CheckInit(func) \
6  if(PetscUnlikely(!initialized)) \
7  SETERRQ(mpi_comm, PETSC_ERR_ARG_WRONGSTATE, "Object not initialized. Call Initialize() first.");
8 
10  const MPI_Comm& mpi_comm_in,
11  const std::vector<PetscReal>& qn_list_in,
12  const std::vector<PetscInt>& qn_size_in
13  )
14 {
16  if(qn_list_in.size()==0)
17  SETERRQ(mpi_comm, PETSC_ERR_ARG_WRONG, "Initialization error: Empty input list.");
19  if(qn_list_in.size()!=qn_size_in.size())
20  SETERRQ(mpi_comm, PETSC_ERR_ARG_WRONG, "Initialization error: Input list sizes mismatch.");
21 
22  mpi_comm = mpi_comm_in;
23 
29  num_sectors = (PetscInt) qn_list_in.size();
30 
31  /* Ensure that qn_list_in is in descending order and unique */
32  {
33  PetscReal qn_prev = qn_list_in[0];
34  for(PetscInt i = 1; i < num_sectors; ++i)
35  {
36  if(qn_list_in[i] >= qn_prev) SETERRQ(PETSC_COMM_SELF,1,"qn_list_in must be sorted descending.");
37  qn_prev = qn_list_in[i];
38  }
39  }
40 
41  qn_list = qn_list_in;
42  qn_size = qn_size_in;
43  qn_offset.resize(num_sectors+1);
44  qn_offset[0] = 0;
45  for(PetscInt i = 1; i < num_sectors+1; ++i)
46  qn_offset[i] = qn_offset[i-1] + qn_size[i-1];
47  num_states = qn_offset.back();
48  initialized = PETSC_TRUE;
49  return 0;
50 }
51 
52 
54  const PetscInt& BlockIdx,
55  PetscInt& GlobIdxStart,
56  PetscInt& GlobIdxEnd
57  ) const
58 {
59  CheckInit(__FUNCTION__);
62  if(PetscUnlikely((BlockIdx < 0) || (BlockIdx >= num_sectors)))
64  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Given BlockIdx (%d) out of bounds [0, %d).", BlockIdx, num_sectors);
65 
66  GlobIdxStart = qn_offset[BlockIdx];
67  GlobIdxEnd = qn_offset[BlockIdx + 1];
68  return 0;
69 }
70 
71 
73  const PetscInt& BlockIdx,
74  const PetscInt& BlockShift,
75  PetscInt& GlobIdxStart,
76  PetscInt& GlobIdxEnd,
77  PetscBool& flg
78  ) const
79 {
80  CheckInit(__FUNCTION__);
83  if(PetscUnlikely((BlockIdx < 0) || (BlockIdx >= num_sectors)))
85  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Given BlockIdx (%d) out of bounds [0, %d).", BlockIdx, num_sectors);
86 
87  PetscInt BlockIdx_out = BlockIdx + BlockShift;
88  if(BlockIdx_out < 0 || BlockIdx_out >= num_sectors){
89  flg = PETSC_FALSE;
90  return 0;
91  }
92  flg = PETSC_TRUE;
93  GlobIdxStart = qn_offset[BlockIdx_out];
94  GlobIdxEnd = qn_offset[BlockIdx_out + 1];
95  return 0;
96 }
97 
98 
100  const PetscReal& QNValue,
101  PetscInt& GlobIdxStart,
102  PetscInt& GlobIdxEnd
103  ) const
104 {
106  CheckInit(__FUNCTION__);
107 
108  /* Search QNValue from qn_list and get the index */
109  PetscInt BlockIdx = std::find(qn_list.begin(), qn_list.end(), QNValue) - qn_list.begin();
110 
112  if(PetscUnlikely(BlockIdx==num_sectors))
113  SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Given QNValue (%g) not found.", QNValue);
114 
115  GlobIdxStart = qn_offset[BlockIdx];
116  GlobIdxEnd = qn_offset[BlockIdx + 1];
117 
118  return 0;
119 }
120 
121 
123  const PetscInt& GlobIdx,
124  PetscInt& BlockIdx
125  ) const
126 {
127  PetscErrorCode ierr = 0;
128 
130  CheckInit(__FUNCTION__);
132  if(PetscUnlikely(GlobIdx < 0 || GlobIdx >= num_states))
133  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Given GlobIdx (%d) out of bounds [0, %d).", GlobIdx, num_states);
134 
135  BlockIdx = -1;
136  while(GlobIdx >= qn_offset[BlockIdx+1]) ++BlockIdx;
137 
138  return ierr;
139 }
140 
141 
143  const PetscInt& GlobIdx,
144  PetscInt& BlockIdx,
145  PetscInt& LocIdx
146  ) const
147 {
148  PetscErrorCode ierr;
149 
150  ierr = GlobalIdxToBlockIdx(GlobIdx, BlockIdx); CHKERRQ(ierr);
151  LocIdx = GlobIdx - qn_offset[BlockIdx];
152 
153  return(0);
154 }
155 
156 
157 
159  const PetscInt& GlobIdx,
160  PetscReal& QNValue
161  ) const
162 {
163  PetscErrorCode ierr = 0;
165  CheckInit(__FUNCTION__);
166 
167  PetscInt BlockIdx;
169  ierr = GlobalIdxToBlockIdx(GlobIdx, BlockIdx); CHKERRQ(ierr);
170 
171  return ierr;
172 }
173 
174 
176  const PetscInt& BlockIdx,
177  const PetscInt& LocIdx,
178  PetscInt& GlobIdx
179  ) const
180 {
182  CheckInit(__FUNCTION__);
183 
184  if(PetscUnlikely((BlockIdx < 0) || (BlockIdx >= num_sectors)))
186  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Given BlockIdx (%d) out of bounds [0, %d).", BlockIdx, num_sectors);
187 
188  GlobIdx = qn_offset[BlockIdx] + LocIdx;
189  return(0);
190 }
191 
192 
194  const PetscInt& BlockIdx,
195  const PetscInt& LocIdx
196  ) const
197 {
198  assert(initialized);
199  assert((0 <= BlockIdx) && (BlockIdx < num_sectors));
200  return qn_offset[BlockIdx] + LocIdx;
201 }
std::vector< PetscReal > qn_list
List of Sz quantum numbers.
PetscBool initialized
Tells whether initialized previously.
std::vector< PetscInt > qn_offset
Offset for each quantum number block.
PetscErrorCode QNToGlobalRange(const PetscReal &QNValue, PetscInt &GlobIdxStart, PetscInt &GlobIdxEnd) const
Maps the quantum number value to the global indices [start,end)
PetscErrorCode BlockIdxToGlobalIdx(const PetscInt &BlockIdx, const PetscInt &LocIdx, PetscInt &GlobIdx) const
Maps the block index of a basis state to its global index.
PetscErrorCode BlockIdxToGlobalRange(const PetscInt &BlockIdx, PetscInt &GlobIdxStart, PetscInt &GlobIdxEnd) const
Maps the quantum number block index to the global indices [start,end)
std::vector< PetscInt > qn_size
Number of states in each quantum number block.
PetscErrorCode OpBlockToGlobalRange(const PetscInt &BlockIdx, const PetscInt &BlockShift, PetscInt &GlobIdxStart, PetscInt &GlobIdxEnd, PetscBool &flg) const
Maps the shifted quantum number block index to the global indices [start,end).
MPI_Comm mpi_comm
MPI Communicator.
PetscErrorCode GlobalIdxToBlockIdx(const PetscInt &GlobIdx, PetscInt &BlockIdx) const
Maps the global index of a basis state to its block index.
PetscErrorCode GlobalIdxToQN(const PetscInt &GlobIdx, PetscReal &QNValue) const
Maps the global index of a basis state to its quantum number.
PetscErrorCode Initialize(const MPI_Comm &mpi_comm_in, const std::vector< PetscReal > &qn_list_in, const std::vector< PetscInt > &qn_size_in)
Initializes the quantum number object.
PetscInt num_sectors
Number of Sz sectors in the Hilbert space.
PetscInt num_states
Number of basis states in the Hilbert space.
This site was generated by Sphinx using Doxygen with a customized theme from doxygen-bootstrapped.