Tensor Network Theory Library  Beta release 1.2.1
A library of routines for performing TNT-based operations
 All Data Structures Functions Variables Groups Pages
tntNodeQN.c
1 /*
2 Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3 $LastChangedDate: 2015-06-29 20:44:17 +0100 (Mon, 29 Jun 2015) $
4 (c) University of Oxford 2014
5 */
6 
7 #include "../headers/tnt_int.h"
8 #include "../headers/dec_public.h"
9 #include "../headers/dec_tnode.h"
10 #include "../headers/dec_network.h"
11 
12 
37 void tntNodeSetQN(tntNode A,
38  tntLegLabel legA,
39  tntIntArray *qvals,
40  int legdir)
41 {
42 
43  unsigned legdim = tntNodeGetLegDim(A,legA);
44  extern tntSystem systype; /* Internal decleration of global variable for system type */
45  unsigned symm_num_qn = systype.symm_num_qn; /* The number of quantum numbers needed to label each index for the current symmetry type */
46  int *qval_zeros; /* zero array for setting quantum number info */
47  double start_norm, finish_norm; /* start norm and finish norm for printing warning if values lost */
48  unsigned legid;
49  TNT_ERR_RET_DEFS /* return value from internal function */
50 
51  char warning_msg[TNT_STRLEN]; /* Buffer for warning message */
52  char err_msg[TNT_STRLEN]; /* Buffer for error message */
53 
54  /* Get the integer leg id */
55  ret = _tnt_node_id_chartonum(&legid, *legA);
56  TNT_PUB_ERR_CHK /* NO_COVERAGE */
57 
58  /* Check that there are the correct number of quantum numbers */
59  if ((NULL != qvals)&&(legdim*symm_num_qn > qvals->sz)) {
60  sprintf(err_msg,"Incorrect number of quantum number values provided|" /* NO_COVERAGE */
61  "Number provided: %d, number required: %d x %d = %d",qvals->sz,symm_num_qn,legdim,legdim*symm_num_qn); /* NO_COVERAGE */
62  sprintf(tnt_err.errinfostr,"%s",err_msg); /* NO_COVERAGE */
63  sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
64  _tnt_print_error(); /* NO_COVERAGE */
65  } /* NO_COVERAGE */
66 
67  /* find starting norm */
68  ret = _tnt_tnode_norm(&start_norm,A);
69  TNT_PUB_ERR_CHK /* NO_COVERAGE */
70 
71 
72  /* Call function to set quantum number information */
73  if (NULL == qvals) {
74  /* if NULL provided as argument, generate zero array first */
75  chk = qval_zeros = calloc(legdim*symm_num_qn, sizeof(int));
76  TNT_PUB_MEM_CHK /* NO_COVERAGE */
77 
78  ret = _tnt_tnode_setqn(A, legid, qval_zeros, legdir);
79  TNT_PUB_ERR_CHK /* NO_COVERAGE */
80 
81  free(qval_zeros);
82  } else {
83  /* otherwise set using quantum number values provided in argument */
84  ret = _tnt_tnode_setqn(A, legid, qvals->vals, legdir);
85  TNT_PUB_ERR_CHK /* NO_COVERAGE */
86  }
87 
88  /* find finishing norm */
89  ret = _tnt_tnode_norm(&finish_norm,A);
90  TNT_PUB_ERR_CHK /* NO_COVERAGE */
91 
92  if (fabs(start_norm-finish_norm)/start_norm>TNT_DEFAULT_TOL) {
93  sprintf(warning_msg, "Warning when setting quantum number information using tntNodeSetQN()|Conversion to a symmetric blocked form has resulted in information being lost|" /* NO_COVERAGE */
94  "Initial norm is %.4g, difference in node norm is %.4g",start_norm,fabs(start_norm-finish_norm)); /* NO_COVERAGE */
95  tntWarningPrint(warning_msg); /* NO_COVERAGE */
96  } /* NO_COVERAGE */
97 }
98 
105 void tntNodeSetQN_nowarn(tntNode A,
106  tntLegLabel legA,
107  tntIntArray *qvals,
108  int legdir)
109 {
110 
111  unsigned legid; /* Leg id to set quantum number information to */
112  unsigned legdim = tntNodeGetLegDim(A,legA);
113  extern tntSystem systype; /* Internal decleration of global variable for system type */
114  unsigned symm_num_qn = systype.symm_num_qn; /* The number of quantum numbers needed to label each index for the current symmetry type */
115  int *qval_zeros; /* zero array for setting quantum number info */
116  char err_msg[TNT_STRLEN]; /* Buffer for error messages */
117  TNT_ERR_RET_DEFS /* return value from internal function */
118 
119 
120  /* Check that there are the correct number of quantum numbers */
121  if ((NULL != qvals)&&(legdim*symm_num_qn > qvals->sz)) {
122  sprintf(err_msg,"Incorrect number of quantum number values provided|" /* NO_COVERAGE */
123  "Number provided: %d, number required: %d x %d = %d",qvals->sz,symm_num_qn,legdim,legdim*symm_num_qn); /* NO_COVERAGE */
124  sprintf(tnt_err.errinfostr,"%s",err_msg); /* NO_COVERAGE */
125  sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
126  _tnt_print_error(); /* NO_COVERAGE */
127  } /* NO_COVERAGE */
128 
129  /* Get the integer leg id */
130  ret = _tnt_node_id_chartonum(&legid, *legA);
131  TNT_PUB_ERR_CHK /* NO_COVERAGE */
132 
133  /* Call function to set quantum number information */
134  if (NULL == qvals) {
135  /* if NULL provided as argument, generate zero array first */
136  chk = qval_zeros = calloc(legdim*symm_num_qn, sizeof(int));
137  TNT_PUB_MEM_CHK /* NO_COVERAGE */
138 
139  ret = _tnt_tnode_setqn(A, legid, qval_zeros, legdir);
140  TNT_PUB_ERR_CHK /* NO_COVERAGE */
141 
142  free(qval_zeros);
143  } else {
144  /* otherwise set using quantum number values provided in argument */
145  ret = _tnt_tnode_setqn(A, legid, qvals->vals, legdir);
146  TNT_PUB_ERR_CHK /* NO_COVERAGE */
147  }
148 }
149 
155 tntIntArray tntNodeGetQN(tntNode A,
156  tntLegLabel legA)
158 {
159  unsigned legid; /* Leg id to get quantum number information from */
160  tntIntArray qn_nums; /* Array to return containing quantum numbers */
161  TNT_ERR_RET_DEFS /* Return value from internal function */
162 
163  ret = _tnt_tnode_checkqn(A);
164  TNT_PUB_ERR_CHK /* NO_COVERAGE */
165 
166  /* Get the integer leg id */
167  ret = _tnt_node_id_chartonum(&legid, *legA);
168  TNT_PUB_ERR_CHK /* NO_COVERAGE */
169 
170  ret = _tnt_tnode_getqn(&qn_nums, A, legid);
171  TNT_PUB_ERR_CHK /* NO_COVERAGE */
172 
173  /* Return the array */
174  return qn_nums;
175 
176 }
177 
182 void tntNodeClearQN(tntNode A)
183 {
184 
185  TNT_ERR_RET_DEFS /* return value from internal function */
186 
187  /* clear quantum number info in internal function */
188  ret = _tnt_tnode_clearqn(A);
189  TNT_PUB_ERR_CHK /* NO_COVERAGE */
190 }
191 
204 void tntNodeMakeCovariantQN(tntNode A)
205 {
206 
207  int symmcheck; /* Flag for symmetry properties of node */
208  int legnum; /* Leg number that should have the quantum numbers set */
209  tntIntArray qns; /* Quantum numbers to apply */
210  TNT_ERR_RET_DEFS /* return value from internal function */
211 
212  ret = _tnt_tnode_checkqn(A);
213  TNT_PUB_ERR_CHK /* NO_COVERAGE */
214 
215  /* Get the quantum number for the remaining leg */
216  ret = _tnt_tnode_checksymmprop(&symmcheck, &qns, &legnum, A);
217  TNT_PUB_ERR_CHK /* NO_COVERAGE */
218 
219  /* Return error if no values found */
220  if (-2 == symmcheck) {
221  sprintf(tnt_err.errinfostr, "Error when attempting to make node covariant|" /* NO_COVERAGE */
222  "No quantum numbers found which result in node with non-zero norm|" /* NO_COVERAGE */
223  "Initial node does not have any non-zero elements"); /* NO_COVERAGE */
224  sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
225  _tnt_print_error(); /* NO_COVERAGE */
226  } /* NO_COVERAGE */
227 
228  /* set the quantum number label on the original node */
229  ret = _tnt_tnode_setqn(A, A->leg_id[legnum], qns.vals, TNT_QN_OUT);
230  TNT_PUB_ERR_CHK /* NO_COVERAGE */
231 
232  /* Free the arrays that are no longer required */
233  tntIntArrayFree(&qns);
234 }
235 
void tntNodeSetQN(tntNode A, tntLegLabel legA, tntIntArray *qvals, int legdir)
Definition: tntNodeQN.c:37
tntSystem systype
Definition: tntSys.c:12
void tntNodeMakeCovariantQN(tntNode A)
Definition: tntNodeQN.c:204
tntIntArray tntNodeGetQN(tntNode A, tntLegLabel legA)
Definition: tntNodeQN.c:155
void tntIntArrayFree(tntIntArray *arr)
Definition: tntArray.c:620
void tntNodeClearQN(tntNode A)
Definition: tntNodeQN.c:182
void tntNodeSetQN_nowarn(tntNode A, tntLegLabel legA, tntIntArray *qvals, int legdir)
Definition: tntNodeQN.c:105
unsigned tntNodeGetLegDim(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:246