MADNESS 0.10.1
pointgroupsymmetry.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30
31 $Id$
32*/
33
34
35/*!
36 \file chem/pointgroupsymmetry.cc
37 \brief implements point group operations
38
39 The source is
40 <a href=http://code.google.com/p/m-a-d-n-e-s-s/source/browse/local
41 /trunk/src/apps/chem/pointgroupsymmetry.h>here</a>.
42
43 \par Use cases
44 There are 3 use cases for the projector
45 - create_symmetry_adapted_basis()
46 Given a single function generate a set of symmetry-adapted functions of a given irrep
47 - operator()()
48 Given a set of functions transform them to a set of symmetry-adapted function.
49 This is most likely the case for a localized-to-symmetrized transformation of orbitals.
50 The irreps will be determined by the projection based on a rank-revealing Cholesky
51 decomposition. It is therefore necessary that the set of input functions is normalized,
52 so that small eigenvalues are always due to numerics and not to physics.
53 There will be a rough check on closedness, i.e. that the old and the new set of functions
54 project on the same space.
55 - project_on_irreps()
56 Given a set of functions and a set of corresponding irreps, reproject the functions on
57 their irreps
58 Furthermore a reduction method is provided to do some algebra with the irreps
59
60*/
61#ifndef SRC_APPS_CHEM_POINTGROUPSYMMETRY_H_
62#define SRC_APPS_CHEM_POINTGROUPSYMMETRY_H_
63
66
67namespace madness {
68
69 template<typename T, std::size_t NDIM>
70 class Function;
71}
72
73
74
75namespace madness {
77 typedef std::vector<int> characterlineT;
78
79 std::string schoenflies_; ///< Schoenflies symbol of the point group
80 int order_; ///< order of the point group
81 std::map<std::string,characterlineT> irreps_;
82 std::vector<pg_operator> operators_; ///< symmetry operators
83 std::vector<std::string> mullikan_; ///< Mullikan symbols of the irreps
84 bool is_abelian=true; ///< currently always true
85
86};
87
88/*!
89 \file projector_irrep.h
90 \brief Defines and implements the symmetry projector class
91 \ingroup chem
92 \addtogroup chem
93
94 \par Introduction
95
96*/
97
99
100public:
101
102 /// default ctor
103 projector_irrep() = default;
104
105 /// ctor takes the point group and the optionally the irrep
106 projector_irrep(std::string pointgroup, std::string irrep="all")
107 : lindep_(1.e-3), verbosity_(0), keep_ordering_(true) {
108 std::transform(pointgroup.begin(), pointgroup.end(), pointgroup.begin(), ::tolower);
109 table_=get_table(pointgroup);
110 set_irrep(irrep);
111 }
112
113 /// print the parameters of this projector
114 void print_info(World& world) const {
115 if (world.rank()==0) {
116 print("symmetry projector for point group ",table_.schoenflies_);
117 print("");
118 print(" working on irrep:", irrep_);
119 print(" linear dependency threshold:", lindep_);
120 print(" keep ordering:", keep_ordering_);
121 print(" orthonormalize irreps:", orthonormalize_irreps_);
122 print(" verbosity level:", verbosity_);
123 print("");
125 }
126 }
127
128 /// set the irrep on which this projector projects
129 projector_irrep& set_irrep(std::string irrep) {
130 std::transform(irrep.begin(), irrep.end(), irrep.begin(), ::tolower);
131
132 // check consistency of the input
133 if (std::find(table_.mullikan_.begin(), table_.mullikan_.end(), irrep) == table_.mullikan_.end()) {
134 if (irrep!="all") {
135 print("irrep",irrep);
136 print("point group", table_.schoenflies_);
137 MADNESS_EXCEPTION("no such irrep in this point group",1);
138 }
139 }
140
141 irrep_=irrep;
142 return *this;
143 }
144
145 /// set the linear dependency threshold
146 projector_irrep& set_lindep(const double ld) {
147 lindep_=ld;
148 return *this;
149 }
150
151 /// set the verbosity level
154 return *this;
155 }
156
157 /// get the verbosity level
158 int get_verbosity() const {return verbosity_;}
159
160 /// get the verbosity level
163 return *this;
164 }
165
166 /// get the verbosity level
168
169 /// get the point group name
170 std::string get_pointgroup() const {return table_.schoenflies_;}
171
172 /// return the character table
174
175 /// set the ordering after symmetrization: irreps or keep as is
176 projector_irrep& set_ordering(const std::string o) {
177 if (o=="irrep") keep_ordering_=false;
178 else if (o=="keep") keep_ordering_=true;
179 else {
180 print("projector_irrep: ordering parameter unknown: ",o);
181 MADNESS_EXCEPTION("projector_irrep: ordering parameter unknown",1);
182 }
183 return *this;
184 }
185
186 std::vector<std::string> get_all_irreps() const {
187 return table_.mullikan_;
188 }
189
190 /// projector on a given irrep
191
192 /// @return a vector[irreps] of a vector of functions
193 template<typename T, std::size_t NDIM>
194 std::vector<Function<T,NDIM> > operator()(const Function<T,NDIM>& rhs) const {
195
196 std::vector<Function<T,NDIM> > vrhs;
197 vrhs.push_back(rhs);
198 return this->operator()(vrhs);
199
200 }
201
202 /// projector on a given irrep
203
204 /// @return a vector[irreps] of a vector of functions
205 template<typename T, std::size_t NDIM>
206 std::vector<Function<T,NDIM> > operator()(
207 const std::vector<Function<T,NDIM> >& vrhs) const {
208
210 std::vector<std::string> sirrep;
211 return apply_symmetry_operators(vrhs,metric,sirrep);
212 }
213
214 /// projector on a given irrep
215
216 /// @return a vector[irreps] of a vector of functions
217 template<typename T, std::size_t NDIM>
218 std::vector<Function<T,NDIM> > operator()(
219 const std::vector<Function<T,NDIM> >& vrhs,
220 const Function<typename Tensor<T>::scalar_type,NDIM>& metric) const {
221
222 std::vector<std::string> sirrep;
223 return apply_symmetry_operators(vrhs,metric,sirrep);
224 }
225
226 /// projector on a given irrep
227
228 /// @return a vector[irreps] of a vector of functions
229 template<typename T, std::size_t NDIM>
230 std::vector<Function<T,NDIM> > operator()(
231 const std::vector<Function<T,NDIM> >& vrhs,
232 const Function<typename Tensor<T>::scalar_type,NDIM>& metric,
233 std::vector<std::string>& sirreps) const {
234
235 return apply_symmetry_operators(vrhs,metric,sirreps);
236 }
237
238 /// projector on a given irrep
239
240 /// @return a vector[irreps] of a vector of functions
241 template<typename T, std::size_t NDIM>
242 std::vector<Function<T,NDIM> > operator()(
243 const std::vector<Function<T,NDIM> >& vrhs,
244 std::vector<std::string>& sirreps) const {
245
247 return apply_symmetry_operators(vrhs,metric,sirreps);
248 }
249
250 /// create a symmetry-adapted basis from a single function
251
252 /// @return a vector[irreps] of a vector of functions
253 template<typename T, std::size_t NDIM>
254 std::vector<Function<T,NDIM> > create_symmetry_adapted_basis(
255 const Function<T,NDIM>& rhs,
256 const Function<typename Tensor<T>::scalar_type,NDIM>& metric,
257 std::vector<std::string>& sirreps) {
258
259 std::vector<Function<T,NDIM> > vrhs(1,rhs);
260 return apply_symmetry_operators(vrhs,metric,sirreps);
261
262 }
263
264 /// create a symmetry-adapted basis from a single function
265
266 /// @return a vector[irreps] of a vector of functions
267 template<typename T, std::size_t NDIM>
268 std::vector<Function<T,NDIM> > create_symmetry_adapted_basis(
269 const Function<T,NDIM>& rhs,
270 std::vector<std::string>& sirreps) {
271
272 std::vector<Function<T,NDIM> > vrhs(1,rhs);
274 return apply_symmetry_operators(vrhs,metric,sirreps);
275
276 }
277
278 /// print the character table
280 print("character table for point group ",table_.schoenflies_);
281 printf(" ");
282 for (auto& op : table_.operators_) {
283 printf(" %5s ",op.symbol().c_str());
284 }
285 printf("\n");
286 for (auto& mullikan : table_.mullikan_) {
287 printf(" %5s ",mullikan.c_str());
288 std::vector<int> characters=table_.irreps_.find(mullikan)->second;
289 for (auto& character : characters) {
290 printf(" %5i ",character);
291 }
292 printf("\n");
293 }
294 }
295
296 /// (re-)project the argument on the given irreps
297
298 /// @param[in] vrhs the vector of functions to be projected on the irreps given by irreps
299 /// @param[in] irreps the irreps in order of the functions
300 /// @return vrhs projected on the irreps
301 template<typename T, std::size_t NDIM>
302 std::vector<Function<T,NDIM> > project_on_irreps(const std::vector<Function<T,NDIM> >& vhrs,
303 const std::vector<std::string>& irreps) const;
304
305 /// reduce a reducible representation
306
307 /// @param[in] reps vector or irrep or reduc. reps whose product will be reduced
308 /// @return vector of irreps constituting the input product
309 std::vector<std::string> reduce(const std::vector<std::string> reps) const;
310
311 /// reduce a product of two irreps
312 std::vector<std::string> reduce(const std::string irrep1, const std::string irrep2) const {
313 return reduce(vector_factory<std::string>(irrep1,irrep2));
314 }
315
316 /// reduce a product of three irreps
317 std::vector<std::string> reduce(const std::string irrep1, const std::string irrep2,
318 const std::string irrep3) const {
319 return reduce(vector_factory<std::string>(irrep1,irrep2,irrep3));
320 }
321
322 /// reduce a product of four irreps
323 std::vector<std::string> reduce(const std::string irrep1, const std::string irrep2,
324 const std::string irrep3, const std::string irrep4) const {
325 return reduce(vector_factory<std::string>(irrep1,irrep2,irrep3,irrep4));
326 }
327
328 /// get a mapping canonical to irrep-sorting
329 std::vector<int> get_canonical_to_irrep_map(std::vector<std::string> sirreps) const {
330
331 // distribute into bins
332 std::map<std::string,std::vector<int> > m;
333 for (size_t i=0; i<sirreps.size(); ++i) m[sirreps[i]].push_back(i);
334
335 // concatenate bins
336 std::vector<int> map;
337 for (auto& irrep : table_.mullikan_) {
338 map.insert(end(map), begin(m[irrep]), end(m[irrep]));
339 }
340 return map;
341 }
342
343 /// given a mapping resort
344 template<typename R>
345 static std::vector<R> resort(const std::vector<int> map,
346 const std::vector<R>& vrhs) {
347 MADNESS_ASSERT(map.size()==vrhs.size());
348 std::vector<R> result(vrhs.size());
349 for (size_t i=0; i<map.size(); ++i) result[i]=vrhs[map[i]];
350 return result;
351 }
352
353 /// given a mapping resort
354 template<typename R>
355 static std::vector<R> reverse_resort(const std::vector<int> map,
356 const std::vector<R>& vrhs) {
357 MADNESS_ASSERT(map.size()==vrhs.size());
358 std::vector<R> result(vrhs.size());
359 for (int i=0; i<map.size(); ++i) result[map[i]]=vrhs[i];
360 return result;
361 }
362
363private:
364
366
367 /// choose one of the irreps or "all"
368 std::string irrep_="all";
369
370 /// linear dependency threshold for the orthogonalization
371 double lindep_=1.e-3;
372
373 /// verbosity level
375
376 /// after projection: result functions being ordered according to irreps or ordering unchanged
377 bool keep_ordering_=true;
378
379 /// orthonormalize within the irreps or simply discard linear dependent vectors
381
383
385
387
389
391
393
395
397
398
399 /// return the character table according to the requested point group
400 const charactertable get_table(std::string pointgroup) {
401
402 std::transform(pointgroup.begin(), pointgroup.end(), pointgroup.begin(), ::tolower);
403
404 charactertable table;
405 if (pointgroup=="c1") table=make_c1_table();
406 else if (pointgroup=="ci") table=make_ci_table();
407 else if (pointgroup=="cs") table=make_cs_table();
408 else if (pointgroup=="c2") table=make_c2_table();
409 else if (pointgroup=="c2v") table=make_c2v_table();
410 else if (pointgroup=="c2h") table=make_c2h_table();
411 else if (pointgroup=="d2") table=make_d2_table();
412 else if (pointgroup=="d2h") table=make_d2h_table();
413 else {
414 MADNESS_EXCEPTION("unknown group table",1);
415 }
416 return table;
417 }
418
419 /// symmetrize a vector of functions
420
421 /// project a number of functions on a given number of irreps
422 /// linear dependencies are removed, the functions are orthonormalized
423 /// vanishing input functions are mapped onto vanishing output functions with irrep "null"
424 /// the number of input and output function is expected to be the same!
425 /// @param[in] vrhs vector of functions to be projected on the irrep
426 /// @param[in] vbra bra of vrhs if applicable (if bra /= ket), may be empty
427 /// @param[out] sirrep vector with the irrep names corresponding to the result
428 template<typename T, std::size_t NDIM>
429 std::vector<Function<T,NDIM> > apply_symmetry_operators(
430 const std::vector<Function<T,NDIM> >& vrhs,
431 Function<typename Tensor<T>::scalar_type,NDIM> metric,
432 std::vector<std::string>& sirreps) const;
433
434 /// sort the functions according to their irreps
435 template<typename T, std::size_t NDIM>
436 std::vector<Function<T,NDIM> > sort_to_irreps(std::vector<Function<T,NDIM> >& vrhs,
437 std::vector<std::string>& sirreps) const {
438 std::vector<int> map=get_canonical_to_irrep_map(sirreps);
439 return resort(map,vrhs);
440 }
441
442};
443
444
445} /* namespace madness */
446
447#endif /* SRC_APPS_CHEM_POINTGROUPSYMMETRY_H_ */
This header should include pretty much everything needed for the parallel runtime.
A multiresolution adaptive numerical function.
Definition mra.h:122
TensorTypeData< T >::scalar_type scalar_type
C++ typename of the real type associated with a complex type.
Definition tensor.h:409
A parallel world class.
Definition world.h:132
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:318
Definition pointgroupsymmetry.h:98
const charactertable get_table(std::string pointgroup)
return the character table according to the requested point group
Definition pointgroupsymmetry.h:400
std::vector< int > get_canonical_to_irrep_map(std::vector< std::string > sirreps) const
get a mapping canonical to irrep-sorting
Definition pointgroupsymmetry.h:329
int get_verbosity() const
get the verbosity level
Definition pointgroupsymmetry.h:158
projector_irrep()=default
default ctor
bool get_orthonormalize_irreps() const
get the verbosity level
Definition pointgroupsymmetry.h:167
charactertable make_d2h_table() const
Definition pointgroupsymmetry.cc:470
void print_info(World &world) const
print the parameters of this projector
Definition pointgroupsymmetry.h:114
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vrhs, const Function< typename Tensor< T >::scalar_type, NDIM > &metric, std::vector< std::string > &sirreps) const
projector on a given irrep
Definition pointgroupsymmetry.h:230
charactertable make_cs_table() const
Definition pointgroupsymmetry.cc:384
std::string irrep_
choose one of the irreps or "all"
Definition pointgroupsymmetry.h:368
double lindep_
linear dependency threshold for the orthogonalization
Definition pointgroupsymmetry.h:371
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vrhs, const Function< typename Tensor< T >::scalar_type, NDIM > &metric) const
projector on a given irrep
Definition pointgroupsymmetry.h:218
charactertable make_c1_table() const
Definition pointgroupsymmetry.cc:374
projector_irrep & set_irrep(std::string irrep)
set the irrep on which this projector projects
Definition pointgroupsymmetry.h:129
charactertable table_
Definition pointgroupsymmetry.h:365
std::vector< std::string > reduce(const std::string irrep1, const std::string irrep2, const std::string irrep3) const
reduce a product of three irreps
Definition pointgroupsymmetry.h:317
bool orthonormalize_irreps_
orthonormalize within the irreps or simply discard linear dependent vectors
Definition pointgroupsymmetry.h:380
charactertable make_c2h_table() const
Definition pointgroupsymmetry.cc:438
std::vector< Function< T, NDIM > > create_symmetry_adapted_basis(const Function< T, NDIM > &rhs, std::vector< std::string > &sirreps)
create a symmetry-adapted basis from a single function
Definition pointgroupsymmetry.h:268
std::vector< std::string > reduce(const std::string irrep1, const std::string irrep2) const
reduce a product of two irreps
Definition pointgroupsymmetry.h:312
std::vector< std::string > get_all_irreps() const
Definition pointgroupsymmetry.h:186
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vrhs) const
projector on a given irrep
Definition pointgroupsymmetry.h:206
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vrhs, std::vector< std::string > &sirreps) const
projector on a given irrep
Definition pointgroupsymmetry.h:242
std::vector< Function< T, NDIM > > create_symmetry_adapted_basis(const Function< T, NDIM > &rhs, const Function< typename Tensor< T >::scalar_type, NDIM > &metric, std::vector< std::string > &sirreps)
create a symmetry-adapted basis from a single function
Definition pointgroupsymmetry.h:254
charactertable make_d2_table() const
Definition pointgroupsymmetry.cc:454
charactertable make_c2_table() const
Definition pointgroupsymmetry.cc:409
projector_irrep & set_ordering(const std::string o)
set the ordering after symmetrization: irreps or keep as is
Definition pointgroupsymmetry.h:176
std::vector< Function< T, NDIM > > sort_to_irreps(std::vector< Function< T, NDIM > > &vrhs, std::vector< std::string > &sirreps) const
sort the functions according to their irreps
Definition pointgroupsymmetry.h:436
projector_irrep & set_orthonormalize_irreps(bool flag)
get the verbosity level
Definition pointgroupsymmetry.h:161
static std::vector< R > reverse_resort(const std::vector< int > map, const std::vector< R > &vrhs)
given a mapping resort
Definition pointgroupsymmetry.h:355
projector_irrep & set_lindep(const double ld)
set the linear dependency threshold
Definition pointgroupsymmetry.h:146
std::vector< Function< T, NDIM > > apply_symmetry_operators(const std::vector< Function< T, NDIM > > &vrhs, Function< typename Tensor< T >::scalar_type, NDIM > metric, std::vector< std::string > &sirreps) const
symmetrize a vector of functions
Definition pointgroupsymmetry.cc:107
std::vector< Function< T, NDIM > > project_on_irreps(const std::vector< Function< T, NDIM > > &vhrs, const std::vector< std::string > &irreps) const
(re-)project the argument on the given irreps
Definition pointgroupsymmetry.cc:56
void print_character_table() const
print the character table
Definition pointgroupsymmetry.h:279
projector_irrep & set_verbosity(int v)
set the verbosity level
Definition pointgroupsymmetry.h:152
bool keep_ordering_
after projection: result functions being ordered according to irreps or ordering unchanged
Definition pointgroupsymmetry.h:377
static std::vector< R > resort(const std::vector< int > map, const std::vector< R > &vrhs)
given a mapping resort
Definition pointgroupsymmetry.h:345
projector_irrep(std::string pointgroup, std::string irrep="all")
ctor takes the point group and the optionally the irrep
Definition pointgroupsymmetry.h:106
charactertable get_table() const
return the character table
Definition pointgroupsymmetry.h:173
std::vector< std::string > reduce(const std::string irrep1, const std::string irrep2, const std::string irrep3, const std::string irrep4) const
reduce a product of four irreps
Definition pointgroupsymmetry.h:323
charactertable make_c2v_table() const
Definition pointgroupsymmetry.cc:421
std::vector< std::string > reduce(const std::vector< std::string > reps) const
reduce a reducible representation
Definition pointgroupsymmetry.cc:320
std::string get_pointgroup() const
get the point group name
Definition pointgroupsymmetry.h:170
std::vector< Function< T, NDIM > > operator()(const Function< T, NDIM > &rhs) const
projector on a given irrep
Definition pointgroupsymmetry.h:194
int verbosity_
verbosity level
Definition pointgroupsymmetry.h:374
charactertable make_ci_table() const
Definition pointgroupsymmetry.cc:397
static const double v
Definition hatom_sf_dirac.cc:20
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:225
implements point group operations
static const double m
Definition relops.cc:9
Definition pointgroupsymmetry.h:76
std::vector< std::string > mullikan_
Mullikan symbols of the irreps.
Definition pointgroupsymmetry.h:83
std::vector< int > characterlineT
Definition pointgroupsymmetry.h:77
std::vector< pg_operator > operators_
symmetry operators
Definition pointgroupsymmetry.h:82
std::map< std::string, characterlineT > irreps_
Definition pointgroupsymmetry.h:81
int order_
order of the point group
Definition pointgroupsymmetry.h:80
std::string schoenflies_
Schoenflies symbol of the point group.
Definition pointgroupsymmetry.h:79
bool is_abelian
currently always true
Definition pointgroupsymmetry.h:84
static const std::size_t NDIM
Definition testpdiff.cc:42