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 
64 #include <madness/world/MADworld.h>
66 
67 namespace madness {
68 
69  template<typename T, std::size_t NDIM>
70  class Function;
71 }
72 
73 
74 
75 namespace 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 
100 public:
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
153  verbosity_=v;
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
173  charactertable get_table() const {return 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
279  void print_character_table() const {
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 
363 private:
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
374  int verbosity_=1;
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< 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
projector_irrep & set_orthonormalize_irreps(bool flag)
get the verbosity level
Definition: pointgroupsymmetry.h:161
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
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
charactertable make_c1_table() const
Definition: pointgroupsymmetry.cc:374
charactertable table_
Definition: pointgroupsymmetry.h:365
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
bool orthonormalize_irreps_
orthonormalize within the irreps or simply discard linear dependent vectors
Definition: pointgroupsymmetry.h:380
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
std::vector< std::string > reduce(const std::string irrep1, const std::string irrep2) const
reduce a product of two irreps
Definition: pointgroupsymmetry.h:312
charactertable make_c2h_table() const
Definition: pointgroupsymmetry.cc:438
projector_irrep & set_lindep(const double ld)
set the linear dependency threshold
Definition: pointgroupsymmetry.h:146
static std::vector< R > resort(const std::vector< int > map, const std::vector< R > &vrhs)
given a mapping resort
Definition: pointgroupsymmetry.h:345
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 > > 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< 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
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
charactertable make_d2_table() const
Definition: pointgroupsymmetry.cc:454
charactertable make_c2_table() const
Definition: pointgroupsymmetry.cc:409
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
bool keep_ordering_
after projection: result functions being ordered according to irreps or ordering unchanged
Definition: pointgroupsymmetry.h:377
std::vector< Function< T, NDIM > > operator()(const Function< T, NDIM > &rhs) const
projector on a given irrep
Definition: pointgroupsymmetry.h:194
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
projector_irrep(std::string pointgroup, std::string irrep="all")
ctor takes the point group and the optionally the irrep
Definition: pointgroupsymmetry.h:106
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 get_table() const
return the character table
Definition: pointgroupsymmetry.h:173
static std::vector< R > reverse_resort(const std::vector< int > map, const std::vector< R > &vrhs)
given a mapping resort
Definition: pointgroupsymmetry.h:355
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
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
projector_irrep & set_verbosity(int v)
set the verbosity level
Definition: pointgroupsymmetry.h:152
projector_irrep & set_irrep(std::string irrep)
set the irrep on which this projector projects
Definition: pointgroupsymmetry.h:129
int verbosity_
verbosity level
Definition: pointgroupsymmetry.h:374
projector_irrep & set_ordering(const std::string o)
set the ordering after symmetrization: irreps or keep as is
Definition: pointgroupsymmetry.h:176
charactertable make_ci_table() const
Definition: pointgroupsymmetry.cc:397
std::vector< Fcwf > transform(World &world, std::vector< Fcwf > &a, Tensor< std::complex< double >> U)
Definition: fcwf.cc:477
const double m
Definition: gfit.cc:199
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
File holds all helper structures necessary for the CC_Operator and CC2 class.
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
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