1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkZeroFluxNeumannBoundaryCondition_h
19 #define itkZeroFluxNeumannBoundaryCondition_h
20 #include "itkImageBoundaryCondition.h"
21 
22 namespace itk
23 {
24 /** \class ZeroFluxNeumannBoundaryCondition
25  * \brief
26  * A function object that determines a neighborhood of values at an
27  * image boundary according to a Neumann boundary condition where first,
28  * upwind derivatives on the boundary are zero.  This is a useful condition
29  * in solving some classes of differential equations.
30  *
31  * For example, invoking this function object on a 7x5 iterator that masks
32  * a region at an image corner (iterator is centered on the 2):
33    \code
34                  * * * * * * *
35                  * * * * * * *
36                  * * 1 2 3 4 5  (where * denotes pixels that lie
37                  * * 3 3 5 5 6          outside of the image boundary)
38                  * * 4 4 6 7 8
39    \endcode
40  * returns the following neighborhood of values:
41    \code
42                  1 1 1 2 3 4 5
43                  1 1 1 2 3 4 5
44                  1 1 1 2 3 4 5
45                  3 3 3 3 5 5 6   (note the corner values)
46                  4 4 4 4 6 7 8
47    \endcode
48  * The input to this function object is a neighborhood iterator.  This boundary
49  * condition object is designed to be given as a template argument to a
50  * NeighborhoodIterator or any of the NeighborhoodIterator
51  * subclasses.
52  *
53  * \ingroup DataRepresentation
54  * \ingroup ImageObjects
55  * \ingroup ITKCommon
56  */
57 template< typename TInputImage, typename TOutputImage = TInputImage >
58 class ITK_TEMPLATE_EXPORT ZeroFluxNeumannBoundaryCondition:
59     public ImageBoundaryCondition< TInputImage, TOutputImage >
60 {
61 public:
62   /** Standard class type aliases. */
63   using Self = ZeroFluxNeumannBoundaryCondition;
64   using Superclass = ImageBoundaryCondition< TInputImage, TOutputImage >;
65 
66   /** Extract information from the image type. */
67   using PixelType = typename Superclass::PixelType;
68   using PixelPointerType = typename Superclass::PixelPointerType;
69   using OutputPixelType = typename Superclass::OutputPixelType;
70   using RegionType = typename Superclass::RegionType;
71   using IndexType = typename Superclass::IndexType;
72   using SizeType = typename Superclass::SizeType;
73   using OffsetType = typename Superclass::OffsetType;
74   using NeighborhoodType = typename Superclass::NeighborhoodType;
75 
76   using NeighborhoodAccessorFunctorType = typename Superclass::NeighborhoodAccessorFunctorType;
77 
78   /** Extract information from the image type. */
79   static constexpr unsigned int ImageDimension = Superclass::ImageDimension;
80 
81   /** Default constructor. */
82   ZeroFluxNeumannBoundaryCondition() = default;
83 
84   /** Runtime information support. */
GetNameOfClass()85   const char * GetNameOfClass() const override
86   {
87     return "itkZeroFluxNeumannBoundaryCondition";
88   }
89 
90   /** Computes and returns a neighborhood of appropriate values from
91    * neighborhood iterator data.. */
92   OutputPixelType operator()(const OffsetType & point_index,
93                                      const OffsetType & boundary_offset,
94                                      const NeighborhoodType *data) const override;
95 
96   /** Computes and returns the appropriate pixel value from
97    * neighborhood iterator data, using the functor. */
98   OutputPixelType operator()(
99     const OffsetType & point_index,
100     const OffsetType & boundary_offset,
101     const NeighborhoodType *data,
102     const NeighborhoodAccessorFunctorType & neighborhoodAccessorFunctor) const override;
103 
104   /** Determines the necessary input region for the output region.
105    * For this boundary condition, only the intersection of the largest
106    * possible image region and the output requested region is
107    * needed. If the intersection is empty, then a one-pixel layer of
108    * the image from the side closest to the output requested region is needed.
109    *
110    * \param inputLargestPossibleRegion Largest possible region of the input image.
111    * \param outputRequestedRegion The output requested region.
112    * \return The necessary input region required to determine the
113    * pixel values in the outputRequestedRegion.
114    */
115   RegionType GetInputRequestedRegion( const RegionType & inputLargestPossibleRegion,
116                                               const RegionType & outputRequestedRegion ) const override;
117 
118   /** Returns a value for a given pixel at an index. If the index is inside the
119    * bounds of the input image, then the pixel value is obtained from
120    * the input image. Otherwise, the nearest pixel value is returned.
121    *
122    * \param index The index of the desired pixel.
123    * \param image The image from which pixel values should be determined.
124    */
125   OutputPixelType GetPixel( const IndexType & index, const TInputImage * image ) const override;
126 
127 };
128 } // end namespace itk
129 
130 #ifndef ITK_MANUAL_INSTANTIATION
131 #include "itkZeroFluxNeumannBoundaryCondition.hxx"
132 #endif
133 
134 /*
135 #ifndef ITK_MANUAL_INSTANTIATION
136 #include "itkZeroFluxNeumannBoundaryCondition.hxx"
137 #endif
138 */
139 
140 #endif
141