PolyFEM
Loading...
Searching...
No Matches
KernelProblem.cpp
Go to the documentation of this file.
1#include "KernelProblem.hpp"
3
4#include <iostream>
5#include <fstream>
6
7namespace polyfem
8{
9 namespace problem
10 {
11 KernelProblem::KernelProblem(const std::string &name, const assembler::Assembler &assembler)
12 : ProblemWithSolution(name), assembler_(assembler)
13 {
14 }
15
16 VectorNd KernelProblem::eval_fun(const VectorNd &pt, const double t) const
17 {
18 AutodiffGradPt a_pt(pt.size());
19
21 for (long i = 0; i < pt.size(); ++i)
22 a_pt(i) = AutodiffScalarGrad(i, pt(i));
23
24 const auto eval = eval_fun(a_pt, t);
25
26 VectorNd res(eval.size());
27
28 for (long i = 0; i < eval.size(); ++i)
29 res(i) = eval(i).getValue();
30
31 return res;
32 }
33
34 AutodiffGradPt KernelProblem::eval_fun(const AutodiffGradPt &pt, const double tt) const
35 {
36 AutodiffGradPt res(is_scalar() ? 1 : pt.size());
37 for (long i = 0; i < res.size(); ++i)
38 res(i) = AutodiffScalarGrad(0);
39
40 auto kw = kernel_weights_;
41
42 const Eigen::VectorXd t = Eigen::VectorXd::LinSpaced(n_kernels_, 0, 1);
43
44 if (pt.size() == 2)
45 {
46 if (kw.size() == 0)
47 {
48 kw.resize(t.size() * 4);
49 kw.setOnes();
50 }
51
52 assert(kw.size() == t.size() * 4);
53
54 for (long i = 0; i < t.size(); ++i)
55 {
56 const auto dx = pt(0) - (0 - kernel_distance_);
57 const auto dy = pt(1) - t(i);
58 AutodiffGradPt rvect(2);
59 rvect << dx, dy;
60 if (kw(i) > 0)
61 res += assembler_.kernel(2, rvect, sqrt(dx * dx + dy * dy)) * polyfem::AutodiffScalarGrad(kw(i));
62 }
63
64 for (long i = 0; i < t.size(); ++i)
65 {
66 const auto dx = pt(0) - (1 + kernel_distance_);
67 const auto dy = pt(1) - t(i);
68 AutodiffGradPt rvect(2);
69 rvect << dx, dy;
70 if (kw(t.size() + i) > 0)
71 res += assembler_.kernel(2, rvect, sqrt(dx * dx + dy * dy)) * polyfem::AutodiffScalarGrad(kw(t.size() + i));
72 }
73
74 for (long i = 0; i < t.size(); ++i)
75 {
76 const auto dx = pt(0) - t(i);
77 const auto dy = pt(1) - (0 - kernel_distance_);
78 AutodiffGradPt rvect(2);
79 rvect << dx, dy;
80 if (kw(t.size() * 2 + i) > 0)
81 res += assembler_.kernel(2, rvect, sqrt(dx * dx + dy * dy)) * polyfem::AutodiffScalarGrad(kw(t.size() * 2 + i));
82 }
83
84 for (long i = 0; i < t.size(); ++i)
85 {
86 const auto dx = pt(0) - t(i);
87 const auto dy = pt(1) - (1 + kernel_distance_);
88 AutodiffGradPt rvect(2);
89 rvect << dx, dy;
90 if (kw(t.size() * 3 + i) > 0)
91 res += assembler_.kernel(2, rvect, sqrt(dx * dx + dy * dy)) * polyfem::AutodiffScalarGrad(kw(t.size() * 3 + i));
92 }
93 }
94 else if (pt.size() == 3)
95 {
96 if (kw.size() == 0)
97 {
98 kw.resize(t.size() * t.size() * 6);
99 kw.setOnes();
100 }
101
102 assert(kw.size() == t.size() * t.size() * 6);
103
105 for (long i = 0; i < t.size(); ++i)
106 {
107 for (long j = 0; j < t.size(); ++j)
108 {
109 const auto dx = pt(0) - (0 - kernel_distance_);
110 const auto dy = pt(1) - t(i);
111 const auto dz = pt(2) - t(j);
112 AutodiffGradPt rvect(3);
113 rvect << dx, dy, dz;
114 if (kw(i * t.size() + j) > 0)
115 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(i * t.size() + j));
116 }
117 }
118
119 for (long i = 0; i < t.size(); ++i)
120 {
121 for (long j = 0; j < t.size(); ++j)
122 {
123 const auto dx = pt(0) - (1 + kernel_distance_);
124 const auto dy = pt(1) - t(i);
125 const auto dz = pt(2) - t(j);
126 AutodiffGradPt rvect(3);
127 rvect << dx, dy, dz;
128 if (kw(t.size() * t.size() + i * t.size() + j) > 0)
129 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(t.size() * t.size() + i * t.size() + j));
130 }
131 }
132
134 for (long i = 0; i < t.size(); ++i)
135 {
136 for (long j = 0; j < t.size(); ++j)
137 {
138 const auto dx = pt(0) - t(i);
139 const auto dy = pt(1) - (0 - kernel_distance_);
140 const auto dz = pt(2) - t(j);
141 AutodiffGradPt rvect(3);
142 rvect << dx, dy, dz;
143 if (kw(t.size() * t.size() * 2 + i * t.size() + j) > 0)
144 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(t.size() * t.size() * 2 + i * t.size() + j));
145 }
146 }
147
148 for (long i = 0; i < t.size(); ++i)
149 {
150 for (long j = 0; j < t.size(); ++j)
151 {
152 const auto dx = pt(0) - t(i);
153 const auto dy = pt(1) - (1 + kernel_distance_);
154 const auto dz = pt(2) - t(j);
155 AutodiffGradPt rvect(3);
156 rvect << dx, dy, dz;
157 if (kw(t.size() * t.size() * 3 + i * t.size() + j) > 0)
158 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(t.size() * t.size() * 3 + i * t.size() + j));
159 }
160 }
161
163 for (long i = 0; i < t.size(); ++i)
164 {
165 for (long j = 0; j < t.size(); ++j)
166 {
167 const auto dx = pt(0) - t(i);
168 const auto dy = pt(1) - t(j);
169 const auto dz = pt(2) - (0 - kernel_distance_);
170 AutodiffGradPt rvect(3);
171 rvect << dx, dy, dz;
172 if (kw(t.size() * t.size() * 4 + i * t.size() + j) > 0)
173 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(t.size() * t.size() * 4 + i * t.size() + j));
174 ;
175 }
176 }
177
178 for (long i = 0; i < t.size(); ++i)
179 {
180 for (long j = 0; j < t.size(); ++j)
181 {
182 const auto dx = pt(0) - t(i);
183 const auto dy = pt(1) - t(j);
184 const auto dz = pt(2) - (1 + kernel_distance_);
185 AutodiffGradPt rvect(3);
186 rvect << dx, dy, dz;
187 if (kw(t.size() * t.size() * 5 + i * t.size() + j) > 0)
188 res += assembler_.kernel(3, rvect, sqrt(dx * dx + dy * dy + dz * dz)) * polyfem::AutodiffScalarGrad(kw(t.size() * t.size() * 5 + i * t.size() + j));
189 ;
190 }
191 }
192 }
193 else
194 {
195 assert(false);
196 }
197
198 res = res * AutodiffScalarGrad(tt);
199
200 return res;
201 }
202
203 void KernelProblem::rhs(const assembler::Assembler &assembler, const Eigen::MatrixXd &pts, const double t, Eigen::MatrixXd &val) const
204 {
205 const int size = size_for(pts);
206 val.resize(pts.rows(), size);
207 val.setZero();
208 }
209
211 {
212 if (params.count("n_kernels") && !params["n_kernels"] > 0)
213 n_kernels_ = params["n_kernels"];
214
215 if (params.count("kernel_distance") && !params["kernel_distance"] > 0)
216 kernel_distance_ = params["kernel_distance"];
217
218 if (params.count("kernel_weights") && !params["kernel_weights"].empty())
219 {
220 std::ifstream in(params["kernel_weights"].get<std::string>());
221 std::string token;
222 in >> token;
223 int n_weights;
224 in >> n_weights;
225 kernel_weights_.resize(n_weights);
226 for (int i = 0; i < n_weights; ++i)
227 in >> kernel_weights_(i);
228 }
229 }
230
232 {
233 return !assembler_.is_tensor();
234 }
235 } // namespace problem
236} // namespace polyfem
double val
Definition Assembler.cpp:86
virtual Eigen::Matrix< AutodiffScalarGrad, Eigen::Dynamic, 1, 0, 3, 1 > kernel(const int dim, const AutodiffGradPt &rvect, const AutodiffScalarGrad &r) const
virtual bool is_tensor() const
KernelProblem(const std::string &name, const assembler::Assembler &assembler)
VectorNd eval_fun(const VectorNd &pt, const double t) const override
bool is_scalar() const override
void rhs(const assembler::Assembler &assembler, const Eigen::MatrixXd &pts, const double t, Eigen::MatrixXd &val) const override
const assembler::Assembler & assembler_
void set_parameters(const json &params) override
virtual int size_for(const Eigen::MatrixXd &pts) const
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > VectorNd
Definition Types.hpp:11
nlohmann::json json
Definition Common.hpp:9
DScalar1< double, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > > AutodiffScalarGrad
Eigen::Matrix< AutodiffScalarGrad, Eigen::Dynamic, 1, 0, 3, 1 > AutodiffGradPt
static void setVariableCount(size_t value)
Set the independent variable count used by the automatic differentiation layer.
Definition autodiff.h:54