MADNESS 0.10.1
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
34/*!
35 \file mra/sdf_domainmask.h
36 \brief Defines abstract interfaces and concrete classes signed distance
37 functions and domain masks.
38
39 Interfaces for a signed distance function (sdf) and a domain mask are
40 made. The original conception of these interfaces was for doing
41 shapes and interior boundary conditions in MADNESS; however, the
42 interfaces were abstracted for other applications.
43
44 The domain mask builds on a sdf such that \f$0 <= \mbox{mask(sdf)} <= 1\f$
45 for smooth switching between domains. That said, a mask needs a sdf.
46
47 A general-purpose functor is given that combines a sdf and mask
48 to produce MADNESS functions for various entities including
49 - The domain mask (trace is the volume)
50 - The gradient of mask (related to the surface)
51 - The surface (trace is the surface area)
52 - The normal derivative of the surface
53
54 \ingroup mrabcint
55*/
56
57#ifndef MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
58#define MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
59
60#include <madness/mra/mra.h>
61
62namespace madness {
63
64 /** \brief The interface for a signed distance function (sdf).
65
66 A class implementing this interface will need to provide the sdf
67 given a point in coordinate space, and also the gradient of the
68 sdf at this point.
69
70 \c NDIM is the dimensionality of the coordinate space.
71
72 \ingroup mrabcint */
73 template <std::size_t NDIM>
75 public:
76 /** \brief Returns the signed distance from the surface,
77 - Positive is ``inside''
78 - Negative is ``outside''
79
80 \param[in] x The coordinate
81 \return The signed distance */
82 virtual double sdf(const Vector<double,NDIM>& x) const = 0;
83
84 /** \brief Returns the gradient of the signed distance from the
85 surface (i.e., \c dsdf(x)/dx[i] )
86
87 \param[in] x The coordinate
88 \return The gradient */
90 const = 0;
91
92 virtual ~SignedDFInterface() {}
93 };
94
95 /** \brief The interface for masking functions defined by signed distance
96 functions.
97
98 This interface was initially conceived for using shapes in MADNESS
99 to specify internal boundary conditions. The signed distance function
100 defines the shape, and this mask allows calculations of volumes,
101 surfaces, etc.
102
103 \ingroup mrabcint */
105 public:
106 /** \brief Returns the characteristic mask function
107 - 1 in interior
108 - 0 in exterior
109 - 1/2 on boundary
110
111 \param[in] d The signed distance from the surface
112 \return The mask or characteristic function */
113 virtual double mask(double d) const = 0;
114
115 /** \brief Returns the derivative of the characteristic mask function
116 with respect to the distance (from the surface)
117
118 \param[in] d The signed normal distance from the surface
119 \return Derivative of the characteristic mask function */
120 virtual double dmask(double d) const = 0;
121
122 /** \brief Returns the value of the normalized surface layer function
123
124 Normalized means the volume integral of this function should
125 converge to the surface area in the limit of a either an infinitely
126 thin surface or zero curvature. The function thus acts as a
127 ``delta function'' located at the boundary.
128
129 \param[in] d The signed normal distance from the surface
130 \return Normalized surface layer function */
131 virtual double surface(double d) const = 0;
132
133 /** \brief Returns the derivative of the normalized surface layer
134 function
135
136 \param[in] d The signed normal distance from the surface
137 \return Derivative of the normalized surface layer function */
138 virtual double dsurface(double d) const = 0;
139
141 };
142
143 /** \brief Framework for combining a signed distance function (sdf)
144 with a domain mask to produce MADNESS functions.
145
146 This interface provides functor functionality to produce MADNESS
147 functions for
148 - the domain mask (given the sdf)
149 - the derivative of the domain mask
150 - the surface (given the sdf)
151 - the normal derivative of the surface layer
152
153 The functor defaults to the domain mask; however, member functions
154 can toggle between the other options.
155
156 \ingroup mrabcint */
157 template <std::size_t NDIM>
158 class DomainMaskSDFFunctor : public FunctionFunctorInterface<double,NDIM> {
159
160 private:
161 /// \brief Bury the default constructor
163
164 private: // protected may be better if this becomes highly inherited
165 /// The domain mask to use
166 std::shared_ptr<DomainMaskInterface> mask;
167
168 /// The signed distance function
169 std::shared_ptr<SignedDFInterface<NDIM> > sdf;
170
171 int mswitch; ///< Which masking function to use (mask, surface, etc.)
172
173 public:
174 // switch values
175 static const int MASK; ///< Use the \c mask() function in \c mask
176 static const int MASK_COMPLEMENT; ///< Get the complement of \c mask()
177 static const int DMASK; ///< Use the \c dmask() function in \c mask
178 static const int SURFACE; ///< Use the \c surface() function in \c mask
179 static const int DSURFACE; ///< Use the \c dsurface() function in \c mask
180
181 /** \brief Constructor for mask/sdf functor
182
183 \param mask Pointer to the domain mask
184 \param sdf Pointer to the signed distance function */
185 DomainMaskSDFFunctor(std::shared_ptr<DomainMaskInterface> mask,
186 std::shared_ptr<SignedDFInterface<NDIM> > sdf)
187 : mask(mask), sdf(sdf), mswitch(MASK)
188 {}
189
190 /** \brief Constructor for mask/sdf function specifying the desired
191 function (mask, surface, etc.)
192
193 \param mask Pointer to the domain mask
194 \param sdf Pointer to the signed distance function
195 \param[in] _mswitch Which function to use (MASK, DMASK, SURFACE,
196 DSURFACE, or MASK_COMPLEMENT) */
197 DomainMaskSDFFunctor(std::shared_ptr<DomainMaskInterface> mask,
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
210 /** \brief Uses the functor interface to make a MADNESS function
211
212 \param x Point to compute value
213 \return Value of the desired function */
214 double operator()(const Vector<double,NDIM>& x) const {
216 return mask->mask(sdf->sdf(x));
218 return 1.0 - mask->mask(sdf->sdf(x));
220 return mask->dmask(sdf->sdf(x));
222 return mask->surface(sdf->sdf(x));
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
232 /** \brief Toggles which function from DomainMaskInterface to use when
233 making the MADNESS function.
234
235 \param _mswitch The function to use (should be MASK, DMASK,
236 SURFACE, DSURFACE, or MASK_COMPLEMENT) */
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>
253
254 template<std::size_t NDIM>
256
257 template<std::size_t NDIM>
259
260 template<std::size_t NDIM>
262
263 template<std::size_t NDIM>
265
266 /** \brief Provides the Li-Lowengrub-Ratz-Voight (LLRV) domain mask
267 characteristic functions.
268
269 \ingroup mrabcint
270
271 See X. Li, J. Lowengrub, A. R&auml;tz, and A. Voight, ``Solving PDEs in
272 Complex Geometries: A Diffuse Domain Approach,'' Commun. Math. Sci., 7,
273 p81-107, 2009.
274
275 Given a signed distance, this class implements in the domain mask
276 and surface functions from the above reference. For the domain mask,
277
278 \f[ \varphi(d) = \frac{1}{2}\left( 1 - \tanh\left(
279 \frac{3d}{\varepsilon} \right) \right) \f]
280
281 where \f$d\f$ is the signed distance. The normalized surface function
282 is
283
284 \f[ B(\varphi) = \frac{36}{\varepsilon} \varphi^2 (1-\varphi)^2. \f]
285
286 The constant \f$36/\varepsilon\f$ is chosen to fulfill
287
288 \f[ \int_{-\infty}^\infty B(s) \, ds = 1 \f]
289
290 This class assumes the domain mask is uniformly 0 or 1 outside
291 signed distances \f$ |8 \epsilon| \f$ since the switching function
292 becomes 0/1 to machine precision at these levels. Specifically,
293 for this function the parameter \f$ \epsilon \f$ is an effective
294 measure of the full width of the surface layer since
295
296 \f[ \int_{-\epsilon/2}^{\epsilon/2} B(s) \, ds \doteq 0.987 \f]
297
298 and
299
300 \f[ \int_{-\epsilon}^{\epsilon} B(s) \, ds \doteq 0.999963 \f] */
302 private:
303 LLRVDomainMask() : epsilon(0.0) {} ///< Forbidden
304
305 protected:
306 const double epsilon; ///< The width of the transition region
307
308 public:
309 /** \brief Constructor for the domain mask
310
311 \param[in] epsilon The effective width of the surface */
314 {}
315
316 /** \brief Value of characteristic function at normal distance d from
317 the surface
318
319 \param[in] d The signed distance. Negative is ``inside,''
320 positive is ``outside.''
321 \return The domain mask */
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
334 /** \brief Derivative of characteristic function with respect to the
335 normal distance
336
337 \param[in] d The signed distance
338 \return The derivative */
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
349 /** \brief Value of surface function at distance d normal to surface
350
351 \param[in] d The signed distance
352 \return The value of the surface function */
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
359 /** \brief Value of d(surface)/ddistance
360
361 \param[in] d The signed distance
362 \return The derivative of the surface function */
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
372 /** \brief Use a Gaussian for the surface function and the corresponding erf
373 for the domain mask. */
375 private:
376 GaussianDomainMask() : epsilon(0.0) {} ///< Forbidden
377
378 protected:
379 const double epsilon; ///< The width of the transition region
380
381 public:
382 /** \brief Constructor for the domain mask
383
384 \param[in] epsilon The effective width of the surface */
388
389 /** \brief Value of characteristic function at normal distance d from
390 the surface
391
392 \param[in] d The signed distance. Negative is ``inside,''
393 positive is ``outside.''
394 \return The domain mask */
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
407 /** \brief Derivative of characteristic function with respect to the
408 normal distance
409
410 \param[in] d The signed distance
411 \return The derivative */
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
422 /** \brief Value of surface function at distance d normal to surface
423
424 \param[in] d The signed distance
425 \return The value of the surface function */
426 double surface(double d) const {
427 return exp(-d*d*0.5/(epsilon*epsilon)) / (sqrt(2.0*constants::pi)
428 * epsilon);
429 }
430
431 /** \brief Value of d(surface)/ddistance
432
433 \param[in] d The signed distance
434 \return The derivative of the surface function */
435 double dsurface(double d) const {
436 return -exp(-d*d*0.5/(epsilon*epsilon)) * d / (sqrt(2.0*constants::pi)
438 }
439
441 };
442
443} // end of madness namespace
444
445#endif // MADNESS_MRA_SDF_DOMAINMASK_H__INCLUDED
The interface for masking functions defined by signed distance functions.
Definition sdf_domainmask.h:104
virtual double dmask(double d) const =0
Returns the derivative of the characteristic mask function with respect to the distance (from the sur...
virtual double dsurface(double d) const =0
Returns the derivative of the normalized surface layer function.
virtual double mask(double d) const =0
Returns the characteristic mask function.
virtual ~DomainMaskInterface()
Definition sdf_domainmask.h:140
virtual double surface(double d) const =0
Returns the value of the normalized surface layer function.
Framework for combining a signed distance function (sdf) with a domain mask to produce MADNESS functi...
Definition sdf_domainmask.h:158
static const int MASK
Use the mask() function in mask.
Definition sdf_domainmask.h:175
virtual ~DomainMaskSDFFunctor()
Definition sdf_domainmask.h:248
DomainMaskSDFFunctor()
Bury the default constructor.
Definition sdf_domainmask.h:162
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
void setMaskFunction(int _mswitch)
Toggles which function from DomainMaskInterface to use when making the MADNESS function.
Definition sdf_domainmask.h:237
double operator()(const Vector< double, NDIM > &x) const
Uses the functor interface to make a MADNESS function.
Definition sdf_domainmask.h:214
DomainMaskSDFFunctor(std::shared_ptr< DomainMaskInterface > mask, std::shared_ptr< SignedDFInterface< NDIM > > sdf)
Constructor for mask/sdf functor.
Definition sdf_domainmask.h:185
static const int DMASK
Use the dmask() function in mask.
Definition sdf_domainmask.h:177
static const int MASK_COMPLEMENT
Get the complement of mask()
Definition sdf_domainmask.h:176
std::shared_ptr< DomainMaskInterface > mask
The domain mask to use.
Definition sdf_domainmask.h:166
std::shared_ptr< SignedDFInterface< NDIM > > sdf
The signed distance function.
Definition sdf_domainmask.h:169
static const int SURFACE
Use the surface() function in mask.
Definition sdf_domainmask.h:178
static const int DSURFACE
Use the dsurface() function in mask.
Definition sdf_domainmask.h:179
int mswitch
Which masking function to use (mask, surface, etc.)
Definition sdf_domainmask.h:171
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
Use a Gaussian for the surface function and the corresponding erf for the domain mask.
Definition sdf_domainmask.h:374
double mask(double d) const
Value of characteristic function at normal distance d from the surface.
Definition sdf_domainmask.h:395
double dsurface(double d) const
Value of d(surface)/ddistance.
Definition sdf_domainmask.h:435
virtual ~GaussianDomainMask()
Definition sdf_domainmask.h:440
const double epsilon
The width of the transition region.
Definition sdf_domainmask.h:379
GaussianDomainMask(double epsilon)
Constructor for the domain mask.
Definition sdf_domainmask.h:385
GaussianDomainMask()
Forbidden.
Definition sdf_domainmask.h:376
double surface(double d) const
Value of surface function at distance d normal to surface.
Definition sdf_domainmask.h:426
double dmask(double d) const
Derivative of characteristic function with respect to the normal distance.
Definition sdf_domainmask.h:412
Provides the Li-Lowengrub-Ratz-Voight (LLRV) domain mask characteristic functions.
Definition sdf_domainmask.h:301
double surface(double d) const
Value of surface function at distance d normal to surface.
Definition sdf_domainmask.h:353
const double epsilon
The width of the transition region.
Definition sdf_domainmask.h:306
virtual ~LLRVDomainMask()
Definition sdf_domainmask.h:369
LLRVDomainMask()
Forbidden.
Definition sdf_domainmask.h:303
double mask(double d) const
Value of characteristic function at normal distance d from the surface.
Definition sdf_domainmask.h:322
double dmask(double d) const
Derivative of characteristic function with respect to the normal distance.
Definition sdf_domainmask.h:339
LLRVDomainMask(double epsilon)
Constructor for the domain mask.
Definition sdf_domainmask.h:312
double dsurface(double d) const
Value of d(surface)/ddistance.
Definition sdf_domainmask.h:363
The interface for a signed distance function (sdf).
Definition sdf_domainmask.h:74
virtual double sdf(const Vector< double, NDIM > &x) const =0
Returns the signed distance from the surface,.
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] )
virtual ~SignedDFInterface()
Definition sdf_domainmask.h:92
A simple, fixed dimension vector.
Definition vector.h:64
real_function_3d mask
Definition dirac-hatom.cc:27
Main include file for MADNESS and defines Function interface.
const double pi
Mathematical constant .
Definition constants.h:48
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
void error(const char *msg)
Definition world.cc:139
static const double d
Definition nonlinschro.cc:121