Browse Source

unified interfaces

master
gjj 7 months ago
parent
commit
ac0df77087
  1. 48
      algoim/organizer/organizer.hpp
  2. 573
      algoim/organizer/primitive.hpp
  3. 7
      algoim/sparkstack.hpp
  4. 2
      algoim/xarray.hpp
  5. 53
      examples/examples_quad_general.cpp
  6. 6
      examples/examples_quad_multipoly.cpp
  7. 2
      gjj/myDebug.hpp
  8. 47
      gjj/primitiveDebug.hpp

48
algoim/organizer/organizer.hpp

@ -29,11 +29,11 @@ namespace algoim::Organizer
class BasicTask
{
public:
std::vector<BernsteinPrimitive> primitives;
// std::vector<std::shared_ptr<PrimitiveDesc>> primitives;
BasicTask(std::vector<std::shared_ptr<Primitive>> ps) {};
// BasicTask(std::vector<std::shared_ptr<PrimitiveDesc>> ps) {};
BasicTask(std::shared_ptr<Primitive> p)
BasicTask(std::shared_ptr<PrimitiveDesc> p)
{
int q = 20;
real volume = 0;
@ -43,25 +43,45 @@ public:
uvector3 range = xmax - xmin;
if (auto pt = std::dynamic_pointer_cast<PowerTensor>(p)) {
detail::powerTransformation(range, xmin, pt->tensor);
auto primitive = BernsteinTensor(*pt);
if (auto pt = std::dynamic_pointer_cast<SphereDesc>(p)) {
tensor3 tensor(nullptr, 3);
algoim_spark_alloc(real, tensor);
makeSphere(*pt, tensor);
detail::powerTransformation(range, xmin, tensor);
tensor3 phi(nullptr, 3);
algoim_spark_alloc(real, phi);
detail::power2BernsteinTensor(tensor, phi);
uvector<real, 3> testX(0., 0., 0.25);
real testEvalBernstein = bernstein::evalBernsteinPoly(primitive.tensor, testX);
real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX);
// auto vec1 = xarray2StdVector(phi);
std::cout << "eval bernstein without interpolation:" << testEvalBernstein << std::endl;
ImplicitPolyQuadrature<3> ipquad(primitive.tensor);
ImplicitPolyQuadrature<3> ipquad(phi);
ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) {
if (primitive.isInside(x)) volume += w * integrand(xmin + x * (xmax - xmin));
if (isInsideBernstein(phi, x)) volume += w * integrand(xmin + x * (xmax - xmin));
});
} else if (auto pc = std::dynamic_pointer_cast<PowerTensorComplex>(p)) {
detail::powerTransformation(range, xmin, pc->compositeTensor);
auto primitive = BernsteinTensorComplex(*pc);
ImplicitPolyQuadrature<3> ipquad(primitive.compositeTensor);
} else if (auto pt = std::dynamic_pointer_cast<MeshDesc>(p)) {
const int faceCount = pt->indexInclusiveScan.size();
assert(faceCount > 1);
std::vector<tensor3> planeTensors(faceCount, tensor3(nullptr, 2));
algoim_spark_alloc(real, planeTensors);
tensor3 compositeTensor(nullptr, 1 + faceCount);
algoim_spark_alloc(real, compositeTensor);
makeMesh(*pt, compositeTensor, planeTensors);
detail::powerTransformation(range, xmin, compositeTensor);
tensor3 phi(nullptr, 1 + faceCount);
algoim_spark_alloc(real, phi);
detail::power2BernsteinTensor(compositeTensor, phi);
ImplicitPolyQuadrature<3> ipquad(phi);
ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) {
if (primitive.isInside(x)) volume += w * integrand(xmin + x * (xmax - xmin));
auto realX = x * range + xmin;
if (isInsidePowers(planeTensors, realX)) volume += w * integrand(realX);
});
}
volume *= pow(xmax - xmin, 3);

573
algoim/organizer/primitive.hpp

@ -1,5 +1,6 @@
#pragma once
#include <cassert>
#include <cmath>
#include <cstddef>
#include <vector>
#include "iostream"
@ -17,36 +18,6 @@ namespace algoim::Organizer
namespace detail
{
void compositePower(const std::vector<xarray<real, 3>>& powers,
int powerIdx,
uvector<int, 3> powerSum,
real factor,
xarray<real, 3>& res)
{
if (powerIdx == 0) {
{
uvector3 ext(1, 1, 1);
for (auto& t : powers) { ext += t.ext() - 1; }
assert(all(ext == res.ext()));
}
xarrayInit(res);
}
if (powerIdx == powers.size()) {
res.m(powerSum) += factor;
return;
}
auto& power = powers[powerIdx];
for (auto i = power.loop(); ~i; ++i) {
if (power.l(i) == 0) {
factor = 0;
continue;
}
compositePower(powers, powerIdx + 1, powerSum + i(), factor * power.l(i), res);
}
// int a = 1;
}
// void compositePower(const std::vector<xarray<real, 3>>& powers) {}
template <int N>
@ -113,7 +84,7 @@ class Primitive
public:
virtual void print() = 0;
virtual real eval(uvector3) { return 0; }
virtual real eval(const uvector3&) { return 0; }
};
template <int N>
@ -135,216 +106,243 @@ real evalBernstein(const xarray<real, N>& phi, const uvector<real, N>& x)
return bernstein::evalBernsteinPoly(phi, x);
}
class PowerTensor : public Primitive
// class PowerTensor : public Primitive
// {
// public:
// xarray<real, 3> tensor;
// // SparkStack<real>* sparkStackPtr;
// void print() override { std::cout << "Power" << std::endl; }
// real eval(const uvector3& p) override { return evalPower(tensor, p); }
// // PowerTensor() {}
// PowerTensor(const xarray<real, 3>& t_) : tensor(t_) {}
// // const xarray<real, 3>& getTensor() { return tensor; }
// ~PowerTensor() = default;
// };
// class PowerTensorComplex : public Primitive
// {
// public:
// xarray<real, 3> compositeTensor; // 复合后的张量
// SparkStack<real>* sparkStackPtr;
// std::vector<xarray<real, 3>> tensors; // 原始张量
// // std::vector<PowerTensor> powerTensors; // 原始张量
// void print() override { std::cout << "PowerTensorComplex" << std::endl; }
// static void compositePower(const std::vector<PowerTensor>& powers,
// int powerIdx,
// uvector<int, 3> powerSum,
// real factor,
// xarray<real, 3>& res)
// {
// // const xarray<real, 3>& tensor
// if (powerIdx == 0) {
// {
// uvector3 ext(1, 1, 1);
// for (auto& t : powers) { ext += t.tensor.ext() - 1; }
// assert(all(ext == res.ext()));
// }
// xarrayInit(res);
// }
// if (powerIdx == powers.size()) {
// res.m(powerSum) += factor;
// return;
// }
// auto& tensor = powers[powerIdx].tensor;
// for (auto i = tensor.loop(); ~i; ++i) {
// if (tensor.l(i) == 0) {
// factor = 0;
// continue;
// }
// compositePower(powers, powerIdx + 1, powerSum + i(), factor * tensor.l(i), res);
// }
// }
// static void compositePower(const std::vector<xarray<real, 3>>& powers,
// int powerIdx,
// uvector<int, 3> powerSum,
// real factor,
// xarray<real, 3>& res)
// {
// if (powerIdx == 0) {
// {
// uvector3 ext(1, 1, 1);
// for (auto& t : powers) { ext += t.ext() - 1; }
// assert(all(ext == res.ext()));
// }
// xarrayInit(res);
// }
// if (powerIdx == powers.size()) {
// res.m(powerSum) += factor;
// return;
// }
// auto& power = powers[powerIdx];
// for (auto i = power.loop(); ~i; ++i) {
// if (power.l(i) == 0) {
// factor = 0;
// continue;
// }
// compositePower(powers, powerIdx + 1, powerSum + i(), factor * power.l(i), res);
// }
// }
// // PowerTensorComplex() {}
// PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_, xarray<real, 3>& ct_) : tensors(ts_), compositeTensor(ct_)
// {
// uvector3 ext(1);
// for (auto& t : ts_) { ext += t.ext() - 1; }
// assert(all(ext == compositeTensor.ext()));
// compositePower(tensors, 0, uvector3(0), 1, compositeTensor);
// }
// PowerTensorComplex(const std::vector<PowerTensor>& pts_, xarray<real, 3>& ct_) : compositeTensor(ct_)
// {
// uvector3 ext(1);
// tensors.resize(pts_.size());
// for (int i = 0; i < pts_.size(); ++i) {
// tensors[i] = pts_[i].tensor;
// ext += pts_[i].tensor.ext() - 1;
// }
// assert(all(ext == compositeTensor.ext()));
// compositePower(tensors, 0, uvector3(0), 1, compositeTensor);
// }
// PowerTensorComplex(const std::vector<PowerTensorComplex>& ptcs_, xarray<real, 3>& ct_) : compositeTensor(ct_)
// {
// std::vector<xarray<real, 3>> originCompositeTensors;
// uvector3 ext(1);
// for (auto& ptc : ptcs_) {
// for (auto& t : ptc.tensors) { tensors.emplace_back(t); }
// originCompositeTensors.push_back(ptc.compositeTensor);
// ext += ptc.compositeTensor.ext() - 1;
// }
// compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
// }
// real eval(const uvector3& p) override { return evalPower(compositeTensor, p); }
// bool isInside(const uvector3& p)
// {
// for (auto& t : tensors) {
// if (evalPower(t, p) >= 0) { return false; }
// }
// return true;
// }
// };
// class BernsteinPrimitive : public Primitive
// {
// };
// class BernsteinTensor : public BernsteinPrimitive
// {
// public:
// xarray<real, 3> tensor;
// void print() override { std::cout << "Bernstein" << std::endl; }
// real eval(const uvector3& p) override { return evalBernstein(tensor, p); }
// BernsteinTensor(const PowerTensor& pt_)
// {
// auto v0 = xarray2StdVector(pt_.tensor);
// tensor.ext_ = pt_.tensor.ext();
// algoim_spark_alloc(real, tensor);
// auto v1 = xarray2StdVector(pt_.tensor);
// auto v2 = xarray2StdVector(tensor);
// detail::power2BernsteinTensor(pt_.tensor, tensor);
// uvector3 x(0.2, 0.5, 0.6);
// real BernsteinValue = bernstein::evalBernsteinPoly(tensor, x);
// real PowerValue = evalPower(pt_.tensor, x);
// int a = 1;
// }
// bool isInside(uvector3 p) { return eval(p) < 0; }
// };
// class BernsteinTensorComplex : public BernsteinPrimitive
// {
// public:
// bool fromPower;
// xarray<real, 3> compositeTensor; // 复合后的张量
// std::vector<xarray<real, 3>> tensors; // 原始张量
// void print() override { std::cout << "Bernstein Complex" << std::endl; }
// real eval(const uvector3& p) override { return evalBernstein(compositeTensor, p); }
// // BernsteinTensorComplex(const PowerTensorComplex& pc_) : fromPower(true), tensors(pc_.tensors)
// // {
// // compositeTensor.ext_ = pc_.compositeTensor.ext();
// // algoim_spark_alloc(real, compositeTensor);
// // detail::power2BernsteinTensor(pc_.compositeTensor, compositeTensor);
// // };
// bool isInside(uvector3 p)
// {
// if (fromPower) {
// for (auto& t : tensors) {
// if (evalPower(t, p) >= 0) { return false; }
// }
// return true;
// } else {
// for (auto& t : tensors) {
// if (eval(p) >= 0) { return false; }
// }
// return true;
// }
// return true;
// };
// };
bool isInsidePowers(const std::vector<tensor3>& tensors, const uvector3& p)
{
public:
xarray<real, 3> tensor;
// SparkStack<real>* sparkStackPtr;
void print() override { std::cout << "Power" << std::endl; }
real eval(uvector3 p) override { return evalPower(tensor, p); }
// PowerTensor() {}
PowerTensor(const xarray<real, 3>& t_) : tensor(t_) {}
// const xarray<real, 3>& getTensor() { return tensor; }
~PowerTensor() = default;
};
class PowerTensorComplex : public Primitive
{
public:
xarray<real, 3> compositeTensor; // 复合后的张量
SparkStack<real>* sparkStackPtr;
// std::vector<xarray<real, 3>> tensors; // 原始张量
std::vector<PowerTensor> tensors; // 原始张量
void print() override { std::cout << "PowerTensorComplex" << std::endl; }
// PowerTensorComplex() {}
// PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_) : tensors(ts_)
// {
// uvector3 ext(1, 1, 1);
// for (auto& t : ts_) { ext += t.ext() - 1; }
// compositeTensor.ext_ = ext;
// sparkStackPtr = algoim_spark_alloc_heap(real, compositeTensor);
// // detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
// }
PowerTensorComplex(const std::vector<PowerTensor>& pts_, xarray<real, 3>& ptc_) : tensors(pts_), compositeTensor(ptc_)
{
uvector3 ext(1);
for (auto& pt : pts_) { ext += pt.tensor.ext() - 1; }
assert(all(ext == compositeTensor.ext()));
detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
}
PowerTensorComplex(const std::vector<PowerTensorComplex>& pcs_)
{
for (auto& pc : pcs_) {
for (auto& t : pc.tensors) { tensors.push_back(t); }
}
std::vector<xarray<real, 3>> originCompositeTensors;
uvector3 ext(1, 1, 1);
for (auto& pc : pcs_) {
originCompositeTensors.push_back(pc.compositeTensor);
ext += pc.compositeTensor.ext() - 1;
}
compositeTensor.ext_ = ext;
sparkStackPtr = algoim_spark_alloc_heap(real, compositeTensor);
detail::compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
}
PowerTensorComplex add(const PowerTensorComplex& pc)
{
std::vector<PowerTensorComplex> pcs;
pcs.emplace_back(*this);
pcs.emplace_back(pc);
return PowerTensorComplex(pcs);
}
PowerTensorComplex add(const PowerTensor& pt)
{
std::vector<PowerTensorComplex> pcs;
pcs.emplace_back(*this);
// pcs.emplace_back(PowerTensorComplex({pt.tensor}));
return PowerTensorComplex(pcs);
}
real eval(uvector3 p) override { return evalPower(compositeTensor, p); }
bool isInside(uvector3 p)
{
for (auto& t : tensors) {
// if (evalPower(t, p) >= 0) { return false; }
}
return true;
for (auto& t : tensors) {
if (evalPower(t, p) >= 0) { return false; }
}
return true;
};
PowerTensorComplex makeMesh(const std::vector<uvector3>& vertices, const std::vector<uvector<int, 3>>& indices)
{
uvector3 ext(1 + indices.size());
// PowerTensorComplex pc(ext);
std::vector<PowerTensor> pts;
for (const auto& index : indices) {
// xarray<real, 3> tensor(nullptr, ); // 最高1次
// algoim_spark_alloc(real, tensor);
PowerTensor pt(uvector3(2));
uvector3 V01 = vertices[index(1)] - vertices[index(0)];
uvector3 V02 = vertices[index(2)] - vertices[index(0)];
uvector3 N = cross(V01, V02);
N /= norm(N);
real d = -dot(N, vertices[index(0)]);
// 法线所指方向为>0区域
pt.tensor.m(uvector3(0, 0, 0)) = d;
pt.tensor.m(uvector3(1, 0, 0)) = N(0);
pt.tensor.m(uvector3(0, 1, 0)) = N(1);
pt.tensor.m(uvector3(0, 0, 1)) = N(2);
pts.push_back(pt);
}
PowerTensorComplex pc(pts);
pc.compositeTensor.ext_ = ext;
algoim_spark_alloc(real, pc.compositeTensor);
// detail::compositePower(pc.tensors, 0, 0, 1, pc.compositeTensor);
return pc;
}
bool isInsideBernstein(const tensor3& t, const uvector3& p) { return evalBernstein(t, p) < 0; }
PowerTensor makeSphere(const real r, const uvector3& c = 0, const uvector3& a = 1)
{
uvector<int, 3> ext = 3;
PowerTensor pt(ext);
for (int dim = 0; dim < 3; ++dim) {
uvector<int, 3> idx = 0;
pt.tensor.m(idx) += c(dim) * c(dim);
idx(dim) = 1;
pt.tensor.m(idx) = 2 * a(dim) * (-c(dim));
idx(dim) = 2;
pt.tensor.m(idx) = a(dim) * a(dim);
}
pt.tensor.m(0) -= r * r;
return pt;
}
bool isInsidePower(const tensor3& t, const uvector3& p) { return evalPower(t, p) < 0; }
PowerTensor makeCylinder(uvector3 startPt, uvector3 endPt, real r)
{
// PowerTensor pt;
// TODO:
return PowerTensor({});
}
class BernsteinPrimitive : public Primitive
class FRep : public Primitive
{
};
private:
std::function<real(uvector3)> f;
class BernsteinTensor : public BernsteinPrimitive
{
public:
xarray<real, 3> tensor;
void print() override { std::cout << "Bernstein" << std::endl; }
real eval(uvector3 p) override { return evalBernstein(tensor, p); }
void print() override { std::cout << "FRep" << std::endl; }
BernsteinTensor(const PowerTensor& pt_)
{
auto v0 = xarray2StdVector(pt_.tensor);
tensor.ext_ = pt_.tensor.ext();
algoim_spark_alloc(real, tensor);
auto v1 = xarray2StdVector(pt_.tensor);
auto v2 = xarray2StdVector(tensor);
detail::power2BernsteinTensor(pt_.tensor, tensor);
uvector3 x(0.2, 0.5, 0.6);
real BernsteinValue = bernstein::evalBernsteinPoly(tensor, x);
real PowerValue = evalPower(pt_.tensor, x);
int a = 1;
}
real eval(const uvector3& p) override { return f(p); }
bool isInside(uvector3 p) { return eval(p) < 0; }
FRep(std::function<real(uvector3)> f_) : f(f_) {}
};
class BernsteinTensorComplex : public BernsteinPrimitive
enum PrimitiveType { Sphere, Cylinder, Cone, Mesh, BRep };
class PrimitiveDesc
{
public:
bool fromPower;
xarray<real, 3> compositeTensor; // 复合后的张量
std::vector<xarray<real, 3>> tensors; // 原始张量
void print() override { std::cout << "Bernstein Complex" << std::endl; }
real eval(uvector3 p) override { return evalBernstein(compositeTensor, p); }
// const static PrimitiveType type;
PrimitiveDesc() = default;
// BernsteinTensorComplex(const PowerTensorComplex& pc_) : fromPower(true), tensors(pc_.tensors)
// {
// compositeTensor.ext_ = pc_.compositeTensor.ext();
// algoim_spark_alloc(real, compositeTensor);
// detail::power2BernsteinTensor(pc_.compositeTensor, compositeTensor);
// };
bool isInside(uvector3 p)
{
if (fromPower) {
for (auto& t : tensors) {
if (evalPower(t, p) >= 0) { return false; }
}
return true;
} else {
for (auto& t : tensors) {
if (eval(p) >= 0) { return false; }
}
return true;
}
return true;
};
virtual void print() {} // 空定义也可以,但是一定要有定义
};
class ParametricSurface
@ -388,27 +386,30 @@ private:
int degree;
};
class BRep : public Primitive
class BRepDesc : virtual public PrimitiveDesc
{
const static PrimitiveType type = BRep;
std::vector<uvector3> vertices;
std::vector<ParametricCurve> curves;
std::vector<ParametricSurface> surfaces;
public:
void print() override { std::cout << "FRep" << std::endl; }
void print() override { std::cout << "BRep Description" << std::endl; }
real eval(uvector3 p) override
real eval(const uvector3& p)
{
// DOTO: the implicit conversion of Parametric BRep
return 0;
}
BRep(const std::vector<uvector3>& vs_, const std::vector<ParametricCurve>& cs_, const std::vector<ParametricSurface>& ss_)
BRepDesc(const std::vector<uvector3>& vs_,
const std::vector<ParametricCurve>& cs_,
const std::vector<ParametricSurface>& ss_)
: vertices(vs_), curves(cs_), surfaces(ss_)
{
}
BRep(const BRep& brep)
BRepDesc(const BRepDesc& brep)
{
vertices = brep.vertices;
curves = brep.curves;
@ -416,16 +417,116 @@ public:
}
};
class FRep : public Primitive
class SphereDesc : virtual public PrimitiveDesc
{
private:
std::function<real(uvector3)> f;
public:
const static PrimitiveType type = Sphere;
real radius;
uvector3 center;
uvector3 amplitude;
SphereDesc(real r_, const uvector3& c_, const uvector3& a_) : PrimitiveDesc(), radius(r_), center(c_), amplitude(a_) {}
void print() override { std::cout << "Sphere Description" << std::endl; }
};
class CylinderDesc : virtual public PrimitiveDesc
{
const static PrimitiveType type = Cylinder;
uvector3 node1;
uvector3 node2;
real radius;
CylinderDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {}
void print() override { std::cout << "Cylinder Description" << std::endl; }
};
class ConeDesc : virtual public PrimitiveDesc
{
const static PrimitiveType type = Cone;
uvector3 node1;
uvector3 node2;
real radius;
ConeDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {}
void print() override { std::cout << "Cone Description" << std::endl; }
};
class MeshDesc : virtual public PrimitiveDesc
{
public:
void print() override { std::cout << "FRep" << std::endl; }
const static PrimitiveType type = Mesh;
std::vector<uvector3> vertices;
std::vector<int> indices;
std::vector<int> indexInclusiveScan;
MeshDesc(const std::vector<uvector3>& vertices_,
const std::vector<int>& indices_,
const std::vector<int>& indexInclusiveScan_)
: PrimitiveDesc(), vertices(vertices_), indices(indices_), indexInclusiveScan(indexInclusiveScan_)
{
}
real eval(uvector3 p) override { return f(p); }
void print() override { std::cout << "Mesh Description" << std::endl; }
};
FRep(std::function<real(uvector3)> f_) : f(f_) {}
void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors)
{
uvector3 ext(1 + mesh.indexInclusiveScan.size());
assert(all(ext == tensor.ext()));
assert(planeTensors.size() == mesh.indexInclusiveScan.size());
// for (const auto& index : indices) {
for (int i = 0; i < mesh.indexInclusiveScan.size(); ++i) {
const int indexBeg = i == 0 ? 0 : mesh.indexInclusiveScan[i - 1];
const int indexSize = mesh.indexInclusiveScan[i] - indexBeg;
assert(indexSize >= 3);
auto& planeTensor = planeTensors[i];
xarrayInit(planeTensor);
auto& vertices = mesh.vertices;
auto& indices = mesh.indices;
uvector3 V01 = vertices[indices[indexBeg + 1]] - mesh.vertices[indices[indexBeg]];
uvector3 V02 = vertices[indices[indexBeg + 2]] - mesh.vertices[indices[indexBeg]];
uvector3 N = cross(V01, V02);
N /= norm(N);
real d = -dot(N, vertices[indices[indexBeg]]);
// 法线所指方向为>0区域
planeTensor.m(uvector3(0, 0, 0)) = d;
planeTensor.m(uvector3(1, 0, 0)) = N(0);
planeTensor.m(uvector3(0, 1, 0)) = N(1);
planeTensor.m(uvector3(0, 0, 1)) = N(2);
// test other vertices
for (int j = indexBeg + 3; j < mesh.indexInclusiveScan[i]; ++j) {
assert(dot(N, vertices[indices[j]]) + d < std::numeric_limits<real>::epsilon());
}
}
// compositePower(planeTensors, 0, 0, 1, tensor);
// return PowerTensorComplex(planeTensors, tensor);
};
void makeSphere(const SphereDesc& sphereDesc, xarray<real, 3>& tensor)
{
uvector<int, 3> ext = 3;
assert(all(ext == tensor.ext()));
for (int dim = 0; dim < 3; ++dim) {
uvector<int, 3> idx = 0;
tensor.m(idx) += sphereDesc.center(dim) * sphereDesc.center(dim);
idx(dim) = 1;
tensor.m(idx) = 2 * sphereDesc.amplitude(dim) * (-sphereDesc.center(dim));
idx(dim) = 2;
tensor.m(idx) = sphereDesc.amplitude(dim) * sphereDesc.amplitude(dim);
}
tensor.m(0) -= sphereDesc.radius * sphereDesc.radius;
// return PowerTensor(tensor);
};
void makeCylinder(xarray<real, 3>& tensor, uvector3 startPt, uvector3 endPt, real r)
{
// PowerTensor pt;
// TODO:
}
} // namespace algoim::Organizer

7
algoim/sparkstack.hpp

@ -96,6 +96,13 @@ public:
len_ = (alloc(&a.data_, a.size()) + ...);
}
template <int N>
explicit SparkStack(std::vector<xarray<T, N>>& as)
{
len_ = 0;
for (auto& a : as) len_ += alloc(&a.data_, a.size());
}
// Release memory when the SparkStack object goes out of scope
~SparkStack()
{

2
algoim/xarray.hpp

@ -375,6 +375,8 @@ public:
xarray<T, N>& ref() { return *this; }
};
using tensor3 = xarray<real, 3>;
template <typename T, int N>
void xarrayInit(xarray<T, N>& arr)
{

53
examples/examples_quad_general.cpp

@ -7,25 +7,24 @@
#include <fstream>
#include "quadrature_general.hpp"
template<int N>
struct Ellipsoid
{
template<typename T>
T operator() (const algoim::uvector<T,N>& x) const
template <int N>
struct Ellipsoid {
template <typename T>
T operator()(const algoim::uvector<T, N>& x) const
{
if constexpr (N == 2)
return x(0)*x(0) + 4.0*x(1)*x(1) - 1.0;
return x(0) * x(0) + 4.0 * x(1) * x(1) - 1.0;
else
return x(0)*x(0) + 4.0*x(1)*x(1) + 9.0*x(2)*x(2) - 1.0;
return x(0) * x(0) + 4.0 * x(1) * x(1) + 9.0 * x(2) * x(2) - 1.0;
}
template<typename T>
algoim::uvector<T,N> grad(const algoim::uvector<T,N>& x) const
template <typename T>
algoim::uvector<T, N> grad(const algoim::uvector<T, N>& x) const
{
if constexpr (N == 2)
return algoim::uvector<T,N>(2.0*x(0), 8.0*x(1));
return algoim::uvector<T, N>(2.0 * x(0), 8.0 * x(1));
else
return algoim::uvector<T,N>(2.0*x(0), 8.0*x(1), 18.0*x(2));
return algoim::uvector<T, N>(2.0 * x(0), 8.0 * x(1), 18.0 * x(2));
}
};
@ -39,8 +38,8 @@ int main(int argc, char* argv[])
{
std::cout << "Area of a 2D ellipse using automatic subdivision:\n";
Ellipsoid<2> phi;
auto q = algoim::quadGen<2>(phi, algoim::HyperRectangle<double,2>(-1.1, 1.1), -1, -1, 4);
double area = q([](const auto& x) { return 1.0; });
auto q = algoim::quadGen<2>(phi, algoim::HyperRectangle<double, 2>(-1.1, 1.1), -1, -1, 4);
double area = q([](const auto& x) { return 1.0; });
std::cout << " computed area = " << area << "\n";
std::cout << " (exact area = 1.5707963267948966)\n\n";
}
@ -49,8 +48,8 @@ int main(int argc, char* argv[])
{
std::cout << "Volume of a 3D ellipsoid using automatic subdivision:\n";
Ellipsoid<3> phi;
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double,3>(-1.1, 1.1), -1, -1, 4);
double volume = q([](const auto& x) { return 1.0; });
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double, 3>(-1.1, 1.1), -1, -1, 4);
double volume = q([](const auto& x) { return 1.0; });
std::cout << " computed volume = " << volume << "\n";
std::cout << " (exact volume = 0.6981317007977318)\n\n";
}
@ -59,15 +58,15 @@ int main(int argc, char* argv[])
{
int n = 16;
std::cout << "Area of a 2D ellipse, computed via the cells of a " << n << " by " << n << " Cartesian grid:\n";
double dx = 2.2 / n;
double dx = 2.2 / n;
Ellipsoid<2> phi;
double area = 0.0;
for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
{
algoim::uvector<double,2> xmin{-1.1 + i*dx, -1.1 + j*dx};
algoim::uvector<double,2> xmax{-1.1 + i*dx + dx, -1.1 + j*dx + dx};
area += algoim::quadGen<2>(phi, algoim::HyperRectangle<double,2>(xmin, xmax), -1, -1, 4).sumWeights();
}
double area = 0.0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j) {
algoim::uvector<double, 2> xmin{-1.1 + i * dx, -1.1 + j * dx};
algoim::uvector<double, 2> xmax{-1.1 + i * dx + dx, -1.1 + j * dx + dx};
area += algoim::quadGen<2>(phi, algoim::HyperRectangle<double, 2>(xmin, xmax), -1, -1, 4).sumWeights();
}
std::cout << " computed area = " << area << "\n";
std::cout << " (exact area = 1.5707963267948966)\n\n";
}
@ -76,8 +75,8 @@ int main(int argc, char* argv[])
{
std::cout << "Surface area of a 3D ellipsoid using automatic subdivision:\n";
Ellipsoid<3> phi;
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double,3>(-1.1, 1.1), 3, -1, 4);
double surface_area = q.sumWeights();
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double, 3>(-1.1, 1.1), 3, -1, 4);
double surface_area = q.sumWeights();
std::cout << " computed surface area = " << surface_area << "\n";
std::cout << " (exact surface area = 4.4008095646649703)\n\n";
}
@ -85,8 +84,8 @@ int main(int argc, char* argv[])
// Visualisation of a quadrature scheme in ParaView via XML VTP file
{
std::cout << "Visualisation of a quadrature scheme in ParaView via XML VTP file:\n";
Ellipsoid<3> phi;
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double,3>(-1.1, 1.1), -1, -1, 2);
Ellipsoid<3> phi;
auto q = algoim::quadGen<3>(phi, algoim::HyperRectangle<double, 3>(-1.1, 1.1), -1, -1, 2);
std::ofstream f("scheme.vtp");
algoim::outputQuadratureRuleAsVtpXML(q, f);
std::cout << " scheme.vtp file written, containing " << q.nodes.size() << " quadrature points\n";

6
examples/examples_quad_multipoly.cpp

@ -16,7 +16,7 @@
#include "xarray.hpp"
#include "myDebug.hpp"
// #include "primitiveDebug.hpp"
#include "primitiveDebug.hpp"
using namespace algoim;
@ -397,8 +397,8 @@ int main(int argc, char* argv[])
}
// module_test();
testMain();
// testPrimitive();
// testMain();
testPrimitive();
return 0;
}
#endif

2
gjj/myDebug.hpp

@ -1190,4 +1190,6 @@ void testMain()
// testQuarterSphere();
// testPower2Bernstein();
int a = log(2.01);
std::cout << "log(3) " << a << std::endl;
}

47
gjj/primitiveDebug.hpp

@ -30,44 +30,37 @@ using namespace algoim;
void case0()
{
std::vector<std::shared_ptr<Primitive>> ps;
// std::vector<std::shared_ptr<PrimitiveDesc>> ps;
// mesh
std::vector<uvector3> vertices = {uvector3(-0.8, -0.8, -0.8),
uvector3(-0.8, -0.8, 0.8),
uvector3(-0.8, 0.8, -0.8),
uvector3(-0.8, 0.8, 0.8),
uvector3(0.8, -0.8, -0.8),
uvector3(0.8, -0.8, 0.8),
uvector3(0.8, 0.8, -0.8),
uvector3(0.8, 0.8, 0.8)
std::vector<uvector3> vertices = {uvector3(-0.8, -0.8, -0.8),
uvector3(-0.8, -0.8, 0.8),
uvector3(-0.8, 0.8, -0.8),
uvector3(-0.8, 0.8, 0.8),
uvector3(0.8, -0.8, -0.8),
uvector3(0.8, -0.8, 0.8),
uvector3(0.8, 0.8, -0.8),
uvector3(0.8, 0.8, 0.8)
};
std::vector<uvector<int, 3>> indixes = {
uvector<int, 3>(2, 1, 0),
uvector<int, 3>(1, 2, 3),
uvector<int, 3>(0, 1, 4),
uvector<int, 3>(4, 1, 5),
uvector<int, 3>(6, 2, 0),
uvector<int, 3>(6, 0, 4),
uvector<int, 3>(0, 3, 2),
uvector<int, 3>(0, 2, 6),
uvector<int, 3>(1, 3, 7),
uvector<int, 3>(1, 7, 5),
uvector<int, 3>(5, 7, 6),
uvector<int, 3>(4, 5, 6),
};
std::vector<int> indices = {2, 3, 1, 0, // force break here
4, 0, 1, 5, //
4, 6, 2, 0, //
6, 7, 3, 2, //
7, 6, 4, 5, //
3, 7, 5, 1};
std::vector<int> scan = {4, 8, 12, 16, 20, 24};
// ps.emplace_back(std::make_shared<PowerTensorComplex>(makeMesh(vertices, indixes)));
// ps.emplace_back(std::make_shared<PowerTensor>(makeSphere(0.2)));
auto phi0 = std::make_shared<PowerTensorComplex>(makeMesh(vertices, indixes));
phi0->add(*std::make_shared<PowerTensor>(makeSphere(0.2)));
auto basicTask = BasicTask(phi0);
// ps.emplace_back(std::make_shared<MeshDesc>(MeshDesc(vertices, indices, scan)));
// auto basicTask = BasicTask(ps);
}
void case1()
{
auto phi0 = std::make_shared<PowerTensor>(makeSphere(0.2));
auto phi0 = std::make_shared<SphereDesc>(SphereDesc(0.8, 0., 1.));
// SphereDesc sphere(0.8, 0., 1.);
auto basicTask = BasicTask(phi0);
}

Loading…
Cancel
Save