| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -6,10 +6,65 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <iostream> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <iomanip> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <fstream> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <vector> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "quadrature_multipoly.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "vector" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using namespace algoim; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const static std::vector<std::vector<real>> binomial_table = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 0, 0, 0, 0, 0, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 1, 0, 0, 0, 0, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 2, 1, 0, 0, 0, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 3, 3, 1, 0, 0, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 4, 6, 4, 1, 0, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 5, 10, 10, 5, 1, 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    {1, 6, 15, 20, 15, 6, 1} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// function模板不允许直接<部分>特化,所以用类模板
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template<int N> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct DebugXArray { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						template<typename Phi> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						void operator()(const xarray<real, N>& iData, Phi&& phi) {	 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template<> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct DebugXArray<2>{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						template<typename Phi> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						void operator()(const xarray<real, 2>& iData, Phi&& phi) {	 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								std::vector<std::vector<real>> data(iData.ext(0), std::vector<real>(iData.ext(1))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for (int i = 0; i < iData.ext(0); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									for (int j = 0; j < iData.ext(1); ++j) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										data[i][j] = iData(i, j); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								real inputX1 = 0.2, inputX2 = 0.3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								std::vector<real> b1(iData.ext(0)), b2(iData.ext(1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								int n1 = iData.ext(0) - 1, n2 = iData.ext(1) - 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								real res = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for (int i = 0; i < iData.ext(0); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										b1[i] = binomial_table[n1][i] * std::pow(inputX1, i) * std::pow(1 - inputX1, n1-i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for (int i = 0; i < iData.ext(1); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										b2[i] = binomial_table[n2][i] * std::pow(inputX2, i) * std::pow(1 - inputX2, n2-i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for (int i = 0; i < iData.ext(0); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									real tmp = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									for (int j = 0; j < iData.ext(1); j++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										tmp += data[i][j] * b2[j]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									res += tmp * b1[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// original phi function evaluation
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								const uvector<real,2> x(inputX1, inputX2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								real phiEval = phi(x); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// Driver method which takes a functor phi defining a single polynomial in the reference
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// rectangle [xmin, xmax]^N, of Bernstein degree P, along with an integrand function,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// and performances a q-refinement convergence study, comparing the computed integral
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -21,6 +76,7 @@ void qConv(const Phi& phi, real xmin, real xmax, uvector<int,N> P, const F& inte | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    xarray<real,N> phipoly(nullptr, P); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    algoim_spark_alloc(real, phipoly); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bernstein::bernsteinInterpolate<N>([&](const uvector<real,N>& x) { return phi(xmin + x * (xmax - xmin)); }, phipoly); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							DebugXArray<N>()(phipoly, [&](const uvector<real,N>& x) { return phi(xmin + x * (xmax - xmin)); }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Build quadrature hierarchy
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ImplicitPolyQuadrature<N> ipquad(phipoly); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -169,7 +225,7 @@ int main(int argc, char* argv[]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::cout << std::scientific << std::setprecision(10); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // q-convergence study for a 2D ellipse
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (false) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto ellipse = [](const uvector<real,2>& x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return x(0)*x(0) + x(1)*x(1)*4 - 1; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -186,7 +242,7 @@ int main(int argc, char* argv[]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // q-convergence study for a 3D ellipsoid
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (false) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto ellipsoid = [](const uvector<real,3>& x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return x(0)*x(0) + x(1)*x(1)*4 + x(2)*x(2)*9 - 1; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -204,7 +260,7 @@ int main(int argc, char* argv[]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Visusalisation of a 2D case involving a single polynomial; this example corresponds to
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Figure 3, row 3, left column, https://doi.org/10.1016/j.jcp.2021.110720
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (false) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto phi = [](const uvector<real,2>& xx) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            real x = xx(0)*2 - 1; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -221,7 +277,7 @@ int main(int argc, char* argv[]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Visusalisation of a 3D case involving a single polynomial; this example corresponds to
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Figure 3, row 3, right column, https://doi.org/10.1016/j.jcp.2021.110720
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (false){ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto phi = [](const uvector<real,3>& xx) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            real x = xx(0)*2 - 1; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |