15 for (
int col = 0; col < N; col++)
18 double maxval = fabs(A[col * N + col]);
19 for (
int r = col + 1;
r < N;
r++)
21 if (fabs(A[
r * N + col]) > maxval)
23 maxval = fabs(A[
r * N + col]);
29 for (
int j = 0; j < N; j++)
30 std::swap(A[col * N + j], A[piv * N + j]);
31 std::swap(b[col], b[piv]);
33 const double pivval = A[col * N + col];
34 assert(fabs(pivval) > 1.0e-14 &&
"Singular system in solveSmallLinearSystem");
35 const double invPiv = 1.0 / pivval;
36 for (
int j = col; j < N; j++)
37 A[col * N + j] *= invPiv;
39 for (
int r = 0;
r < N;
r++)
43 const double factor = A[
r * N + col];
46 for (
int j = col; j < N; j++)
47 A[
r * N + j] -= factor * A[col * N + j];
48 b[
r] -= factor * b[col];
52 for (
int i = 0; i < N; i++)
77 const std::array<double, 3> &nodal_values)
80 const double tx = Jit00 * nx + Jit10 * ny;
81 const double ty = Jit01 * nx + Jit11 * ny;
85 1., 0., 0., 0., 0., 0.,
86 0., 0., 0., 1., 1., 0.,
87 0., 0., 0., 1., 0., 1.,
88 -1., -x0, 0., 1., x0, 0.,
89 -1., 0., -y0, 1., 0., y0,
90 0., -ma * tx, -ma * ty, 0., mb * tx, mb * ty};
91 double rhs[6] = {nodal_values[0], nodal_values[1], nodal_values[2], 0.0, 0.0, jf};
96 std::array<double, 6> out;
97 for (
int i = 0; i < 6; ++i)
100 if (std::isnan(out[i]) || std::isinf(out[i]))
101 throw std::runtime_error(
"solve_ifem_basis_coefficients (P1) returned NaN or Inf");
129 const std::array<double, 6> &nodal_values)
132 assert(!((x0 == 0.0 && y0 == 0.0) || (x0 == 1.0 && y0 == 0.0) || (x0 == 0.0 && y0 == 1.0)) &&
133 "Interface passes through a triangle vertex");
134 assert(!(x0 > 0.5 && y0 <= 0.5) &&
135 "Invalid interface location for quadratic basis functions (should have been flipped upstream)");
137 const double tx = Jit00 * nx + Jit10 * ny;
138 const double ty = Jit01 * nx + Jit11 * ny;
139 const double v1 = nodal_values[0], v2 = nodal_values[1], v3 = nodal_values[2],
140 v4 = nodal_values[3], v5 = nodal_values[4], v6 = nodal_values[5];
143 double A[144] = {0.0};
144 double rhs[12] = {0.0};
153 A[1 * 12 + 10] = 1.0;
159 A[2 * 12 + 11] = 1.0;
167 A[3 * 12 + 10] = 0.25;
173 A[3 * 12 + 4] = 0.25;
181 A[4 * 12 + 9] = 0.25;
182 A[4 * 12 + 10] = 0.25;
183 A[4 * 12 + 11] = 0.25;
191 A[5 * 12 + 11] = 0.25;
197 A[5 * 12 + 5] = 0.25;
202 A[6 * 12 + 0] = -1.0;
204 A[6 * 12 + 4] = -x0 * x0;
207 A[6 * 12 + 10] = x0 * x0;
210 A[7 * 12 + 0] = -1.0;
212 A[7 * 12 + 5] = -y0 * y0;
215 A[7 * 12 + 11] = y0 * y0;
218 A[8 * 12 + 0] = -1.0;
219 A[8 * 12 + 1] = -0.5 * x0;
220 A[8 * 12 + 2] = -0.5 * y0;
221 A[8 * 12 + 3] = -0.25 * x0 * y0;
222 A[8 * 12 + 4] = -0.25 * x0 * x0;
223 A[8 * 12 + 5] = -0.25 * y0 * y0;
225 A[8 * 12 + 7] = 0.5 * x0;
226 A[8 * 12 + 8] = 0.5 * y0;
227 A[8 * 12 + 9] = 0.25 * x0 * y0;
228 A[8 * 12 + 10] = 0.25 * x0 * x0;
229 A[8 * 12 + 11] = 0.25 * y0 * y0;
232 A[9 * 12 + 1] = -ma * tx;
233 A[9 * 12 + 2] = -ma * ty;
234 A[9 * 12 + 3] = -ma * x0 * ty;
235 A[9 * 12 + 4] = -ma * 2.0 * x0 * tx;
236 A[9 * 12 + 7] = mb * tx;
237 A[9 * 12 + 8] = mb * ty;
238 A[9 * 12 + 9] = mb * x0 * ty;
239 A[9 * 12 + 10] = mb * 2.0 * x0 * tx;
243 A[10 * 12 + 1] = -ma * tx;
244 A[10 * 12 + 2] = -ma * ty;
245 A[10 * 12 + 3] = -ma * y0 * tx;
246 A[10 * 12 + 5] = -ma * 2.0 * y0 * ty;
247 A[10 * 12 + 7] = mb * tx;
248 A[10 * 12 + 8] = mb * ty;
249 A[10 * 12 + 9] = mb * y0 * tx;
250 A[10 * 12 + 11] = mb * 2.0 * y0 * ty;
256 A[11 * 12 + 3] = -ma * 2.0 * tx * ty;
257 A[11 * 12 + 4] = -ma * 2.0 * tx * tx;
258 A[11 * 12 + 5] = -ma * 2.0 * ty * ty;
259 A[11 * 12 + 9] = mb * 2.0 * tx * ty;
260 A[11 * 12 + 10] = mb * 2.0 * tx * tx;
261 A[11 * 12 + 11] = mb * 2.0 * ty * ty;
266 std::array<double, 12> out;
267 for (
int i = 0; i < 12; ++i)
270 if (std::isnan(out[i]) || std::isinf(out[i]))
271 throw std::runtime_error(
"solve_ifem_basis_coefficients (P2) returned NaN or Inf");
std::array< double, 6 > solve_ifem_basis_coefficients(int basis_order, double x0, double y0, double nx, double ny, double ma, double mb, double jf, double Jit00, double Jit01, double Jit10, double Jit11, const std::array< double, 3 > &nodal_values)