Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////////
2 : // Copyright 2019 Lakshman Anumolu, Raunak Bardia.
3 : //
4 : // Redistribution and use in source and binary forms, with or without
5 : // modification, are permitted provided that the following conditions are
6 : // met:
7 : //
8 : // 1. Redistributions of source code must retain the above copyright notice,
9 : // this list of conditions and the following disclaimer.
10 : //
11 : // 2. Redistributions in binary form must reproduce the above copyright notice,
12 : // this list of conditions and the following disclaimer in the documentation
13 : // and/or other materials provided with the distribution.
14 : //
15 : // 3. Neither the name of the copyright holder nor the names of its contributors
16 : // may be used to endorse or promote products derived from this software without
17 : // specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 : ///////////////////////////////////////////////////////////////////////////////
31 :
32 : #include "gals/cpu/interpolation/hermite.h"
33 :
34 : #include <math.h>
35 :
36 : template <typename T>
37 705 : GALS::CPU::InterpolatedFields<GALS::CPU::Vec3<T>> GALS::INTERPOLATION::Hermite<T, GALS::CPU::Grid<T, 2>>::interpolate(
38 : const GALS::CPU::Grid<typename GALS::CPU::Grid<T, 2>::value_type, GALS::CPU::Grid<T, 2>::dim> &grid,
39 : const typename GALS::CPU::Grid<T, 2>::position_type &x_interp,
40 : const GALS::CPU::Levelset<GALS::CPU::Grid<T, 2>, T> &levelset, const bool use_gradient_limiting)
41 : {
42 705 : GALS::CPU::InterpolatedFields<GALS::CPU::Vec3<T>> hermite_fields;
43 :
44 : using T_GRID = GALS::CPU::Grid<T, 2>;
45 : const int dim = T_GRID::dim;
46 : const int axis_x = 0, axis_y = 1;
47 : const auto &axis_vectors = GALS::CPU::Grid<typename T_GRID::value_type, T_GRID::dim>::axis_vectors;
48 1410 : const GALS::CPU::Vec3<int> base_i_j = grid.baseNodeId(x_interp);
49 1410 : const GALS::CPU::Vec3<int> base_ip1_j = GALS::CPU::Vec3<int>(base_i_j[0] + axis_vectors(0, 0), base_i_j[1], 0);
50 1410 : const GALS::CPU::Vec3<int> base_i_jp1 = GALS::CPU::Vec3<int>(base_i_j[0], base_i_j[1] + axis_vectors(1, 1), 0);
51 2115 : const GALS::CPU::Vec3<int> base_ip1_jp1 =
52 1410 : GALS::CPU::Vec3<int>(base_i_j[0] + axis_vectors(0, 0), base_i_j[1] + axis_vectors(1, 1), 0);
53 :
54 1410 : const typename T_GRID::position_type x_base = grid(base_i_j);
55 705 : const auto &dx = grid.dX();
56 705 : const auto &one_over_dx = grid.oneOverDX();
57 :
58 1410 : GALS::CPU::Vec3<T> eta = (x_interp - x_base) * one_over_dx;
59 :
60 2820 : const ControlPoints<T> &control_points_bottom = GALS::INTERPOLATION::get_control_points(
61 1410 : levelset.phiPrev()(base_i_j), levelset.psiPrev()(base_i_j)[axis_x], levelset.phiPrev()(base_ip1_j),
62 2115 : levelset.psiPrev()(base_ip1_j)[axis_x], dx[axis_x], use_gradient_limiting);
63 2115 : const ControlPoints<T> &control_points_top = GALS::INTERPOLATION::get_control_points(
64 1410 : levelset.phiPrev()(base_i_jp1), levelset.psiPrev()(base_i_jp1)[axis_x], levelset.phiPrev()(base_ip1_jp1),
65 1410 : levelset.psiPrev()(base_ip1_jp1)[axis_x], dx[axis_x], use_gradient_limiting);
66 2115 : const ControlPoints<T> &control_points_left = GALS::INTERPOLATION::get_control_points(
67 1410 : levelset.phiPrev()(base_i_j), levelset.psiPrev()(base_i_j)[axis_y], levelset.phiPrev()(base_i_jp1),
68 1410 : levelset.psiPrev()(base_i_jp1)[axis_y], dx[axis_y], use_gradient_limiting);
69 2115 : const ControlPoints<T> &control_points_right = GALS::INTERPOLATION::get_control_points(
70 1410 : levelset.phiPrev()(base_ip1_j), levelset.psiPrev()(base_ip1_j)[axis_y], levelset.phiPrev()(base_ip1_jp1),
71 1410 : levelset.psiPrev()(base_ip1_jp1)[axis_y], dx[axis_y], use_gradient_limiting);
72 :
73 705 : T c_1 =
74 2115 : levelset.psiPrev()(base_i_j)[axis_y] + dx[axis_x] * one_third * levelset.phiMixedDerivativesPrev()(base_i_j)[0];
75 2115 : T c_2 = levelset.psiPrev()(base_ip1_j)[axis_x] +
76 1410 : dx[axis_y] * one_third * levelset.phiMixedDerivativesPrev()(base_ip1_j)[0];
77 2115 : T c_2_prime = levelset.psiPrev()(base_ip1_jp1)[axis_x] -
78 1410 : dx[axis_y] * one_third * levelset.phiMixedDerivativesPrev()(base_ip1_jp1)[0];
79 2115 : T c_3 = levelset.psiPrev()(base_i_jp1)[axis_y] +
80 1410 : dx[axis_x] * one_third * levelset.phiMixedDerivativesPrev()(base_i_jp1)[0];
81 :
82 3525 : T bx[] = {B0(eta[0]), B1(eta[0]), B2(eta[0]), B3(eta[0])};
83 2820 : T bx_prime[] = {B0_Prime(eta[0]), B1_Prime(eta[0]), B2_Prime(eta[0]), B3_Prime(eta[0])};
84 3525 : T by[] = {B0(eta[1]), B1(eta[1]), B2(eta[1]), B3(eta[1])};
85 3525 : T by_prime[] = {B0_Prime(eta[1]), B1_Prime(eta[1]), B2_Prime(eta[1]), B3_Prime(eta[1])};
86 :
87 8460 : T control_points_all[] = {control_points_left.c_30,
88 705 : control_points_left.c_21,
89 705 : control_points_left.c_12,
90 705 : control_points_left.c_03,
91 : control_points_bottom.c_21,
92 705 : control_points_bottom.c_21 + dx[axis_y] * one_third * c_1,
93 705 : control_points_top.c_21 - dx[axis_y] * one_third * c_3,
94 : control_points_top.c_21,
95 705 : control_points_bottom.c_12,
96 705 : control_points_right.c_21 - dx[axis_x] * one_third * c_2,
97 705 : control_points_right.c_12 - dx[axis_x] * one_third * c_2_prime,
98 705 : control_points_top.c_12,
99 705 : control_points_right.c_30,
100 : control_points_right.c_21,
101 : control_points_right.c_12,
102 705 : control_points_right.c_03};
103 :
104 6345 : for (int i = 0, k = 0; i < 4; ++i)
105 25380 : for (int j = 0; j < 4; ++j) {
106 11280 : hermite_fields.phi_interpolated += bx[i] * by[j] * control_points_all[k];
107 11280 : ++k;
108 : }
109 :
110 6345 : for (int i = 0, k = 0; i < 4; ++i)
111 25380 : for (int j = 0; j < 4; ++j) {
112 11280 : hermite_fields.psi_interpolated[axis_x] += bx_prime[i] * by[j] * control_points_all[k];
113 11280 : ++k;
114 : }
115 705 : hermite_fields.psi_interpolated[axis_x] *= one_over_dx[axis_x];
116 :
117 6345 : for (int i = 0, k = 0; i < 4; ++i)
118 25380 : for (int j = 0; j < 4; ++j) {
119 11280 : hermite_fields.psi_interpolated[axis_y] += bx[i] * by_prime[j] * control_points_all[k];
120 11280 : ++k;
121 : }
122 705 : hermite_fields.psi_interpolated[axis_y] *= one_over_dx[axis_y];
123 :
124 705 : return hermite_fields;
125 : }
126 :
127 : template <typename T>
128 6 : void GALS::INTERPOLATION::Hermite<T, GALS::CPU::Grid<T, 2>>::compute(
129 : const GALS::CPU::Array<GALS::CPU::Grid<T, 2>, typename GALS::CPU::Grid<T, 2>::position_type> &x_interp,
130 : GALS::CPU::Levelset<GALS::CPU::Grid<T, 2>, T> &levelset)
131 : {
132 : typedef GALS::CPU::Grid<T, 2> T_GRID;
133 :
134 12 : const GALS::CPU::Vec3<int> num_cells_interp = x_interp.numCells();
135 6 : const T_GRID &grid = levelset.grid();
136 12 : const GALS::CPU::Vec3<typename T_GRID::value_type> dx = grid.dX();
137 : const auto &axis_vectors = GALS::CPU::Grid<typename T_GRID::value_type, T_GRID::dim>::axis_vectors;
138 :
139 136 : for (int i = 0; i < num_cells_interp[0]; ++i)
140 1475 : for (int j = 0; j < num_cells_interp[1]; ++j)
141 2115 : for (int k = 0; k < num_cells_interp[2]; ++k) {
142 705 : const auto &hermite_fields = this->interpolate(grid, x_interp(i, j, k), levelset);
143 :
144 705 : levelset.phiInterpPrev()(i, j, k) = hermite_fields.phi_interpolated;
145 705 : levelset.psiInterpPrev()(i, j, k) = hermite_fields.psi_interpolated;
146 : }
147 6 : }
148 :
149 3 : template class GALS::INTERPOLATION::Hermite<double, GALS::CPU::Grid<double, 2>>;
|