NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
polyApprox.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
30 
31 #include <iostream>
32 
33 #include <Eigen/LU>
34 
35 using Eigen::MatrixXd;
36 using Eigen::VectorXd;
37 using Eigen::Vector4d;
38 using Vector10d = Eigen::Matrix<double, 10, 1>;
39 
40 
41 polyApprox::polyApprox(const int _order,
42  const std::vector<std::vector<double>> &coords)
43  : order(_order)//, coords(_coords)
44 {
45  switch (order)
46  {
47  case 1:
48  {
49  A = MatrixXd::Zero(4, 4);
50  b = VectorXd::Zero(4);
51  a.resize(4);
52  break;
53  }
54  case 2:
55  {
56  A = MatrixXd::Zero(10, 10);//.resize(10, 10);
57  b = VectorXd::Zero(10);//resize(10);
58  a.resize(10);
59  break;
60  }
61  default:
62  {
63  std::cerr << "Error: order: " << order << " is not supported"
64  << std::endl;
65  exit(1);
66  }
67  }
68  basis.resize(coords.size());
69  for (int i = 0; i < coords.size(); ++i)
70  {
71  basis[i] = computeBasis(coords[i]);
72  A = A + basis[i] * (basis[i].transpose()); // * basis[i];
73  }
74 }
75 
76 
77 std::unique_ptr<polyApprox>
79  const std::vector<std::vector<double>> &coords)
80 {
81  return std::unique_ptr<polyApprox>(new polyApprox(order, coords));
82 }
83 
84 
85 void polyApprox::computeCoeff(const VectorXd &data)
86 {
87  for (int i = 0; i < basis.size(); ++i)
88  {
89  b = b + basis[i] * data(i); // basis[i].transpose() * data(i);
90  }
91  a = A.partialPivLu().solve(b);
92 }
93 
94 
96 {
97  a.setZero();
98  b.setZero();
99 }
100 
101 
102 double polyApprox::eval(const std::vector<double> &coord) const
103 {
104  VectorXd P = computeBasis(coord);
105  return (P.transpose() * a)(0, 0);
106 }
107 
108 
109 VectorXd polyApprox::computeBasis(const std::vector<double> &coord) const
110 {
111  switch (order)
112  {
113  case 1:
114  {
115  Vector4d basisVec;
116  basisVec(0) = 1;
117  basisVec(1) = coord[0];
118  basisVec(2) = coord[1];
119  basisVec(3) = coord[2];
120  return basisVec;
121  }
122  case 2:
123  {
124  Vector10d basisVec;
125  basisVec(0) = 1;
126  basisVec(1) = coord[0];
127  basisVec(2) = coord[1];
128  basisVec(3) = coord[2];
129  basisVec(4) = coord[0] * coord[0];
130  basisVec(5) = coord[0] * coord[1];
131  basisVec(6) = coord[0] * coord[2];
132  basisVec(7) = coord[1] * coord[1];
133  basisVec(8) = coord[1] * coord[2];
134  basisVec(9) = coord[2] * coord[2];
135  return basisVec;
136  }
137  default:
138  {
139  std::cerr << "Error: order " << order << " is not supported."
140  << std::endl;
141  exit(1);
142  }
143  }
144 }
static std::unique_ptr< polyApprox > CreateUnique(int order, const std::vector< std::vector< double >> &coords)
Definition: polyApprox.C:78
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
double eval(const std::vector< double > &coord) const
Definition: polyApprox.C:102
Eigen::VectorXd a
Definition: polyApprox.H:70
void computeCoeff(const Eigen::VectorXd &data)
Definition: polyApprox.C:85
std::vector< Eigen::VectorXd > basis
Definition: polyApprox.H:64
Eigen::MatrixXd A
Definition: polyApprox.H:66
void resetCoeff()
Definition: polyApprox.C:95
Eigen::VectorXd b
Definition: polyApprox.H:68
polyApprox(int _order, const std::vector< std::vector< double >> &coords)
Definition: polyApprox.C:41
Eigen::Matrix< double, 10, 1 > Vector10d
Definition: polyApprox.C:38
Eigen::VectorXd computeBasis(const std::vector< double > &coord) const
Definition: polyApprox.C:109