36 #ifndef AIMS_DIFFUSION_SMOOTHER_D_H 37 #define AIMS_DIFFUSION_SMOOTHER_D_H 67 laplacian(1,1,0) = laplacian(1,0,1) = laplacian(0,1,1) =
68 laplacian(2,1,1) = laplacian(1,2,1) = laplacian(1,1,2) = 0.5;
69 laplacian(1,1,1) = -3;
79 std::cerr <<
"diffusionConvolution Smoother: " 80 <<
"maxiter negative value is forbidden" << std::endl;
87 int maxiter,
bool verbose)
92 kernel(0,1,1) = kernel(2,1,1) = this->_dt / ( ima.
sizeX() * ima.
sizeX() );
93 kernel(1,0,1) = kernel(1,2,1) = this->_dt / ( ima.
sizeY() * ima.
sizeY() );
94 kernel(1,1,0) = kernel(1,1,2) = this->_dt / ( ima.
sizeZ() * ima.
sizeZ() );
95 kernel(1,1,1) = -this->_dt * (2. / (ima.
sizeX() * ima.
sizeX())
100 kernel(1,1,1) = 1. + kernel(1,1,1);
114 tmp1 = &imaF; tmp2 = &ima2;
116 for (
int i = 0; i < maxiter; i++)
118 if (verbose) std::cout <<
"+" << std::flush;
119 if( _hasConstantSources )
124 T & v = _constantSources( x, y, z );
125 if( v != _constantSourcesBackground )
126 (*tmp1)( x, y, z ) = v;
129 (*tmp2) = convolution.
doit((*tmp1), kernel);
135 if( _hasConstantSources )
140 T & v = _constantSources( x, y, z );
141 if( v != _constantSourcesBackground )
142 (*tmp1)( x, y, z ) = v;
146 if (verbose) std::cout <<
"Finished" << std::endl;
159 _constantSources = sources;
160 _constantSourcesBackground = bgr;
161 _hasConstantSources =
true;
165 template <
typename T>
168 _hasConstantSources =
false;
177 this->check(maxiter);
180 kernel(0,1,1) = kernel(2,1,1) = this->_dt / ( ima.
sizeX() * ima.
sizeX() );
181 kernel(1,0,1) = kernel(1,2,1) = this->_dt / ( ima.
sizeY() * ima.
sizeY() );
182 kernel(1,1,0) = kernel(1,1,2) = this->_dt / ( ima.
sizeZ() * ima.
sizeZ() );
183 kernel(1,1,1) = -this->_dt * (2. / (ima.
sizeX() * ima.
sizeX())
188 kernel(1,1,1) = 1. + kernel(1,1,1);
197 this->_background, this->_safe);
203 tmp1 = &imaF; tmp2 = &ima2;
205 for (
int i = 0; i < maxiter; i++)
207 if (verbose) std::cout <<
"+" << std::flush;
208 if (_has_neumann_condition)
209 update_neumann_conditions(*tmp1);
210 (*tmp2) = convolution.
doit((*tmp1), kernel);
216 if (verbose) std::cout <<
"Finished" << std::endl;
225 template<
typename T>
inline 229 _has_neumann_condition =
true;
230 _neumann_conditions.push_back(p);
242 for (
unsigned int i = 0; i < _neumann_conditions.size(); ++i)
245 const Point3df &p = _neumann_conditions[i];
246 for (i = 0; i < 3; ++i)
247 for (d = -1; d <= 1; d += 2)
251 if (p2[i] < 0 or p2[i] >= dim[i])
continue;
252 if ((*(this->_mask))(p2[0], p2[1], p2[2]) != 0)
254 ima(p[0], p[1], p[2]) =ima(p2[0], p2[1], p2[2]);
267 this->check(maxiter);
275 tmp1 = &imaF; tmp2 = &ima2;
277 for (
int i = 0; i < maxiter; i++)
279 if (verbose) std::cout <<
"+" << std::flush;
280 convolution((*tmp1), (*tmp2));
286 if (verbose) std::cout <<
"Finished" << std::endl;
297 int i, d, x, y, z, t, n;
298 int dx = ima1.
dimX();
299 int dy = ima1.
dimY();
300 int dz = ima1.
dimZ();
301 int dt = ima1.
dimT();
304 for (t = 0; t < dt; t++)
305 for (z = 0; z < dz; z++)
306 for (y = 0; y < dy; y++)
307 for (x = 0; x < dx; x++)
309 std::cout <<
"x,y,z = " << x <<
", " << y <<
", " << z << std::endl;
310 std::cout <<
"mask = " << ((*this->_mask)(x, y, z, t)) << std::endl;
311 if ((*this->_mask)(x, y, z, t) == this->_background or
312 (*this->_mask)(x, y, z, t) == this->_neumann_value)
314 ima2(x, y, z, t) = ima1(x, y, z, t);
320 for (i = 0; i < 3; ++i)
321 for (d = -1; d <= 1; d += 2)
325 if (p2[i] < 0 or p2[i] >= dim[i])
continue;
326 if ((*this->_mask)(p2[0], p2[1], p2[2], t)
327 == this->_neumann_value)
continue;
329 val += ima1(p2[0], p2[1], p2[2], t);
331 val -= n * ima1(x, y, z, t);
332 ima2(x, y, z, t) = ima1(x, y, z, t) + this->_dt * val;
static AimsData< float > laplacian
Make convolution only on a specified mask.
static AimsData< float > init_laplacian(void)
Heat diffusion with a volume of given datasource (Dirichlet conditions)
#define ForEach3d(thing, x, y, z)
virtual void convert(const INP &in, OUTP &out) const
void setConstantSources(const AimsData< T > &, const T &background)
The template class to make convolutions.
void removeConstantSources()
virtual AimsData< T > doSmoothing(const AimsData< T > &ima, int maxiter, bool verbose=false)
void swap(scoped_ptr< T > &x, scoped_ptr< T > &y)
AimsData< T > doit(AimsData< T > &, AimsData< T > &)