MADNESS  version 0.9
svpe.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 
32  $Id$
33 */
34 
36 #ifndef MADNESS_SVPE_H
37 #define MADNESS_SVPE_H
38 #include <madness/mra/mra.h>
39 #include <madness/mra/lbdeux.h>
40 #include <madness/misc/ran.h>
41 #include <madness/tensor/solvers.h>
42 #include <ctime>
43 #include <list>
45 #include <madness/mra/funcplot.h>
46 #include <madness/constants.h>
47 #include <vector>
48 
51 //The screen solver, This is the solver being used. It is faster than VolumeSolventPotential
53 private:
54  World& world;
55  double& sigma;
56  double& epsilon_1;
57  double& epsilon_2;
58  int& maxiter;
59  std::vector<double>& atomic_radii;
60  std::vector< madness::Vector<double,3> > atomic_coords;
62  realfunc rdielectric;
63  realfunc surface;
64  realfunc volume;
65 public:
66  //constructor
67  ScreenSolventPotential(World& world,
68  double& sigma,
69  double& epsilon_1,
70  double& epsilon_2,
71  int& maxiter,
72  std::vector<double>& atomic_radii,
73  std::vector< madness::Vector<double,3> > atomic_coords)
74  :world(world)
75  ,sigma(sigma)
76  ,epsilon_1(epsilon_1)
77  ,epsilon_2(epsilon_2)
78  ,maxiter(maxiter)
79  ,atomic_radii(atomic_radii)
80  ,atomic_coords(atomic_coords)
81  ,dlog(3) {
82  // Functors for mask related quantities
83  realfunct rdielectric_functor(new MolecularVolumeExponentialSwitchReciprocal(sigma, epsilon_1, epsilon_2, atomic_radii, atomic_coords));
84  realfunct gradx_functor(new MolecularVolumeExponentialSwitchLogGrad(sigma, epsilon_1, epsilon_2, atomic_radii, atomic_coords,0));
85  realfunct grady_functor(new MolecularVolumeExponentialSwitchLogGrad(sigma, epsilon_1, epsilon_2, atomic_radii, atomic_coords,1));
86  realfunct gradz_functor(new MolecularVolumeExponentialSwitchLogGrad(sigma, epsilon_1, epsilon_2, atomic_radii, atomic_coords,2));
87  realfunct surface_functor(new MolecularSurface(sigma, atomic_radii, atomic_coords));
88 
89  realfunct volume_functor(new MolecularVolumeMask(sigma, atomic_radii, atomic_coords));
90  // Make the actual functions
91  const double rfourpi = -1.0/(4.0*constants::pi);
92  rdielectric = real_factory_3d(world).functor(rdielectric_functor).nofence();
93  dlog[0] = real_factory_3d(world).functor(gradx_functor).nofence();
94  dlog[1] = real_factory_3d(world).functor(grady_functor).nofence();
95  dlog[2] = real_factory_3d(world).functor(gradz_functor); // FENCE
96  scale(world, dlog, rfourpi);
97  rdielectric.truncate(false);
98  truncate(world, dlog);
99  surface = real_factory_3d(world).functor(surface_functor);
100  volume = real_factory_3d(world).functor(volume_functor);
101  }
102  //make surface charge. life is good!!!uuh!
105  real_derivative_3d Dx = free_space_derivative<double,3>(u.world(), 0);
106  real_derivative_3d Dy = free_space_derivative<double,3>(u.world(), 1);
107  real_derivative_3d Dz = free_space_derivative<double,3>(u.world(), 2);
108  return (dlog[0]*Dx(u) + dlog[1]*Dy(u) + dlog[2]*Dz(u)).truncate();
109  }
110  //compute the cavitation energy (surface_tension*solvent accessible surface)
111  double make_cav_energy(const double& surface_tension) const {
112  //surface tension should be in Newton/meter
113  double convfact = 6.423049507*std::pow(10,-4); // 1N/m = 6.423049507e-4a.u
114  return surface.trace()*surface_tension*convfact;
115  }
116  //Compute the reaction potential
117  realfunc ScreenReactionPotential(World& world,int maxiter, const realfunc rhot, bool solventplot)const {
118  const bool USE_SOLVER = true;
119  double tol = std::max(1e-3,FunctionDefaults<3>::get_thresh());
120  real_convolution_3d op = madness::CoulombOperator(world, tol*10.0, tol*0.1);
121  realfunc charge = rdielectric*rhot;
122  realfunc U0 = op(charge);
123  realfunc U = U0;//op(rhot);
124  // realfunc U = Uguess.is_initialized()? Uguess : U0;
125  double unorm = U.norm2();
126  double surf = surface.trace();
127  double vol = volume.trace();
128  if(world.rank() == 0){
129  print("SURFACE ", surf);
130  print("VOLUMEE ", vol);
131  }
132  if (USE_SOLVER) {
133  madness::NonlinearSolver solver(20);//(5);
134  // This section employs a non-linear equation solver from solvers.h
135  // http://onlinelibrary.wiley.com/doi/10.1002/jcc.10108/abstract
136  realfunc uvec, rvec;
137  if (world.rank() == 0){
138  print("\n\n");//for formating output
139 
140  madness::print(" Computing the solute-solvent potential ");
141  madness::print(" ______________________ \n ");
142 
143  madness::print("iteration "," "," residue norm2\n");
144  }
145  for (int iter=0; iter<maxiter; iter++) {
146  uvec = U;
147  coord_3d lo(0.0),hi(0.0);
148  lo[0] = -20.0;
149  hi[0] = 20.0;
150  realfunc surface_charge = make_surface_charge(U);
151  plot_line("svpe_SurfaceCharge.dat",1001,lo,hi,surface_charge);
152 
153  rvec = (U -U0 + op(surface_charge)).truncate() ;
154  realfunc U_new = solver.update(uvec,rvec);
155  double err = rvec.norm2();
156  // madness::print("iter ", iter, " error ", err, "soln(2.4566)", U(coord_3d(2.4566)));
157  if (world.rank()==0)
158  std::printf("%8d %22.10f \n", iter, err);
159 
160  if (err >0.3*unorm){ U = 0.5*U + 0.5*U_new;
161  }
162  else
163  U = U_new;
164  if (err < 10.0*tol) break;
165  }
166  }
167  if (world.rank()==0)
168  print("\n\n"); //formating output
169  //plot the potentials
170  coord_3d lo(0.0),hi(0.0);
171  lo[0] = -20.0;
172  hi[0] = 20.0;
173 
174  realfunc Ufree = op(rhot);
175  realfunc Ureaction = U - Ufree;
176  if(solventplot){
177  // plot_line("svpe_SurfaceCharge.dat",1001,lo,hi,surface_charge);
178  plot_line("svp_2D_surface.dat",1001,lo,hi,surface);
179  plot_line("svp_2D_reaction_pot.dat",1001,lo,hi,Ureaction);
180  // plotdx(surface_charge,"svpe_SurfaceCharge.dx");
181  plotdx(surface,"svp_3D_surface.dx");
182  plotdx(Ureaction,"svpe_reaction_pot.dx");
183  }
184  return Ureaction;
185  }
186 };
187 /*The class below is thw original version of the solvation model
188 //start volumeSolvenPotential
189 class VolumeSolventPotential {
190 private:
191  World& world;
192  double& sigma;
193  double& epsilon_1;
194  double& epsilon_2;
195  int& maxiter;
196  std::vector<double>& atomic_radii;
197  std::vector< madness::Vector<double,3> > atomic_coords;
198  realfunc volume;
199  realfunc surface;
200  vector_real_function_3d grad;
201  template <typename T, int NDIM>
202  struct Reciprocal {
203  void operator()(const Key<NDIM>& key, Tensor<T>& t) const {
204  UNARY_OPTIMIZED_ITERATOR(T, t, *_p0 = 1.0/(*_p0));
205  }
206  template <typename Archive> void serialize(Archive& ar) {}
207  };
208 //Reciprocal of the dielectric function
209  realfunc ReciprocalDielectric(double epsilon_1,double epsilon_2 ,const realfunc& volume) const {
210  realfunc rdielectric = epsilon_1*volume + epsilon_2*(1.0-volume);
211  rdielectric.unaryop(Reciprocal<double,3>());
212  return rdielectric;
213  }
214 //Guess potential function
215  realfunc GuessPotential(World& world,const realfunc& rho) const {
216  double tol = madness::FunctionDefaults<3>::get_thresh();
217  real_convolution_3d op = madness::CoulombOperator(world, tol*10.0, tol*0.1);
218  return op(ReciprocalDielectric(epsilon_1,epsilon_2,volume)*rho); //U_0
219 }
220 //Molecular potential i.e potential due to the molecular charge distribution
221  realfunc MolecularPotential(const realfunc rho)const {
222  return (ReciprocalDielectric(epsilon_1,epsilon_2,volume).scale(-1.0)*rho);
223  }
224  //compute the surface charge
225 realfunc make_surfcharge(const realfunc& u) const {
226  real_derivative_3d Dx = free_space_derivative<double,3>(u.world(), 0);
227  real_derivative_3d Dy = free_space_derivative<double,3>(u.world(), 1);
228  real_derivative_3d Dz = free_space_derivative<double,3>(u.world(), 2);
229 // Gradient of dielectric
230  realfunc di_gradx = (epsilon_1-epsilon_2)*grad[0];
231  realfunc di_grady = (epsilon_1-epsilon_2)*grad[1];
232  realfunc di_gradz = (epsilon_1-epsilon_2)*grad[2];
233  const double rfourpi = -1.0/(4.0*constants::pi);
234  return (ReciprocalDielectric(epsilon_1,epsilon_2,volume).scale(rfourpi) \
235  *(di_gradx*Dx(u) + di_grady*Dy(u) + di_gradz*Dz(u)));//.truncate();
236 }
237 public:
238 //Compute the surface potential
239  realfunc VolumeReactionPotential(const realfunc& rhot)const {
240  const bool USE_SOLVER = true;
241  double tol = std::max(1e-3,FunctionDefaults<3>::get_thresh());
242  real_convolution_3d op = madness::CoulombOperator(world, tol*10.0, tol*0.1);
243  realfunc U = GuessPotential(world, rhot);
244  realfunc W = MolecularPotential(rhot);
245  realfunc U0 = op(W);
246  double unorm = U.norm2();
247  if (USE_SOLVER) {
248  madness::NonlinearSolver solver;
249  // This section employs a non-linear equation solver from solvers.h
250  // http://onlinelibrary.wiley.com/doi/10.1002/jcc.10108/abstract
251  if (world.rank() == 0){
252  print("\n\n");//for formating output
253  madness::print(" Computing the solute-solvent potential ");
254  madness::print(" ______________________ \n ");
255 
256  madness::print("iteration "," "," residue norm2\n");
257  }
258  realfunc uvec, rvec;
259  for (int iter=0; iter<maxiter; iter++) {
260  uvec = U;
261  realfunc Scharge = make_surfcharge(U);
262  rvec = (U + U0 + op(Scharge)).truncate();
263  realfunc U_new = solver.update(uvec,rvec);
264  double err = rvec.norm2();
265  if (world.rank()==0)
266  madness::print(" ", iter," " , err);
267  if (err >0.3*unorm){ U = 0.5*U + 0.5*U_new;
268  }
269 
270  else
271  U = U_new;
272  if(err < 10.0*tol) break;
273  }
274  }
275 //compute the reaction potential after total potential converges
276 //U_ref is the total vacouo potential which is the reference potential
277 //rho_total is the sum of the nuclear and electronic potentials
278  realfunc U_ref = op(rhot);
279  return U - U_ref;
280  }
281 //compute the cavitation energy (surface_tension*solvent accessible surface)
282  double make_cav_energy(const double& surface_tension) const {
283  //surface tension should be in Newton/meter
284  double convfact = 6.423049507*std::pow(10,-4); // 1N/m = 6.423049507e-4a.u
285  return surface.trace()*surface_tension*convfact;
286  }
287 //constructor
288  VolumeSolventPotential(World& world,
289  double& sigma,
290  double& epsilon_1,
291  double& epsilon_2,
292  int& maxiter,
293  std::vector<double>& atomic_radii,
294  std::vector< madness::Vector<double,3> > atomic_coords):
295  world(world),
296  sigma(sigma),
297  epsilon_1(epsilon_1),
298  epsilon_2(epsilon_2),
299  maxiter(maxiter),
300  atomic_radii(atomic_radii),
301  atomic_coords(atomic_coords),
302  grad(3){
303  realfunct volume_functor(new MolecularVolumeMask(sigma, atomic_radii, atomic_coords));
304  realfunct surface_functor(new MolecularVolumeMask(sigma, atomic_radii, atomic_coords));
305  realfunct gradx_functor(new MolecularVolumeMaskGrad(sigma, atomic_radii, atomic_coords, 0));
306  realfunct grady_functor(new MolecularVolumeMaskGrad(sigma, atomic_radii, atomic_coords, 1));
307  realfunct gradz_functor(new MolecularVolumeMaskGrad(sigma, atomic_radii, atomic_coords, 2));
308  //make real functions
309  volume = real_factory_3d(world).functor(volume_functor).initial_level(4);
310  surface = real_factory_3d(world).functor(surface_functor);
311  grad[0] = real_factory_3d(world).functor(gradx_functor);
312  grad[1] = real_factory_3d(world).functor(grady_functor);
313  grad[2] = real_factory_3d(world).functor(gradz_functor);
314  }
315 }; //end VolumeSolventPotential
316 */
317 #endif
A simple Krylov-subspace nonlinear equation solver.
Definition: nonlinsol.h:91
Definition: shared_ptr_bits.h:38
Main include file for MADNESS and defines Function interface.
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:577
Definition: molecularmask.h:252
double make_cav_energy(const double &surface_tension) const
Definition: svpe.h:111
void plotdx(const Function< T, NDIM > &f, const char *filename, const Tensor< double > &cell=FunctionDefaults< NDIM >::get_cell(), const std::vector< long > &npt=std::vector< long >(NDIM, 201L), bool binary=true)
Writes an OpenDX format file with a cube/slice of points on a uniform grid.
Definition: mraimpl.h:3228
void truncate(World &world, std::vector< Function< T, NDIM > > &v, double tol=0.0, bool fence=true)
Truncates a vector of functions.
Definition: vmra.h:194
Defines common mathematical and physical constants.
Vector< double, 3 > coord_3d
Definition: funcplot.h:634
Definition: molecularmask.h:131
Defines interfaces for optimization and non-linear equation solvers.
real_function_3d realfunc
Definition: svpe.h:49
Computes the reciprocal of MolecularVolumeExponentialSwitch.
Definition: molecularmask.h:233
std::vector< real_function_3d > vector_real_function_3d
Definition: functypedefs.h:79
real_functor_3d realfunct
Definition: svpe.h:50
realfunc ScreenReactionPotential(World &world, int maxiter, const realfunc rhot, bool solventplot) const
Definition: svpe.h:117
Function< double, 3 > real_function_3d
Definition: functypedefs.h:65
Derivative< double, 3 > real_derivative_3d
Definition: functypedefs.h:170
World & world() const
Returns the world.
Definition: mra.h:622
double norm2() const
Returns the 2-norm of the function ... global sum ... works in either basis.
Definition: mra.h:650
#define max(a, b)
Definition: lda.h:53
void scale(World &world, std::vector< Function< T, NDIM > > &v, const std::vector< Q > &factors, bool fence=true)
Scales inplace a vector of functions by distinct values.
Definition: vmra.h:290
Function< double, NDIM > update(const Function< double, NDIM > &u, const Function< double, NDIM > &r, const double rcondtol=1e-8, const double cabsmax=1000.0)
Computes next trial solution vector.
Definition: nonlinsol.h:111
void print(const tensorT &t)
Definition: DFcode/mcpfit.cc:140
T trace() const
Returns global value of int(f(x),x) ... global comm required.
Definition: mra.h:1034
SeparatedConvolution< double, 3 > real_convolution_3d
Definition: functypedefs.h:121
realfunc make_surface_charge(const realfunc &u) const
Given the full Coulomb potential computes the surface charge.
Definition: svpe.h:104
std::shared_ptr< FunctionFunctorInterface< double, 3 > > real_functor_3d
Definition: functypedefs.h:107
Implements the SignedDFInterface for common 3-D geometric objects.This file provides signed distance ...
ScreenSolventPotential(World &world, double &sigma, double &epsilon_1, double &epsilon_2, int &maxiter, std::vector< double > &atomic_radii, std::vector< madness::Vector< double, 3 > > atomic_coords)
Definition: svpe.h:67
Definition: svpe.h:52
void plot_line(const char *filename, int npt, const Vector< double, NDIM > &lo, const Vector< double, NDIM > &hi, const Function< T, NDIM > &f)
Generates ASCII file tabulating f(r) at npoints along line r=lo,...,hi.
Definition: funcplot.h:388
Implements (2nd generation) static load/data balancing for functions.
Defines/implements plotting interface for functions.
Tensor< double > op(const Tensor< double > &x)
Definition: kain.cc:508
void print(const A &a)
Print a single item to std::cout terminating with new line.
Definition: print.h:122
FunctionFactory< double, 3 > real_factory_3d
Definition: functypedefs.h:93
Returns the requested component of the derivative of the log of MolecularVolumeExponentialSwitch.
Definition: molecularmask.h:295