MADNESS 0.10.1
potentialmanager.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#ifndef MADNESS_CHEM_POTENTIALMANAGER_H__INCLUDED
34#define MADNESS_CHEM_POTENTIALMANAGER_H__INCLUDED
35
36/// \file moldft/potentialmanager.h
37/// \brief Declaration of molecule related classes and functions
38
43#include <vector>
44#include <string>
45#include <iostream>
46#include <fstream>
47#include <sstream>
48#include <algorithm>
49#include <ctype.h>
50#include <cmath>
52#include <madness/misc/misc.h>
54#include <madness/mra/mra.h>
55
56namespace madness {
58private:
60public:
63
64 double operator()(const coord_3d& x) const {
65 return molecule.nuclear_attraction_potential(x[0], x[1], x[2]);
66 }
67
68 std::vector<coord_3d> special_points() const {return molecule.get_all_coords_vec();}
69};
70
72private:
74public:
77
78 double operator()(const coord_3d& x) const {
79 return molecule.molecular_core_potential(x[0], x[1], x[2]);
80 }
81
82 std::vector<coord_3d> special_points() const {return molecule.get_all_coords_vec();}
83};
84
87 const int atom;
88 const unsigned int core;
89 const int m;
90public:
91 CoreOrbitalFunctor(Molecule& molecule, int atom, unsigned int core, int m)
92 : molecule(molecule), atom(atom), core(core), m(m) {};
93 double operator()(const coord_3d& r) const {
94 return molecule.core_eval(atom, core, m, r[0], r[1], r[2]);
95 };
96};
97
100 const int atom, axis;
101 const unsigned int core;
102 const int m;
103public:
106 double operator()(const coord_3d& r) const {
107 return molecule.core_derivative(atom, axis, core, m, r[0], r[1], r[2]);
108 };
109};
110
111/// Default functor for the nuclear charge density
112
113/// This assumes the default nuclear model optimized to produce potential
114/// close that of a point nucleus (smoothed Coulomb potential). The model
115/// is
117private:
121 std::vector<coord_3d> special_points_;
122 int maxR;
124 double rscale = 1.0;
125public:
126 /// Generic constructor, can handle open and periodic boundaries
127 /// \param molecule atoms
128 /// \param bc boundary conditions
129 /// \param cell simulation cell (unit cell, if periodic)
130 /// \param special_level the initial refinement level
131 /// \param rscale setting `rscale>1` will make a nucleus larger by a factor of \p rscale (in other words, `rcut` is multiplied by the inverse of by this)
135 int special_level = 15,
136 double rscale = 1.0);
137
138 double operator()(const coord_3d& x) const final;
139
140 std::vector<coord_3d> special_points() const final;
141
142 Level special_level() const final;
143
145
146};
147
148/// evaluates Wigner-Seitz-truncated potential in the simulation cell, due to periodic or nonperiodic source functions
150public:
151 /// Constructs a WignerSeitzPotentialFunctor evaluating potential
152 /// in simulation cell \p c due to point charges \p atoms optionally
153 /// periodically repeated according to boundary conditions \p b
154 /// and interaction range along each Cartesian direction limited by \p r .
155 /// Lattice summation range along each axis can be overridden by specifying
156 /// \p lattice_sum_range .
157 /// \tparam Int
158 /// \param atoms list of point charges in the simulation cell
159 /// \param c the simulation cell dimensions
160 /// \param b the boundary conditions
161 /// \param r the kernel range
162 /// \param lattice_sum_range overrides the lattice summation range that by default
163 template <typename Int>
165 BoundaryConditions<3> b, std::array<KernelRange, 3> r,
166 std::array<Int, 3> lattice_sum_range)
167 : atoms(atoms), cell(std::move(c)), bc(std::move(b)), range(std::move(r)),
168 cell_width{cell(0, 1) - cell(0, 0), cell(1, 1) - cell(1, 0),
169 cell(2, 1) - cell(2, 0)},
170 rcell_width{1. / cell_width[0], 1. / cell_width[1],
171 1. / cell_width[2]}, lattice_sum_range{lattice_sum_range[0], lattice_sum_range[1], lattice_sum_range[2]} {
172 for (int d = 0; d != 3; ++d)
173 MADNESS_ASSERT(lattice_sum_range[d] >= 0);
174 }
175
176 /// same as the standard ctor, but lacks the ability to override the lattice sum range
178 BoundaryConditions<3> b, std::array<KernelRange, 3> r) :
179 // N.B. move is a cast, calling make_default_lattice_sum_range like this is OK
180 WignerSeitzPotentialFunctor(atoms, std::move(c), std::move(b), std::move(r), make_default_lattice_sum_range(b,r)) {}
181
182 double operator()(const coord_3d &x) const;
183
184 std::vector<coord_3d> special_points() const {
185 return atoms.get_all_coords_vec();
186 }
187
188 static std::array<std::int64_t, 3> make_default_lattice_sum_range(const BoundaryConditions<3>& bc, const std::array<KernelRange, 3>& range) {
189 std::array<std::int64_t, 3> result;
190 for (int d = 0; d != 3; ++d) {
191 result[d] = bc.is_periodic()[d] ? (range[d].iextent_x2() + 1) / 2 : 0;
192 }
193 return result;
194 }
195
196private:
200 const std::array<KernelRange, 3> range;
201 const std::array<std::int64_t, 3> lattice_sum_range; // range of lattice summation, default is # of cells in each direction with nonzero contributions to the simulation cell
202 const std::array<double, 3> cell_width;
203 const std::array<double, 3> rcell_width;
204};
205
206class SAPFunctor : public FunctionFunctorInterface<double,3> {
207 private:
208 const Atom& atom;
212 std::vector<coord_3d> special_points_;
213 int special_level_ = 15;
214 public:
215 /// Generic constructor, can handle open and periodic boundaries
216 /// \param molecule atoms
217 /// \param smoothing_param controls smoothness of 1/r potential.
218 /// \param bc boundary conditions
219 /// \param cell simulation cell (unit cell, if periodic)
220 /// \param special_level the initial refinement level
221 SAPFunctor(const Atom& atom,
222 double smoothing_param,
225 int special_level = 15);
226
227 double operator()(const coord_3d& x) const;
228};
229
231private:
234std::string core_type_;
235
236public:
237 PotentialManager(const Molecule& molecule, const std::string& core_type)
238 : mol(molecule), core_type_(core_type) {}
239
240 const Molecule& molecule() const {
241 return this->mol;
242 }
243
244 const std::string& core_type() const {
245 return this->core_type_;
246 }
247
249 return vnuc;
250 }
251
252 vector_real_function_3d core_projection(World & world, const vector_real_function_3d& psi, const bool include_Bc = true)
253 {
254 int npsi = psi.size();
255 if (npsi == 0) return psi;
256 int natom = mol.natom();
257 vector_real_function_3d proj = zero_functions_compressed<double,3>(world, npsi);
258 real_tensor overlap_sum(static_cast<long>(npsi));
259
260 for (int i=0; i<natom; ++i) {
261 Atom at = mol.get_atom(i);
262 unsigned int atn = at.atomic_number;
263 unsigned int nshell = mol.n_core_orb(atn);
264 if (nshell == 0) continue;
265 for (unsigned int c=0; c<nshell; ++c) {
266 unsigned int l = mol.get_core_l(atn, c);
267 int max_m = (l+1)*(l+2)/2;
268 nshell -= max_m - 1;
269 for (int m=0; m<max_m; ++m) {
270 real_function_3d core = real_factory_3d(world).functor(real_functor_3d(new CoreOrbitalFunctor(mol, i, c, m)));
271 real_tensor overlap = inner(world, core, psi);
272 overlap_sum += overlap;
273 for (int j=0; j<npsi; ++j) {
274 if (include_Bc) overlap[j] *= mol.get_core_bc(atn, c);
275 proj[j] += core.scale(overlap[j]);
276 }
277 }
278 }
279 world.gop.fence();
280 }
281 if (world.rank() == 0) print("sum_k <core_k|psi_i>:", overlap_sum);
282 return proj;
283 }
284
285 double core_projector_derivative(World & world, const vector_real_function_3d& mo, const real_tensor& occ, int atom, int axis)
286 {
287 vector_real_function_3d cores, dcores;
288 std::vector<double> bc;
289 unsigned int atn = mol.get_atom(atom).atomic_number;
290 unsigned int ncore = mol.n_core_orb(atn);
291
292 // projecting core & d/dx core
293 for (unsigned int c=0; c<ncore; ++c) {
294 unsigned int l = mol.get_core_l(atn, c);
295 int max_m = (l+1)*(l+2)/2;
296 for (int m=0; m<max_m; ++m) {
298 cores.push_back(real_function_3d(real_factory_3d(world).functor(func).truncate_on_project()));
300 dcores.push_back(real_function_3d(real_factory_3d(world).functor(func).truncate_on_project()));
301 bc.push_back(mol.get_core_bc(atn, c));
302 }
303 }
304
305 // calc \sum_i occ_i <psi_i|(\sum_c Bc d/dx |core><core|)|psi_i>
306 double r = 0.0;
307 for (unsigned int c=0; c<cores.size(); ++c) {
308 double rcore= 0.0;
309 real_tensor rcores = inner(world, cores[c], mo);
310 real_tensor rdcores = inner(world, dcores[c], mo);
311 for (unsigned int i=0; i<mo.size(); ++i) {
312 rcore += rdcores[i] * rcores[i] * occ[i];
313 }
314 r += 2.0 * bc[c] * rcore;
315 }
316
317 return r;
318 }
319
321 if (core_type_.substr(0,3) == "mcp") {
322 // START_TIMER(world);
323 gaxpy(world, 1.0, Vpsi, 1.0, core_projection(world, amo));
324 // END_TIMER(world, "MCP Core Projector");
325 }
326 }
327
329 double safety = 0.1;
330 double vtol = FunctionDefaults<3>::get_thresh() * safety;
331 vnuc = real_factory_3d(world).functor(real_functor_3d(new MolecularPotentialFunctor(mol))).thresh(vtol).truncate_on_project();
333 vnuc.reconstruct();
334 // "" is legacy core_type value for all-electron (also be used by CorePotentialManager)
335 // "none" is current core_type value for all-electron
336 if (core_type_ != "" && core_type_ != "none") {
337 real_function_3d c_pot = real_factory_3d(world).functor(real_functor_3d(new MolecularCorePotentialFunctor(mol))).thresh(vtol).initial_level(4);
339 c_pot.reconstruct();
340 vnuc += c_pot;
341 vnuc.truncate();
342 }
343 }
344};
345}
346
347#endif
Declaration of utility class and functions for atom.
Definition molecule.h:58
unsigned int atomic_number
Atomic number.
Definition molecule.h:61
This class is used to specify boundary conditions for all operators.
Definition bc.h:72
Definition potentialmanager.h:98
double operator()(const coord_3d &r) const
Definition potentialmanager.h:106
CoreOrbitalDerivativeFunctor(Molecule &molecule, int atom, int axis, unsigned int core, int m)
Definition potentialmanager.h:104
const Molecule molecule
Definition potentialmanager.h:99
const int axis
Definition potentialmanager.h:100
const int atom
Definition potentialmanager.h:100
const unsigned int core
Definition potentialmanager.h:101
const int m
Definition potentialmanager.h:102
Definition potentialmanager.h:85
CoreOrbitalFunctor(Molecule &molecule, int atom, unsigned int core, int m)
Definition potentialmanager.h:91
double operator()(const coord_3d &r) const
Definition potentialmanager.h:93
const int m
Definition potentialmanager.h:89
const unsigned int core
Definition potentialmanager.h:88
const int atom
Definition potentialmanager.h:87
const Molecule molecule
Definition potentialmanager.h:86
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:100
static double thresh
Truncation threshold.
Definition funcdefaults.h:106
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
Function< T, NDIM > & scale(const Q q, bool fence=true)
Inplace, scale the function by a constant. No communication except for optional fence.
Definition mra.h:978
double thresh() const
Returns value of truncation threshold. No communication.
Definition mra.h:592
void set_thresh(double value, bool fence=true)
Sets the value of the truncation threshold. Optional global fence.
Definition mra.h:602
Function< T, NDIM > & truncate(double tol=0.0, bool fence=true)
Truncate the function with optional fence. Compresses with fence if not compressed.
Definition mra.h:627
const Function< T, NDIM > & reconstruct(bool fence=true) const
Reconstructs the function, transforming into scaling function basis. Possible non-blocking comm.
Definition mra.h:800
Definition potentialmanager.h:71
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition potentialmanager.h:82
MolecularCorePotentialFunctor(const Molecule &molecule)
Definition potentialmanager.h:75
double operator()(const coord_3d &x) const
Definition potentialmanager.h:78
const Molecule & molecule
Definition potentialmanager.h:73
Definition potentialmanager.h:57
MolecularPotentialFunctor(const Molecule &molecule)
Definition potentialmanager.h:61
const Molecule & molecule
Definition potentialmanager.h:59
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition potentialmanager.h:68
double operator()(const coord_3d &x) const
Definition potentialmanager.h:64
Definition molecule.h:124
std::vector< madness::Vector< double, 3 > > get_all_coords_vec() const
Definition molecule.cc:408
double get_core_bc(unsigned int atn, unsigned int c) const
Definition molecule.h:371
const Atom & get_atom(unsigned int i) const
Definition molecule.cc:447
double core_derivative(int atom, int axis, unsigned int core, int m, double x, double y, double z) const
Definition molecule.cc:1094
double molecular_core_potential(double x, double y, double z) const
Definition molecule.cc:1107
double nuclear_attraction_potential(double x, double y, double z) const
nuclear attraction potential for the whole molecule
Definition molecule.cc:960
size_t natom() const
Definition molecule.h:387
double core_eval(int atom, unsigned int core, int m, double x, double y, double z) const
Definition molecule.cc:1085
unsigned int get_core_l(unsigned int atn, unsigned int c) const
Definition molecule.h:367
unsigned int n_core_orb(unsigned int atn) const
Definition molecule.h:360
Default functor for the nuclear charge density.
Definition potentialmanager.h:116
BoundaryConditions< 3 > bc_
Definition potentialmanager.h:119
Level special_level() const final
Override this to change the minimum level of refinement at special points (default is 6)
Definition potentialmanager.cc:85
Tensor< double > cell
Definition potentialmanager.h:120
const Molecule & atoms
Definition potentialmanager.h:118
NuclearDensityFunctor & set_rscale(double rscale)
Definition potentialmanager.cc:89
double rscale
Definition potentialmanager.h:124
double operator()(const coord_3d &x) const final
Definition potentialmanager.cc:57
std::vector< coord_3d > special_points_
Definition potentialmanager.h:121
int maxR
Definition potentialmanager.h:122
std::vector< coord_3d > special_points() const final
Override this to return list of special points to be refined more deeply.
Definition potentialmanager.cc:83
int special_level_
Definition potentialmanager.h:123
Definition potentialmanager.h:230
Molecule mol
Definition potentialmanager.h:232
void apply_nonlocal_potential(World &world, const vector_real_function_3d &amo, vector_real_function_3d Vpsi)
Definition potentialmanager.h:320
const Molecule & molecule() const
Definition potentialmanager.h:240
const real_function_3d & vnuclear()
Definition potentialmanager.h:248
PotentialManager(const Molecule &molecule, const std::string &core_type)
Definition potentialmanager.h:237
const std::string & core_type() const
Definition potentialmanager.h:244
real_function_3d vnuc
Definition potentialmanager.h:233
vector_real_function_3d core_projection(World &world, const vector_real_function_3d &psi, const bool include_Bc=true)
Definition potentialmanager.h:252
double core_projector_derivative(World &world, const vector_real_function_3d &mo, const real_tensor &occ, int atom, int axis)
Definition potentialmanager.h:285
void make_nuclear_potential(World &world)
Definition potentialmanager.h:328
std::string core_type_
Definition potentialmanager.h:234
Definition potentialmanager.h:206
const Atom & atom
Definition potentialmanager.h:208
BoundaryConditions< 3 > bc_
Definition potentialmanager.h:210
std::vector< coord_3d > special_points_
Definition potentialmanager.h:212
Tensor< double > cell
Definition potentialmanager.h:211
double smoothing_param
Definition potentialmanager.h:209
A tensor is a multidimensional array.
Definition tensor.h:317
evaluates Wigner-Seitz-truncated potential in the simulation cell, due to periodic or nonperiodic sou...
Definition potentialmanager.h:149
const BoundaryConditions< 3 > bc
Definition potentialmanager.h:199
WignerSeitzPotentialFunctor(const Molecule &atoms, Tensor< double > c, BoundaryConditions< 3 > b, std::array< KernelRange, 3 > r)
same as the standard ctor, but lacks the ability to override the lattice sum range
Definition potentialmanager.h:177
const std::array< double, 3 > rcell_width
Definition potentialmanager.h:203
const std::array< double, 3 > cell_width
Definition potentialmanager.h:202
const std::array< std::int64_t, 3 > lattice_sum_range
Definition potentialmanager.h:201
WignerSeitzPotentialFunctor(const Molecule &atoms, Tensor< double > c, BoundaryConditions< 3 > b, std::array< KernelRange, 3 > r, std::array< Int, 3 > lattice_sum_range)
Definition potentialmanager.h:164
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition potentialmanager.h:184
const std::array< KernelRange, 3 > range
Definition potentialmanager.h:200
const Tensor< double > cell
Definition potentialmanager.h:198
const Molecule & atoms
Definition potentialmanager.h:197
static std::array< std::int64_t, 3 > make_default_lattice_sum_range(const BoundaryConditions< 3 > &bc, const std::array< KernelRange, 3 > &range)
Definition potentialmanager.h:188
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:161
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:320
WorldGopInterface & gop
Global operations.
Definition world.h:207
Declaration of core potential related class.
std::complex< double > inner(const Fcwf &psi, const Fcwf &phi)
Definition fcwf.cc:275
double psi(const Vector< double, 3 > &r)
Definition hatom_energy.cc:78
double func(double x)
A simple program for testing the CubicInterpolationTable class.
Definition interp3.cc:43
Provides 1D cubic interpolation class.
#define final(a, b, c)
Definition lookup3.c:153
#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
void print(const tensorT &t)
Definition mcpfit.cc:140
Header to declare stuff which has not yet found a home.
Main include file for MADNESS and defines Function interface.
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
std::shared_ptr< FunctionFunctorInterface< double, 3 > > real_functor_3d
Definition functypedefs.h:122
std::vector< real_function_3d > vector_real_function_3d
Definition functypedefs.h:94
int Level
Definition key.h:57
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:108
void gaxpy(const double a, ScalarResult< T > &left, const double b, const T &right, const bool fence=true)
the result type of a macrotask must implement gaxpy
Definition macrotaskq.h:246
Definition mraimpl.h:50
static const double b
Definition nonlinschro.cc:119
static const double d
Definition nonlinschro.cc:121
static const double c
Definition relops.cc:10
static const double m
Definition relops.cc:9
Defines and implements most of Tensor.
std::size_t axis
Definition testpdiff.cc:59
static Molecule molecule
Definition testperiodicdft.cc:39
real_function_1d vnuc(World &world, double t)
Definition testspectralprop.cc:347