MADNESS  version 0.9
sdf_domainmask.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: sdf_shape.h 1792 2010-01-26 12:58:18Z rjharrison $
32 */
33 
57 #ifndef MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
58 #define MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
59 
60 #include <madness/mra/mra.h>
61 
62 namespace madness {
63 
73  template <std::size_t NDIM>
75  public:
82  virtual double sdf(const Vector<double,NDIM>& x) const = 0;
83 
90  const = 0;
91 
92  virtual ~SignedDFInterface() {}
93  };
94 
105  public:
113  virtual double mask(double d) const = 0;
114 
120  virtual double dmask(double d) const = 0;
121 
131  virtual double surface(double d) const = 0;
132 
138  virtual double dsurface(double d) const = 0;
139 
140  virtual ~DomainMaskInterface() {}
141  };
142 
157  template <std::size_t NDIM>
158  class DomainMaskSDFFunctor : public FunctionFunctorInterface<double,NDIM> {
159 
160  private:
163 
164  private: // protected may be better if this becomes highly inherited
167 
170 
171  int mswitch;
172 
173  public:
174  // switch values
175  static const int MASK;
176  static const int MASK_COMPLEMENT;
177  static const int DMASK;
178  static const int SURFACE;
179  static const int DSURFACE;
180 
187  : mask(mask), sdf(sdf), mswitch(MASK)
188  {}
189 
198  std::shared_ptr<SignedDFInterface<NDIM> > sdf, int _mswitch)
199  : mask(mask), sdf(sdf), mswitch(MASK) {
200  if(_mswitch == MASK || _mswitch == DMASK || _mswitch == SURFACE ||
201  _mswitch == DSURFACE || _mswitch == MASK_COMPLEMENT) {
202  mswitch = _mswitch;
203  }
204  else {
205  error("Unrecognized function option in DomainMaskSDFFunctor" \
206  "::DomainMaskSDFFunctor()");
207  }
208  }
209 
214  double operator()(const Vector<double,NDIM>& x) const {
215  if(mswitch == DomainMaskSDFFunctor<NDIM>::MASK)
216  return mask->mask(sdf->sdf(x));
218  return 1.0 - mask->mask(sdf->sdf(x));
219  else if(mswitch == DomainMaskSDFFunctor<NDIM>::DMASK)
220  return mask->dmask(sdf->sdf(x));
221  else if(mswitch == DomainMaskSDFFunctor<NDIM>::SURFACE)
222  return mask->surface(sdf->sdf(x));
223  else if(mswitch == DomainMaskSDFFunctor<NDIM>::DSURFACE)
224  return mask->dsurface(sdf->sdf(x));
225  else {
226  error("Unknown function from DomainMaskInterface in " \
227  "DomainMaskSDFFunctor::operator()");
228  return 0.0;
229  }
230  }
231 
237  void setMaskFunction(int _mswitch) {
238  if(_mswitch == MASK || _mswitch == DMASK || _mswitch == SURFACE ||
239  _mswitch == DSURFACE || _mswitch == MASK_COMPLEMENT) {
240  mswitch = _mswitch;
241  }
242  else {
243  error("Unrecognized function option in DomainMaskSDFFunctor" \
244  "::setMaskFunction()");
245  }
246  }
247 
249  };
250 
251  template<std::size_t NDIM>
252  const int DomainMaskSDFFunctor<NDIM>::MASK = 1;
253 
254  template<std::size_t NDIM>
255  const int DomainMaskSDFFunctor<NDIM>::MASK_COMPLEMENT = 2;
256 
257  template<std::size_t NDIM>
258  const int DomainMaskSDFFunctor<NDIM>::DMASK = 3;
259 
260  template<std::size_t NDIM>
262 
263  template<std::size_t NDIM>
264  const int DomainMaskSDFFunctor<NDIM>::DSURFACE = 5;
265 
302  private:
303  LLRVDomainMask() : epsilon(0.0) {}
304 
305  protected:
306  const double epsilon;
307 
308  public:
312  LLRVDomainMask(double epsilon)
313  : epsilon(epsilon)
314  {}
315 
322  double mask(double d) const {
323  if (d > 8.0*epsilon) {
324  return 0.0; // we're safely outside
325  }
326  else if (d < -8.0*epsilon) {
327  return 1.0; // inside
328  }
329  else {
330  return 0.5 * (1.0 - tanh(3.0 * d / epsilon));
331  }
332  }
333 
339  double dmask(double d) const {
340  if (fabs(d) > 8.0*epsilon) {
341  return 0.0; // we're safely outside or inside
342  }
343  else {
344  double tanh3d = tanh(3.0*d/epsilon);
345  return 1.5*(tanh3d*tanh3d - 1.0) / epsilon;
346  }
347  }
348 
353  double surface(double d) const {
354  double phi = mask(d);
355  double phic = 1.0 - phi;
356  return 36.0*phi*phi*phic*phic/epsilon;
357  }
358 
363  double dsurface(double d) const {
364  double phi = mask(d);
365  double dphi = dmask(d);
366  return 72.0*phi*(1.0-phi)*dphi*(1.0 - 2.0*phi)/epsilon;
367  }
368 
369  virtual ~LLRVDomainMask() {}
370  };
371 
375  private:
376  GaussianDomainMask() : epsilon(0.0) {}
377 
378  protected:
379  const double epsilon;
380 
381  public:
385  GaussianDomainMask(double epsilon)
386  : epsilon(epsilon)
387  {}
388 
395  double mask(double d) const {
396  if (d > 8.0*epsilon) {
397  return 0.0; // we're safely outside
398  }
399  else if (d < -8.0*epsilon) {
400  return 1.0; // inside
401  }
402  else {
403  return (1.0 - erf(d / (sqrt(2.0) * epsilon))) * 0.5;
404  }
405  }
406 
412  double dmask(double d) const {
413  if (fabs(d) > 8.0*epsilon) {
414  return 0.0; // we're safely outside or inside
415  }
416  else {
417  return -exp(-d*d*0.5/(epsilon*epsilon)) / (sqrt(2.0*constants::pi)
418  * epsilon);
419  }
420  }
421 
426  double surface(double d) const {
427  return exp(-d*d*0.5/(epsilon*epsilon)) / (sqrt(2.0*constants::pi)
428  * epsilon);
429  }
430 
435  double dsurface(double d) const {
436  return -exp(-d*d*0.5/(epsilon*epsilon)) * d / (sqrt(2.0*constants::pi)
437  * epsilon*epsilon*epsilon);
438  }
439 
440  virtual ~GaussianDomainMask() {}
441  };
442 
443 } // end of madness namespace
444 
445 #endif // MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
Use a Gaussian for the surface function and the corresponding erf for the domain mask.
Definition: sdf_domainmask.h:374
void error(const char *msg)
Definition: world.cc:128
Definition: shared_ptr_bits.h:38
double mask(double d) const
Value of characteristic function at normal distance d from the surface.
Definition: sdf_domainmask.h:395
const mpreal exp(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2234
const double pi
Mathematical constant pi.
Definition: constants.h:44
const mpreal erf(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2457
Main include file for MADNESS and defines Function interface.
virtual double surface(double d) const =0
Returns the value of the normalized surface layer function.
const double epsilon
The width of the transition region.
Definition: sdf_domainmask.h:379
void setMaskFunction(int _mswitch)
Toggles which function from DomainMaskInterface to use when making the MADNESS function.
Definition: sdf_domainmask.h:237
const double epsilon
The width of the transition region.
Definition: sdf_domainmask.h:306
static const int MASK_COMPLEMENT
Get the complement of mask()
Definition: sdf_domainmask.h:176
double dmask(double d) const
Derivative of characteristic function with respect to the normal distance.
Definition: sdf_domainmask.h:339
virtual double sdf(const Vector< double, NDIM > &x) const =0
Returns the signed distance from the surface,.
Framework for combining a signed distance function (sdf) with a domain mask to produce MADNESS functi...
Definition: sdf_domainmask.h:158
virtual double dmask(double d) const =0
Returns the derivative of the characteristic mask function with respect to the distance (from the sur...
Definition: density.h:50
double dsurface(double d) const
Value of d(surface)/ddistance.
Definition: sdf_domainmask.h:435
virtual ~SignedDFInterface()
Definition: sdf_domainmask.h:92
virtual ~LLRVDomainMask()
Definition: sdf_domainmask.h:369
virtual double dsurface(double d) const =0
Returns the derivative of the normalized surface layer function.
The interface for a signed distance function (sdf).
Definition: sdf_domainmask.h:74
double surface(double d) const
Value of surface function at distance d normal to surface.
Definition: sdf_domainmask.h:426
DomainMaskSDFFunctor(std::shared_ptr< DomainMaskInterface > mask, std::shared_ptr< SignedDFInterface< NDIM > > sdf, int _mswitch)
Constructor for mask/sdf function specifying the desired function (mask, surface, etc...
Definition: sdf_domainmask.h:197
double surface(double d) const
Value of surface function at distance d normal to surface.
Definition: sdf_domainmask.h:353
virtual ~DomainMaskInterface()
Definition: sdf_domainmask.h:140
tensorT sqrt(const tensorT &s, double tol=1e-8)
Computes matrix square root (not used any more?)
Definition: DFcode/moldft.cc:446
static const int DMASK
Use the dmask() function in mask.
Definition: sdf_domainmask.h:177
GaussianDomainMask(double epsilon)
Constructor for the domain mask.
Definition: sdf_domainmask.h:385
Abstract base class interface required for functors used as input to Functions.
Definition: function_interface.h:58
virtual double mask(double d) const =0
Returns the characteristic mask function.
double mask(double d) const
Value of characteristic function at normal distance d from the surface.
Definition: sdf_domainmask.h:322
Provides the Li-Lowengrub-Ratz-Voight (LLRV) domain mask characteristic functions.
Definition: sdf_domainmask.h:301
double operator()(const Vector< double, NDIM > &x) const
Uses the functor interface to make a MADNESS function.
Definition: sdf_domainmask.h:214
virtual ~GaussianDomainMask()
Definition: sdf_domainmask.h:440
DomainMaskSDFFunctor(std::shared_ptr< DomainMaskInterface > mask, std::shared_ptr< SignedDFInterface< NDIM > > sdf)
Constructor for mask/sdf functor.
Definition: sdf_domainmask.h:185
const mpreal tanh(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2352
virtual Vector< double, NDIM > grad_sdf(const Vector< double, NDIM > &x) const =0
Returns the gradient of the signed distance from the surface (i.e., dsdf(x)/dx[i] ) ...
static const int SURFACE
Use the surface() function in mask.
Definition: sdf_domainmask.h:178
const mpreal fabs(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2187
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
The interface for masking functions defined by signed distance functions.
Definition: sdf_domainmask.h:104
LLRVDomainMask(double epsilon)
Constructor for the domain mask.
Definition: sdf_domainmask.h:312
double dmask(double d) const
Derivative of characteristic function with respect to the normal distance.
Definition: sdf_domainmask.h:412
double dsurface(double d) const
Value of d(surface)/ddistance.
Definition: sdf_domainmask.h:363
virtual ~DomainMaskSDFFunctor()
Definition: sdf_domainmask.h:248
static const int DSURFACE
Use the dsurface() function in mask.
Definition: sdf_domainmask.h:179
static const int MASK
Use the mask() function in mask.
Definition: sdf_domainmask.h:175