| 
						
						
						
					 | 
					@ -1,9 +1,11 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#pragma once | 
					 | 
					 | 
					#pragma once | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include <cassert> | 
					 | 
					 | 
					#include <cassert> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					#include <cstddef> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include <vector> | 
					 | 
					 | 
					#include <vector> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "iostream" | 
					 | 
					 | 
					#include "iostream" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "multiloop.hpp" | 
					 | 
					 | 
					#include "multiloop.hpp" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "polyset.hpp" | 
					 | 
					 | 
					#include "polyset.hpp" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					#include "sparkstack.hpp" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "uvector.hpp" | 
					 | 
					 | 
					#include "uvector.hpp" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "real.hpp" | 
					 | 
					 | 
					#include "real.hpp" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "xarray.hpp" | 
					 | 
					 | 
					#include "xarray.hpp" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -136,33 +138,61 @@ real evalBernstein(const xarray<real, N>& phi, const uvector<real, N>& x) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class PowerTensor : public Primitive | 
					 | 
					 | 
					class PowerTensor : public Primitive | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					public: | 
					 | 
					 | 
					public: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    xarray<real, 3> tensor; | 
					 | 
					 | 
					    xarray<real, 3>   tensor; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    SparkStack<real>* sparkStackPtr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    void print() override { std::cout << "Power" << std::endl; } | 
					 | 
					 | 
					    void print() override { std::cout << "Power" << std::endl; } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    real eval(uvector3 p) override { return evalPower(tensor, p); } | 
					 | 
					 | 
					    real eval(uvector3 p) override { return evalPower(tensor, p); } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    PowerTensor() {} | 
					 | 
					 | 
					    // PowerTensor() {}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    PowerTensor(uvector<int, 3> ext_) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        tensor.ext_   = ext_; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        tensor.data_  = nullptr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        sparkStackPtr = algoim_spark_alloc_heap(real, tensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        xarrayInit(tensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    // PowerTensor(xarray<real, 3> t_) : tensor(t_) {}
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    PowerTensor(xarray<real, 3> t_) : tensor(t_) {} | 
					 | 
					 | 
					    ~PowerTensor() | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (sparkStackPtr) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            sparkStackPtr = nullptr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            algoim_spark_release_heap(sparkStackPtr); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					}; | 
					 | 
					 | 
					}; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class PowerTensorComplex : public Primitive | 
					 | 
					 | 
					class PowerTensorComplex : public Primitive | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					public: | 
					 | 
					 | 
					public: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    xarray<real, 3>              compositeTensor; // 复合后的张量
 | 
					 | 
					 | 
					    xarray<real, 3>          compositeTensor; // 复合后的张量
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
					 | 
					 | 
					    SparkStack<real>*        sparkStackPtr; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    // std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    std::vector<PowerTensor> tensors; // 原始张量
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    void print() override { std::cout << "PowerTensorComplex" << std::endl; } | 
					 | 
					 | 
					    void print() override { std::cout << "PowerTensorComplex" << std::endl; } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    PowerTensorComplex() {} | 
					 | 
					 | 
					    // PowerTensorComplex() {}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_) : tensors(ts_) | 
					 | 
					 | 
					    PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_) : tensors(ts_) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    { | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        uvector3 ext(1, 1, 1); | 
					 | 
					 | 
					        uvector3 ext(1, 1, 1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for (auto& t : ts_) { ext += t.ext() - 1; } | 
					 | 
					 | 
					        for (auto& t : ts_) { ext += t.ext() - 1; } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        compositeTensor.ext_ = ext; | 
					 | 
					 | 
					        compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        algoim_spark_alloc(real, compositeTensor); | 
					 | 
					 | 
					        sparkStackPtr        = algoim_spark_alloc_heap(real, compositeTensor); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    PowerTensorComplex(const std::vector<PowerTensor>& pts_) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        uvector3 ext(1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        for (auto& pt : pts_) { ext += pt.tensor.ext() - 1; } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        sparkStackPtr        = algoim_spark_alloc_heap(real, compositeTensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
					 | 
					 | 
					        detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -178,7 +208,7 @@ public: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            ext += pc.compositeTensor.ext() - 1; | 
					 | 
					 | 
					            ext += pc.compositeTensor.ext() - 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        compositeTensor.ext_ = ext; | 
					 | 
					 | 
					        compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        algoim_spark_alloc(real, compositeTensor); | 
					 | 
					 | 
					        sparkStackPtr        = algoim_spark_alloc_heap(real, compositeTensor); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        detail::compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
					 | 
					 | 
					        detail::compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -211,26 +241,27 @@ public: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					PowerTensorComplex makeMesh(const std::vector<uvector3>& vertices, const std::vector<uvector<int, 3>>& indices) | 
					 | 
					 | 
					PowerTensorComplex makeMesh(const std::vector<uvector3>& vertices, const std::vector<uvector<int, 3>>& indices) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    PowerTensorComplex pc; | 
					 | 
					 | 
					    uvector3                 ext(1 + indices.size()); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    uvector3           ext(1, 1, 1); | 
					 | 
					 | 
					    // PowerTensorComplex pc(ext);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    std::vector<PowerTensor> pts; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (const auto& index : indices) { | 
					 | 
					 | 
					    for (const auto& index : indices) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        xarray<real, 3> tensor(nullptr, uvector3(2)); // 最高1次
 | 
					 | 
					 | 
					        // xarray<real, 3> tensor(nullptr, ); // 最高1次
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        algoim_spark_alloc(real, tensor); | 
					 | 
					 | 
					        // algoim_spark_alloc(real, tensor);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        xarrayInit(tensor); | 
					 | 
					 | 
					        PowerTensor pt(uvector3(2)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        uvector3 V01                 = vertices[index(1)] - vertices[index(0)]; | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        uvector3 V02                 = vertices[index(2)] - vertices[index(0)]; | 
					 | 
					 | 
					        uvector3 V01                    = vertices[index(1)] - vertices[index(0)]; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        uvector3 N                   = cross(V01, V02); | 
					 | 
					 | 
					        uvector3 V02                    = vertices[index(2)] - vertices[index(0)]; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        N                           /= norm(N); | 
					 | 
					 | 
					        uvector3 N                      = cross(V01, V02); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        real d                       = -dot(N, vertices[index(0)]); | 
					 | 
					 | 
					        N                              /= norm(N); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        real d                          = -dot(N, vertices[index(0)]); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        // 法线所指方向为>0区域
 | 
					 | 
					 | 
					        // 法线所指方向为>0区域
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        tensor.m(uvector3(0, 0, 0))  = d; | 
					 | 
					 | 
					        pt.tensor.m(uvector3(0, 0, 0))  = d; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        tensor.m(uvector3(1, 0, 0))  = N(0); | 
					 | 
					 | 
					        pt.tensor.m(uvector3(1, 0, 0))  = N(0); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        tensor.m(uvector3(0, 1, 0))  = N(1); | 
					 | 
					 | 
					        pt.tensor.m(uvector3(0, 1, 0))  = N(1); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        tensor.m(uvector3(0, 0, 1))  = N(2); | 
					 | 
					 | 
					        pt.tensor.m(uvector3(0, 0, 1))  = N(2); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        pc.tensors.push_back(tensor); | 
					 | 
					 | 
					        pts.push_back(pt); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					        ext += tensor.ext() - 1; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					    PowerTensorComplex pc(pts); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    pc.compositeTensor.ext_ = ext; | 
					 | 
					 | 
					    pc.compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    algoim_spark_alloc(real, pc.compositeTensor); | 
					 | 
					 | 
					    algoim_spark_alloc(real, pc.compositeTensor); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    detail::compositePower(pc.tensors, 0, 0, 1, pc.compositeTensor); | 
					 | 
					 | 
					    detail::compositePower(pc.tensors, 0, 0, 1, pc.compositeTensor); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -239,11 +270,8 @@ PowerTensorComplex makeMesh(const std::vector<uvector3>& vertices, const std::ve | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					PowerTensor makeSphere(const real r, const uvector3& c = 0, const uvector3& a = 1) | 
					 | 
					 | 
					PowerTensor makeSphere(const real r, const uvector3& c = 0, const uvector3& a = 1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    PowerTensor     pt; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    uvector<int, 3> ext = 3; | 
					 | 
					 | 
					    uvector<int, 3> ext = 3; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    pt.tensor.ext_      = ext; | 
					 | 
					 | 
					    PowerTensor     pt(ext); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					    algoim_spark_alloc(real, pt.tensor); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    xarrayInit(pt.tensor); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (int dim = 0; dim < 3; ++dim) { | 
					 | 
					 | 
					    for (int dim = 0; dim < 3; ++dim) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        uvector<int, 3> idx  = 0; | 
					 | 
					 | 
					        uvector<int, 3> idx  = 0; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -259,9 +287,9 @@ PowerTensor makeSphere(const real r, const uvector3& c = 0, const uvector3& a = | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					PowerTensor makeCylinder(uvector3 startPt, uvector3 endPt, real r) | 
					 | 
					 | 
					PowerTensor makeCylinder(uvector3 startPt, uvector3 endPt, real r) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    PowerTensor pt; | 
					 | 
					 | 
					    // PowerTensor pt;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    // TODO:
 | 
					 | 
					 | 
					    // TODO:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    return pt; | 
					 | 
					 | 
					    return PowerTensor({}); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class BernsteinPrimitive : public Primitive | 
					 | 
					 | 
					class BernsteinPrimitive : public Primitive | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |