diff --git a/ConSol/ConSol/Reconstr/InterpolationBase/Multiquadratics_2D_WENO_b.cpp b/ConSol/ConSol/Reconstr/InterpolationBase/Multiquadratics_2D_WENO_b.cpp index 728f728..a5643b6 100644 --- a/ConSol/ConSol/Reconstr/InterpolationBase/Multiquadratics_2D_WENO_b.cpp +++ b/ConSol/ConSol/Reconstr/InterpolationBase/Multiquadratics_2D_WENO_b.cpp @@ -1,318 +1,318 @@ // // Created by Fabian Moenkeberg on 2020-02-04. // #include "Multiquadratics_2D_WENO_b.hpp" #include "cblas.h" Multiquadratics_2D_WENO_b::Multiquadratics_2D_WENO_b(int order, double eps){ this->order = order; this->order_scheme = 2*((order+1)/2 + (order+1)%2); this->shapeParam = eps; this->dim = 2; this->degPoly = order -1; this->name = MULTIQUADS; setMulti_Index(degPoly+1); } Multiquadratics_2D_WENO_b::Multiquadratics_2D_WENO_b(int order, int degPoly, double eps){ this->order = 1; // this->order_scheme = 2*((order+1)/2 + (order+1)%2); this->order_scheme = order+1; this->shapeParam = eps; this->dim = 2; this->degPoly = degPoly; this->name = MULTIQUADS; setMulti_Index(degPoly+1); } std::vector Multiquadratics_2D_WENO_b::evaluate(std::vector> evPoints, MeshBase *mesh, std::vector> stencil, std::vector> values){ int nStencils = (int) stencil.size(); int nStencil; double rad = 0; for (int i = 0; i < nStencils; i++){ rad = std::max(stableRad / mesh->getApproxStencilSize(stencil[i]), rad); } double eps0 = 0.1/rad; double eps = rad; int nEv = (int) evPoints.size(); std::vector smInd(nStencils); std::vector> ret(nStencils, std::vector(nEv,0)); std::vector res(nEv,0); std::vector> coeff(nStencils); std::vector nP_old(nStencils); std::vector nRbf_old(nStencils); // values[1][2] = 100; // if (nStencils == 4){ // std::cout << "test"; // } for (int ii = 0; ii < nStencils; ii++){ nStencil = stencil[ii].size(); std::vector>> xB(nStencil,std::vector>(NODE_NUM, std::vector(2))); std::vector> xi(NODE_NUM,std::vector(2)); for (int i = 0; i < nStencil; i++){ xi = mesh->getXCoord(mesh->getCells(stencil[ii][i])); xB[i] = xi; } int nRbf = (int) xB.size(); std::vector coeff_old; int nRbf0 = std::min((int) xB.size(),3); // int nRbf_old; // int nP_old; std::vector>> xB_; std::vector values_; std::vector values_old; // int degPoly_ = std::max(getDegPoly(nRbf),0); int degPoly_ = std::min(std::max(getDegPoly(nRbf),0),degPoly); std::vector values_tmp; int nP = multi_index.size(); int nP_tmp = 0; int sum_multi_index = multi_index[0][0] + multi_index[0][1]; for (int i = 0; i < nP; i++) { if (multi_index[i][0] + multi_index[i][1] <= degPoly_) { nP_tmp++; } } nP = nP_tmp; values_ = values[ii]; xB_ = xB; int m = nRbf + nP; int approxOrder = std::min(degPoly_ + 1, order); // std::vector values_tmp = values_; getInterpCoeff(xB_, values_, eps, nP, approxOrder); // getInterpCoeff(xB_, values_tmp, eps, nP, approxOrder); // getInterpCoeff(xB_, values_tmp, eps, 1, 1); values_tmp = values_; if (ii > 0 && ii < nStencils-1){ for ( int i = 0; i < nRbf_old[0]; i++){ values_tmp[i] -= coeff[0][i]; } for ( int i = 0; i < nP_old[0]; i++){ values_tmp[i + nRbf] -= coeff[0][i + nRbf_old[0]]; } }else if (ii == nStencils-1){ int n0 = 0; for ( int i = 0; i < nRbf_old[0]; i++){ values_tmp[i] -= coeff[0][i]; } for ( int i = 0; i < nP_old[0]; i++){ values_tmp[i + nRbf] -= coeff[0][i + nRbf_old[0]]; } for (int i = 1; i < nStencils-1; i++){ values_tmp[0] -= coeff[i][0]; for (int j = 1; j < nRbf_old[i]; j++){ values_tmp[n0 + j] -= coeff[i][j]; } n0 += nRbf_old[i]-1; for ( int j = 0; j < nP_old[i]; j++){ values_tmp[j + nRbf] -= coeff[i][j + nRbf_old[i]]; } } } coeff[ii] = values_tmp; std::vector> EvA0(nEv, std::vector(nRbf)); MVEvaluationMatrix(evPoints, xB_, eps, EvA0, approxOrder); std::vector> PA(nEv, std::vector(nP)); MVPolynomialEvaluationMatrixV(evPoints, xB_, PA, eps, nP); double *EvA = new double[nEv * m]; for (int i = 0; i < nEv; i++) { for (int j = 0; j < nRbf; j++) { EvA[i + j * nEv] = EvA0[i][j]; } for (int j = 0; j < nP; j++) { EvA[i + (j + nRbf) * nEv] = PA[i][j]; } } if (nRbf > 1){ smInd[ii] = my_pow(ptwiseSmInd(xB[0], xB_, values_tmp, eps),1); }else{ // double a1,a2,a3,b1,b2,b3; // if (degPolyMax_>0){ // for (int i = 0; i < 3; i++){ // // } // } smInd[0] = 1; // double d = std::sqrt(std::fabs(calcSize(xB[0]))); // double tmp = 0; // double sum_tt = 0; // std::vectora(3); // std::vectortt(3); // for (int jj = 1; jj <= nRbf0; jj++){ // a[jj-1] = (values[jj] - values[0])/d; // } // double tmp2 = (std::fabs(a[1]-a[0]) + std::fabs(a[2]-a[0]) + std::fabs(a[1]-a[2]))/3; // for (int jj = 0; jj < nRbf0; jj++){ // tt[jj] = (1 + tmp2*tmp2/(1e-10 + a[jj]))/3; // sum_tt += tt[jj]; // } // for (int jj = 0; jj < nRbf0; jj++){ // tmp += my_pow(tt[jj]/sum_tt*a[jj],2); // } // tmp = tmp*std::sqrt(std::abs(calcSize(xB[0]))); // smInd[0] = tmp; } double *sVecPt = values_tmp.data(); double *y = new double[nEv]; cblas_dgemv(CblasColMajor, CBLAS_TRANSPOSE::CblasNoTrans, (int) nEv, (int) (nRbf + nP), 1.0, EvA, (int) nEv, sVecPt, 1, 0.0, y, (int) 1); for (int i = 0; i < nEv; i++){ ret[ii][i] = y[i]; } nP_old[ii] = nP; nRbf_old[ii] = nRbf; delete[] y; delete[] EvA; } for (int i = 1; i < nStencils; i++){ smInd[i] = 1/my_pow(eps0 + my_pow(10,i)*smInd[i] + smInd[0],2); } smInd[0] = 1/my_pow(eps0 + smInd[0] ,2); // double sum_smInd = 0; // for ( int i = 0; i <= nStencils; i++){ // sum_smInd += smInd[i]; // } for (int i = 1; i <= nStencils; i++){ smInd[nStencils-i] /=(smInd[0]); } for ( int j = 0; j < nStencils; j++){ for (int i = 0; i < nEv; i++){ res[i] += ret[j][i]*smInd[j]; } } // if (smInd[nStencils-1]>smInd[0]){ // std::cout << "test"; // } // for (int i = 0; i < nStencils; i++){ // std::cout << smInd[i] << ", "; // } // std::cout << "\n"; return res; } std::vector Multiquadratics_2D_WENO_b::evaluateDirect(std::vector> evPoints, std::vector>> xB, std::vector values, double eps, double rad){ std::vector res(0,0); return res; } double Multiquadratics_2D_WENO_b::ptwiseSmInd(std::vector> xBi, std::vector>> xB, std::vector values, double eps){ int nRbf = (int) xB.size(); int degPoly_ = std::min(std::max(getDegPoly(nRbf),0),degPoly); double Ind = 0; // double s = 0; // double p = 1; // double dist = 0; std::vector xM(2, 0.0); xM[0] = (xBi[0][0] + xBi[1][0] + xBi[2][0])/(double)NODE_NUM; xM[1] = (xBi[0][1] + xBi[1][1] + xBi[2][1])/(double)NODE_NUM; // double delta; // double d_0, d_1; for (int i = 0; i < nRbf;i++){ // Ind += std::pow(values[i],2); // delta = eps*std::sqrt(calcSize(xB[i])); Ind += values[i]*values[i]; // p *= delta*delta; // s += delta*delta; // d_0 = xM[0]-calcMidPt(xB[i],0); // d_1 = xM[1]-calcMidPt(xB[i],1); // dist += eps*std::sqrt(d_0*d_0 + d_1*d_1); } // Ind = Ind*p*p/(s*s); // Ind = 0; // double delta0 = std::sqrt(calcSize(xBi)); double delta0 = (calcSize(xBi)); Ind*= delta0*delta0*0; - int j = 1; + int j = degPoly_; for (int j2 = 0; j2 <= j; j2++){ double Ds = 0; double Ds_tmp = 0; for (int i = 0; i < nRbf;i++){ Ds += values[i]*DF(std::vector{eps*(xM[0]-calcMidPt(xB[i],0)),eps*(xM[1]-calcMidPt(xB[i],1))},j2, j-j2, eps); } Ind += (std::pow(my_pow(eps,j)*Ds,2)) *my_pow(delta0,j); } for (int j = 1;j <= degPoly_+1; j++){ // double Ds = 0; // for (int i = 0; i < nRbf;i++){ // Ds += values[i]*DF(std::vector{eps*(xM[0]-calcMidPt(xB[i],0)),eps*(xM[1]-calcMidPt(xB[i],1))},j); // } // Ds += DPolynomial(xM, xB, values, j, values.size() - nRbf, eps); // Ind += std::pow(Ds,2); for (int j2 = 0; j2 <= j; j2++){ double Ds = 0; double Ds_tmp = 0; // for (int i = 0; i < nRbf;i++){ // Ds += values[i]*DF(std::vector{eps*(xM[0]-calcMidPt(xB[i],0)),eps*(xM[1]-calcMidPt(xB[i],1))},j2, j-j2, eps); //// Ds += values[i]*DF(std::vector{eps*(xM[0]),eps*(xM[1])},j2, j-j2, eps); //// Ds_tmp += values[i]*DF(std::vector{eps*(xM[0]-calcMidPt(xB[i],0)),eps*(xM[1]-calcMidPt(xB[i],1))},j2, j-j2, eps); // } // Ds += DPolynomial(xM, xB, values, j2, j-j2, values.size() - nRbf, eps); double Dt = DPolynomial(xM, xB, values, j2, j-j2, values.size() - nRbf, eps); // Ind += (std::pow(my_pow(eps,j)*Ds + Dt,2)) *my_pow(delta0,j); Ind += (std::pow(my_pow(eps,j)*Ds,2) + std::pow(Dt,2)) *my_pow(delta0,j); } } // if (Ind < 0.1){ // std::cout<< Ind; // } // for (int j2 = 0; j2 <= degPoly_; j2++){ // double Ds = 0; // for (int i = 0; i < nRbf;i++){ // Ds += values[i]*DF(std::vector{eps*(xM[0]),eps*(xM[1])},j2, degPoly_-j2, eps); // } //// Ds += DPolynomial(xM, xB, values, j2, degPoly_-j2, values.size() - nRbf, eps); //// double Dt = DPolynomial(xM, xB, values, j2, j-j2, values.size() - nRbf, eps); // Ind += std::pow(Ds,2)*my_pow(delta0,degPoly_); // } // Ind *= dist; return std::fabs(Ind); } int Multiquadratics_2D_WENO_b::getDegPoly(int n){ int degPoly_; if (false){ degPoly_ = 1; }else{ degPoly_ = (int)floor(-1.5+sqrt(1+8*(n-1))/2); } return degPoly_; }