9 #ifndef __FILEDAPPROXIMATION_HPP
10 #define __FILEDAPPROXIMATION_HPP
12 using namespace boost::numeric;
25 : mField(m_field), feVolume(m_field), feFace(m_field) {}
31 template <
typename FUNEVAL>
40 std::vector<Vec> &vec_F, FUNEVAL &function_evaluator)
43 A(_A), vecF(vec_F), functionEvaluator(function_evaluator) {}
48 std::vector<VectorDouble>
Nf;
60 if (row_data.getIndices().size() == 0)
62 if (col_data.getIndices().size() == 0)
65 const auto &dof_ptr = row_data.getFieldDofs()[0];
66 int rank = dof_ptr->getNbOfCoeffs();
68 int nb_row_dofs = row_data.getIndices().size() / rank;
69 int nb_col_dofs = col_data.getIndices().size() / rank;
71 NN.resize(nb_row_dofs, nb_col_dofs,
false);
74 unsigned int nb_gauss_pts = row_data.getN().size1();
75 for (
unsigned int gg = 0; gg != nb_gauss_pts; gg++) {
76 double w = getVolume() * getGaussPts()(3, gg);
78 cblas_dger(CblasRowMajor, nb_row_dofs, nb_col_dofs,
w,
79 &row_data.getN()(gg, 0), 1, &col_data.getN()(gg, 0), 1,
80 &*NN.data().begin(), nb_col_dofs);
83 if ((row_type != col_type) || (row_side != col_side)) {
84 transNN.resize(nb_col_dofs, nb_row_dofs,
false);
85 ublas::noalias(transNN) = trans(NN);
88 double *data = &*NN.data().begin();
89 double *trans_data = &*transNN.data().begin();
91 row_indices.resize(nb_row_dofs);
92 col_indices.resize(nb_col_dofs);
94 for (
int rr = 0; rr < rank; rr++) {
96 if ((row_data.getIndices().size() % rank) != 0) {
98 "data inconsistency");
101 if ((col_data.getIndices().size() % rank) != 0) {
103 "data inconsistency");
106 unsigned int nb_rows;
107 unsigned int nb_cols;
113 ublas::noalias(row_indices) = ublas::vector_slice<VectorInt>(
114 row_data.getIndices(),
115 ublas::slice(rr, rank, row_data.getIndices().size() / rank));
116 ublas::noalias(col_indices) = ublas::vector_slice<VectorInt>(
117 col_data.getIndices(),
118 ublas::slice(rr, rank, col_data.getIndices().size() / rank));
120 nb_rows = row_indices.size();
121 nb_cols = col_indices.size();
122 rows = &*row_indices.data().begin();
123 cols = &*col_indices.data().begin();
127 nb_rows = row_data.getIndices().size();
128 nb_cols = col_data.getIndices().size();
129 rows = &*row_data.getIndices().data().begin();
130 cols = &*col_data.getIndices().data().begin();
133 if (nb_rows != NN.size1()) {
135 "data inconsistency");
137 if (nb_cols != NN.size2()) {
139 "data inconsistency");
143 if ((row_type != col_type) || (row_side != col_side)) {
144 if (nb_rows != transNN.size2()) {
146 "data inconsistency");
148 if (nb_cols != transNN.size1()) {
150 "data inconsistency");
166 if (data.getIndices().size() == 0)
171 const auto &dof_ptr = data.getFieldDofs()[0];
172 unsigned int rank = dof_ptr->getNbOfCoeffs();
174 int nb_row_dofs = data.getIndices().size() / rank;
176 if (getCoordsAtGaussPts().size1() != data.getN().size1()) {
178 "data inconsistency");
180 if (getCoordsAtGaussPts().size2() != 3) {
182 "data inconsistency");
186 unsigned int nb_gauss_pts = data.getN().size1();
187 for (
unsigned int gg = 0; gg != nb_gauss_pts; gg++) {
189 const double w = getVolume() * getGaussPts()(3, gg);
191 const double x = getCoordsAtGaussPts()(gg, 0);
192 const double y = getCoordsAtGaussPts()(gg, 1);
193 const double z = getCoordsAtGaussPts()(gg, 2);
195 std::vector<VectorDouble> fun_val;
197 fun_val = functionEvaluator(x, y, z);
199 if (fun_val.size() != vecF.size()) {
201 "data inconsistency");
204 Nf.resize(fun_val.size());
205 for (
unsigned int lhs = 0; lhs != fun_val.size(); lhs++) {
208 Nf[lhs].resize(data.getIndices().size());
212 if (fun_val[lhs].size() != rank) {
214 "data inconsistency");
217 for (
unsigned int rr = 0; rr != rank; rr++) {
218 cblas_daxpy(nb_row_dofs,
w * (fun_val[lhs])[rr],
219 &data.getN()(gg, 0), 1, &(Nf[lhs])[rr], rank);
224 for (
unsigned int lhs = 0; lhs != vecF.size(); lhs++) {
227 &data.getIndices()[0], &(Nf[lhs])[0], ADD_VALUES);
238 template <
typename FUNEVAL>
247 FUNEVAL &function_evaluator)
250 A(_A), vecF(vec_F), functionEvaluator(function_evaluator) {}
255 std::vector<VectorDouble>
Nf;
267 if (row_data.getIndices().size() == 0)
269 if (col_data.getIndices().size() == 0)
272 const auto &dof_ptr = row_data.getFieldDofs()[0];
273 int rank = dof_ptr->getNbOfCoeffs();
274 int nb_row_dofs = row_data.getIndices().size() / rank;
275 int nb_col_dofs = col_data.getIndices().size() / rank;
276 NN.resize(nb_row_dofs, nb_col_dofs,
false);
278 unsigned int nb_gauss_pts = row_data.getN().size1();
279 for (
unsigned int gg = 0; gg != nb_gauss_pts; gg++) {
280 double w = getGaussPts()(2, gg);
281 if (getNormalsAtGaussPts().size1()) {
282 w *= 0.5 * cblas_dnrm2(3, &getNormalsAtGaussPts()(gg, 0), 1);
287 cblas_dger(CblasRowMajor, nb_row_dofs, nb_col_dofs,
w,
288 &row_data.getN()(gg, 0), 1, &col_data.getN()(gg, 0), 1,
289 &*NN.data().begin(), nb_col_dofs);
292 if ((row_type != col_type) || (row_side != col_side)) {
293 transNN.resize(nb_col_dofs, nb_row_dofs,
false);
294 ublas::noalias(transNN) = trans(NN);
297 double *data = &*NN.data().begin();
298 double *trans_data = &*transNN.data().begin();
300 row_indices.resize(nb_row_dofs);
301 col_indices.resize(nb_col_dofs);
302 for (
int rr = 0; rr < rank; rr++) {
303 if ((row_data.getIndices().size() % rank) != 0) {
305 "data inconsistency");
307 if ((col_data.getIndices().size() % rank) != 0) {
309 "data inconsistency");
311 unsigned int nb_rows;
312 unsigned int nb_cols;
316 ublas::noalias(row_indices) = ublas::vector_slice<VectorInt>(
317 row_data.getIndices(),
318 ublas::slice(rr, rank, row_data.getIndices().size() / rank));
319 ublas::noalias(col_indices) = ublas::vector_slice<VectorInt>(
320 col_data.getIndices(),
321 ublas::slice(rr, rank, col_data.getIndices().size() / rank));
322 nb_rows = row_indices.size();
323 nb_cols = col_indices.size();
324 rows = &*row_indices.data().begin();
325 cols = &*col_indices.data().begin();
327 nb_rows = row_data.getIndices().size();
328 nb_cols = col_data.getIndices().size();
329 rows = &*row_data.getIndices().data().begin();
330 cols = &*col_data.getIndices().data().begin();
332 if (nb_rows != NN.size1()) {
334 "data inconsistency");
336 if (nb_cols != NN.size2()) {
338 "data inconsistency");
341 if ((row_type != col_type) || (row_side != col_side)) {
342 if (nb_rows != transNN.size2()) {
344 "data inconsistency");
346 if (nb_cols != transNN.size1()) {
348 "data inconsistency");
363 if (data.getIndices().size() == 0)
366 const auto &dof_ptr = data.getFieldDofs()[0];
367 unsigned int rank = dof_ptr->getNbOfCoeffs();
369 int nb_row_dofs = data.getIndices().size() / rank;
371 if (getCoordsAtGaussPts().size1() != data.getN().size1()) {
373 "data inconsistency");
375 if (getCoordsAtGaussPts().size2() != 3) {
377 "data inconsistency");
387 unsigned int nb_gauss_pts = data.getN().size1();
388 for (
unsigned int gg = 0; gg != nb_gauss_pts; gg++) {
389 double w = getGaussPts()(2, gg);
390 w *= 0.5 * cblas_dnrm2(3, &getNormalsAtGaussPts()(gg, 0), 1);
393 const double x = getCoordsAtGaussPts()(gg, 0);
394 const double y = getCoordsAtGaussPts()(gg, 1);
395 const double z = getCoordsAtGaussPts()(gg, 2);
397 if (getNormalsAtGaussPts().size1()) {
398 noalias(normal) = getNormalsAtGaussPts(gg);
399 for (
int dd = 0;
dd < 3;
dd++) {
400 tangent1[
dd] = getTangent1AtGaussPts()(gg,
dd);
401 tangent2[
dd] = getTangent2AtGaussPts()(gg,
dd);
404 noalias(normal) = getNormal();
407 std::vector<VectorDouble> fun_val;
408 EntityHandle ent = getFEMethod()->numeredEntFiniteElementPtr->getEnt();
409 fun_val = functionEvaluator(ent, x, y, z, normal, tangent1, tangent2);
410 if (fun_val.size() != vecF.size()) {
412 "data inconsistency");
415 Nf.resize(fun_val.size());
416 for (
unsigned int lhs = 0; lhs != fun_val.size(); lhs++) {
418 Nf[lhs].resize(data.getIndices().size());
421 if (fun_val[lhs].size() != rank) {
423 "data inconsistency");
425 for (
unsigned int rr = 0; rr != rank; rr++) {
426 cblas_daxpy(nb_row_dofs,
w * (fun_val[lhs])[rr],
427 &data.getN()(gg, 0), 1, &(Nf[lhs])[rr], rank);
432 for (
unsigned int lhs = 0; lhs != vecF.size(); lhs++) {
435 &data.getIndices()[0], &(Nf[lhs])[0], ADD_VALUES);
444 template <
typename FUNEVAL>
446 std::vector<Vec> &vec_F,
447 FUNEVAL &function_evaluator) {
450 feVolume.getOpPtrVector().push_back(
462 template <
typename FUNEVAL>
464 std::vector<Vec> &vec_F,
465 FUNEVAL &function_evaluator) {
480 template <
typename FUNEVAL>
482 const std::string &fe_name,
484 std::vector<Vec> &vec_F,
485 FUNEVAL &function_evaluator) {
495 CHKERR MatAssemblyBegin(
A, MAT_FLUSH_ASSEMBLY);
496 CHKERR MatAssemblyEnd(
A, MAT_FLUSH_ASSEMBLY);
498 for (
unsigned int lhs = 0; lhs < vec_F.size(); lhs++) {
499 CHKERR VecAssemblyBegin(vec_F[lhs]);
500 CHKERR VecAssemblyEnd(vec_F[lhs]);
506 #endif //__FILEDAPPROXIMATION_HPP