|
|
|
@ -10,6 +10,7 @@ |
|
|
|
#include <fstream> |
|
|
|
#include <vector> |
|
|
|
#include "bernstein.hpp" |
|
|
|
#include "multiloop.hpp" |
|
|
|
#include "quadrature_multipoly.hpp" |
|
|
|
#include "binomial.hpp" |
|
|
|
|
|
|
|
@ -92,6 +93,7 @@ void qConvMultiPloy(const F1& fphi1, |
|
|
|
bernstein::bernsteinInterpolate<N>([&](const uvector<real, N>& x) { return fphi2(xmin + x * (xmax - xmin)); }, phi2); |
|
|
|
|
|
|
|
// Build quadrature hierarchy
|
|
|
|
auto t = std::chrono::system_clock::now(); |
|
|
|
ImplicitPolyQuadrature<N> ipquad(phi1, phi2); |
|
|
|
// ImplicitPolyQuadrature<N> ipquad(phi1);
|
|
|
|
|
|
|
|
@ -123,6 +125,9 @@ void qConvMultiPloy(const F1& fphi1, |
|
|
|
surf *= pow(xmax - xmin, N - 1); |
|
|
|
}; |
|
|
|
compute(q); |
|
|
|
auto tAfter = std::chrono::system_clock::now(); |
|
|
|
std::chrono::duration<double> elapsed_seconds = tAfter - t; |
|
|
|
std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n"; |
|
|
|
std::cout << "q volume: " << volume << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
@ -135,9 +140,10 @@ void qConvMultiPloy2(real xmin, real xmax, const uvector<int, N>& P, const F& in |
|
|
|
// bernstein::bernsteinInterpolate<N>([&](const uvector<real, N>& x) { return fphi2(xmin + x * (xmax - xmin)); }, phi2);
|
|
|
|
|
|
|
|
std::vector<xarray<real, N>> phis; // 大量sphere
|
|
|
|
// xarray<real, N>* phis = new xarray<real, N>[100];
|
|
|
|
for (int i = 0; i < 100; i++) { |
|
|
|
real centerX = 1.0 - rand() % 20 / 10.0, centerY = 1.0 - rand() % 20 / 10.0, centerZ = 1.0 - rand() % 20 / 10.0; |
|
|
|
real r = 0.1 + rand() % 9 / 10.0; |
|
|
|
real r = 0.01 + rand() % 10 / 100.0; |
|
|
|
auto fphi = [&](const uvector<real, 3>& xx) { |
|
|
|
real x = xx(0) - centerX; |
|
|
|
real y = xx(1) - centerY; |
|
|
|
@ -147,6 +153,7 @@ void qConvMultiPloy2(real xmin, real xmax, const uvector<int, N>& P, const F& in |
|
|
|
xarray<real, N> phi(nullptr, P); |
|
|
|
algoim_spark_alloc(real, phi); |
|
|
|
bernstein::bernsteinInterpolate<N>([&](const uvector<real, N>& x) { return fphi(xmin + x * (xmax - xmin)); }, phi); |
|
|
|
phis.emplace_back(phi); |
|
|
|
} |
|
|
|
auto t = std::chrono::system_clock::now(); |
|
|
|
|
|
|
|
@ -290,7 +297,7 @@ void qConvBernstein(const xarray<real, N>& phi, |
|
|
|
int q, |
|
|
|
const std::vector<std::array<real, 4>>& halfFaces) |
|
|
|
{ |
|
|
|
uvector<real, 3> testX(0., 0., 0.5); |
|
|
|
uvector<real, 3> testX(0., 0., 0.25); |
|
|
|
real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX); |
|
|
|
auto vec1 = xarray2StdVector(phi); |
|
|
|
std::cout << "eval bernstein without interpolation:" << testEvalBernstein << std::endl; |
|
|
|
@ -307,10 +314,12 @@ void qConvBernstein(const xarray<real, N>& phi, |
|
|
|
if (!halfFaces.empty()) { |
|
|
|
ipquad.integrate(AutoMixed, q, [&](const uvector<real, N>& x, real w) { |
|
|
|
if (bernstein::evalBernsteinPoly(phi, x) >= 0) return; |
|
|
|
uvector<real, N> trueX = xmin + x * (xmax - xmin); |
|
|
|
// std::cout << "trueX: " << trueX << std::endl;
|
|
|
|
bool in = true; |
|
|
|
for (int i = 0; i < halfFaces.size(); ++i) { |
|
|
|
uvector<real, 3> factors(halfFaces[i][0], halfFaces[i][1], halfFaces[i][2]); |
|
|
|
if (prod(factors * x) + halfFaces[i][3] > 0) { |
|
|
|
if (sum(factors * trueX) + halfFaces[i][3] >= 0) { |
|
|
|
in = false; |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -378,6 +387,34 @@ void testSpherePowerDirectly() |
|
|
|
qConvBernstein(phiBernstein, -1, 1, integrand, 10, {}); |
|
|
|
} |
|
|
|
|
|
|
|
void powerTransformation(const uvector<real, 3>& scale, const uvector<real, 3>& bias, xarray<real, 3>& phiPower) |
|
|
|
{ |
|
|
|
std::vector<std::vector<std::vector<real>>> dimOrderExpansion; |
|
|
|
const auto& ext = phiPower.ext(); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
dimOrderExpansion.push_back(std::vector<std::vector<real>>(ext(dim))); |
|
|
|
for (int degree = 0; degree < ext(dim); ++degree) { |
|
|
|
const real* binomDegree = Binomial::row(degree); |
|
|
|
dimOrderExpansion[dim][degree].reserve(degree + 1); |
|
|
|
// 根据二项定理展开
|
|
|
|
for (int i = 0; i <= degree; ++i) { |
|
|
|
dimOrderExpansion[dim][degree].push_back(binomDegree[i] * pow(scale(dim), i) * pow(bias(dim), degree - i)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
for (auto i = phiPower.loop(); ~i; ++i) { |
|
|
|
// 迭代器必须按照坐标的升序进行访问,即,访问ijk时,(i-1)jk,i(j-1)k,ij(k-1)必须已经访问过
|
|
|
|
real base = phiPower.l(i); |
|
|
|
phiPower.l(i) = 0; |
|
|
|
auto exps = i(); |
|
|
|
for (MultiLoop<3> j(0, exps + 1); ~j; ++j) { |
|
|
|
real item = base; |
|
|
|
for (int dim = 0; dim < 3; ++dim) { item *= dimOrderExpansion[dim][exps(dim)][j(dim)]; } |
|
|
|
phiPower.m(j()) += item; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void testSpherePowerDirectlyByTransformation() |
|
|
|
{ |
|
|
|
// a_x(x-c_x)^2 + a_y(y-c_y)^2 + a_z(x-c_z)^2 - r^2
|
|
|
|
@ -386,8 +423,6 @@ void testSpherePowerDirectlyByTransformation() |
|
|
|
assert(all(range != 0)); |
|
|
|
// uvector<real, 3> k = 1 / range;
|
|
|
|
// uvector<real, 3> bias = -k * xmin;
|
|
|
|
uvector<real, 3> k = range; |
|
|
|
uvector<real, 3> bias = xmin; |
|
|
|
real a[3] = {1, 1, 1}; |
|
|
|
real c[3] = {0, 0, 0}; |
|
|
|
real r = 1; |
|
|
|
@ -396,7 +431,6 @@ void testSpherePowerDirectlyByTransformation() |
|
|
|
algoim_spark_alloc(real, phiPower, phiBernstein); |
|
|
|
xarrayInit(phiPower); |
|
|
|
xarrayInit(phiBernstein); |
|
|
|
std::vector<std::vector<real>> dimTransformation; |
|
|
|
auto v = xarray2StdVector(phiPower); |
|
|
|
auto vv = xarray2StdVector(phiBernstein); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
@ -408,25 +442,7 @@ void testSpherePowerDirectlyByTransformation() |
|
|
|
phiPower.m(idx) = a[dim]; |
|
|
|
} |
|
|
|
phiPower.m(0) -= r * r; |
|
|
|
|
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
dimTransformation[0](std::vector<real>(ext(dim), 0)); |
|
|
|
for (int degree = 0; degree < ext(dim); ++degree) { |
|
|
|
// dimTransformation[dim][degree] = 0;
|
|
|
|
const real* binomDegree = Binomial::row(degree); |
|
|
|
for (int i = 0; i <= degree; ++i) { |
|
|
|
// 根据二项定理展开
|
|
|
|
dimTransformation[dim][i] += binomDegree[i] * pow(k(dim), i) * pow(bias(dim), degree - i); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// apply transformation
|
|
|
|
for (auto i = phiPower.loop(); ~i; ++i) { |
|
|
|
real item = phiPower.l(i); |
|
|
|
auto exps = i(); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { item += dimTransformation[dim][exps(dim)]; } |
|
|
|
phiPower.m(i()) = item; |
|
|
|
} |
|
|
|
powerTransformation(range, xmin, phiPower); |
|
|
|
|
|
|
|
auto integrand = [](const uvector<real, 3>& x) { return 1.0; }; |
|
|
|
power2BernsteinTensorProduct(phiPower, phiBernstein); |
|
|
|
@ -457,45 +473,32 @@ void testCylinderPowerDirectly() |
|
|
|
algoim_spark_alloc(real, phiPower, phiBernstein); |
|
|
|
xarrayInit(phiPower); |
|
|
|
xarrayInit(phiBernstein); |
|
|
|
std::vector<std::vector<real>> dimTransformation; |
|
|
|
auto v = xarray2StdVector(phiPower); |
|
|
|
auto vv = xarray2StdVector(phiBernstein); |
|
|
|
real top = c[2] + h * 0.5, bottom = c[2] - h * 0.5; |
|
|
|
phiPower.m(uvector<int, 3>(2, 0, 2)) = -1; |
|
|
|
phiPower.m(uvector<int, 3>(0, 2, 2)) = -1; |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 2)) = r * r; |
|
|
|
phiPower.m(uvector<int, 3>(2, 0, 1)) = top + bottom; |
|
|
|
phiPower.m(uvector<int, 3>(0, 2, 1)) = top + bottom; |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 1)) = -(bottom + top) * r * r; |
|
|
|
phiPower.m(uvector<int, 3>(1, 0, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(0, 1, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 0)) = bottom * top * r * r; |
|
|
|
|
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
dimTransformation.push_back(std::vector<real>(ext(dim), 0)); |
|
|
|
for (int degree = 0; degree < ext(dim); ++degree) { |
|
|
|
// dimTransformation[dim][degree] = 0;
|
|
|
|
const real* binomDegree = Binomial::row(degree); |
|
|
|
for (int i = 0; i <= degree; ++i) { |
|
|
|
// 根据二项定理展开
|
|
|
|
dimTransformation[dim][i] += binomDegree[i] * pow(k(dim), i) * pow(bias(dim), degree - i); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// apply transformation
|
|
|
|
for (auto i = phiPower.loop(); ~i; ++i) { |
|
|
|
real item = phiPower.l(i); |
|
|
|
auto exps = i(); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { item *= dimTransformation[dim][exps(dim)]; } |
|
|
|
phiPower.m(i()) = item; |
|
|
|
} |
|
|
|
phiPower.m(uvector<int, 3>(2, 0, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(0, 2, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(1, 0, 2)) = 2 * c[0]; |
|
|
|
phiPower.m(uvector<int, 3>(0, 1, 2)) = 2 * c[1]; |
|
|
|
phiPower.m(uvector<int, 3>(1, 0, 1)) = -2 * c[0] * (top + bottom); |
|
|
|
phiPower.m(uvector<int, 3>(0, 1, 1)) = -2 * c[1] * (top + bottom); |
|
|
|
phiPower.m(uvector<int, 3>(1, 0, 0)) = 2 * c[0] * (top * bottom); |
|
|
|
phiPower.m(uvector<int, 3>(0, 1, 0)) = 2 * c[0] * (top * bottom); |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 2)) = -(c[0] * c[0] + c[1] * c[1] - r * r); |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 1)) = (bottom + top) * (c[0] * c[0] + c[1] * c[1] - r * r); |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 0)) = -bottom * top * (c[0] * c[0] + c[1] * c[1] - r * r); |
|
|
|
|
|
|
|
powerTransformation(range, xmin, phiPower); |
|
|
|
|
|
|
|
auto integrand = [](const uvector<real, 3>& x) { return 1.0; }; |
|
|
|
power2BernsteinTensorProduct(phiPower, phiBernstein); |
|
|
|
|
|
|
|
v = xarray2StdVector(phiPower); |
|
|
|
uvector<real, 3> testX(0., 0., 0.5); |
|
|
|
uvector<real, 3> testX(0., 0., 0.75); |
|
|
|
real testEval = powerEvaluation(phiPower, testX); |
|
|
|
std::cout << "eval power:" << testEval << std::endl; |
|
|
|
|
|
|
|
@ -506,7 +509,7 @@ void testCylinderPowerDirectly() |
|
|
|
-1, |
|
|
|
1, |
|
|
|
integrand, |
|
|
|
50, |
|
|
|
10, |
|
|
|
{ |
|
|
|
{0, 0, 1, -top }, |
|
|
|
{0, 0, -1, bottom} |
|
|
|
@ -555,9 +558,10 @@ void testBooluarray() |
|
|
|
|
|
|
|
void testMain() |
|
|
|
{ |
|
|
|
testBooluarray(); |
|
|
|
testMultiPolys(); |
|
|
|
testMultiScale(); |
|
|
|
// testBooluarray();
|
|
|
|
// testMultiPolys();
|
|
|
|
// testMultiScale();
|
|
|
|
// testSpherePowerDirectly();
|
|
|
|
testSpherePowerDirectlyByTransformation(); |
|
|
|
testCylinderPowerDirectly(); |
|
|
|
// testCylinderPowerDirectly();
|
|
|
|
} |
|
|
|
|