int laplaceOrder4MatEntry(const pointSet& mesh, int pnb, Array& entries)
{
    int nbEq = 15;
    int NP = mesh.getNIDX(pnb);
    double b[NP];
    double A[nbEq*NP];
    double weight[NP];

    if (NP < nbEq)
        throw mfpmExcept(20);

    b[0] = 0.0;		// const
    b[1] = 0.0;		// h
    b[2] = 0.0;		// k
    b[3] = 2.0;		// hh
    b[4] = 2.0;		// kk
    b[5] = 0.0;		// hk

    b[6] = 0.0;		// hhh
    b[7] = 0.0;		// hhk
    b[8] = 0.0;		// hkk
    b[9] = 0.0;		// kkk

    b[10] = 0.0;	// hhhh
    b[11] = 0.0;	// kkkk
    b[12] = 0.0;	// hhhk
    b[13] = 0.0;	// hhkk
    b[14] = 0.0;	// hkkk


    double maxLength = 0;
    for (int i=0; i<NP; i++)
    {
        int idx = mesh.getIDX(pnb,i);
        double dist = mesh.P(pnb).dist(mesh.P(idx));
        if (dist>maxLength)
            maxLength=dist;
    }
    b[3] /= maxLength*maxLength;
    b[4] /= maxLength*maxLength;


    int diagEntry;
    int idx, mi;
    double h, k;
    double sl2 = pow(mesh.getSL(pnb),2);
    // Store matrix in Fortran format
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        mi = nbEq*i;

        h = mesh.x(idx) - mesh.x(pnb);
        k = mesh.y(idx) - mesh.y(pnb);
        weight[i] = exp(-2.0 * (h*h+k*k)/sl2 );

        h /= maxLength;
        k /= maxLength;

        A[mi+0] = 1.0 * weight[i];
        A[mi+1] = h   * weight[i];
        A[mi+2] = k   * weight[i];
        A[mi+3] = h*h * weight[i];
        A[mi+4] = k*k * weight[i];
        A[mi+5] = h*k * weight[i];

        double fac=1.0;
        A[mi+6] = fac*h*h*h * weight[i];
        A[mi+7] = fac*h*h*k * weight[i];
        A[mi+8] = fac*h*k*k * weight[i];
        A[mi+9] = fac*k*k*k * weight[i];

        A[mi+10] = h*h*h*h * weight[i];
        A[mi+11] = k*k*k*k * weight[i];
        A[mi+12] = h*h*h*k * weight[i];
        A[mi+13] = h*h*k*k * weight[i];
        A[mi+14] = h*k*k*k * weight[i];

    }



    int n = nbEq;
    int lda = nbEq;
    int m = NP;
    int jpv[m+n];
    int lwork = 3*(m+n);
    double work[lwork];
    int info;
    int one = 1;
    int rank;
    char TN[] = "N";
    dgels_(TN, &n, &m, &one, A, &lda, b, &m, work, &lwork, &info);


    if (info!=0)
    {
        cout <<  "Error solving least squares: laplaceMatEntry!" << endl;
        throw mfpmExcept(27);
    }

    for (int i=0; i<NP; i++)
    {
        entries(i) = b[i]*weight[i];
    }

    // Test operator:
    double sum = 0;
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        sum += entries(i)*(mesh.x(idx)*mesh.x(idx)+mesh.y(idx)*mesh.y(idx));
    }
    if ( abs(sum - 4.0) > 1e-7 )
    {
        //cout << pnb << "   " << sum << endl;
        return -2;
    }


    return 0;


}
示例#2
0
double bgGridIntegration(const pointSet& mesh, const scalarField& data)
{
	//cout << "Integrating over domain" << endl;
	// Get bounding box
	double xmin, ymin, xmax, ymax;
	mesh.getBoundingBox(xmin, xmax, ymin, ymax);

	// Get smoothing length
	double sl = mesh.getMinSL();
	double h  = 0.15*sl;

	// Calc dimensions
	int nx = (int) ((xmax-xmin)/h)+2;
	int ny = (int) ((ymax-ymin)/h)+2;


	// Build background grid
#ifndef USE_STACK
	vector<point> P;
	P.reserve(nx*ny);
#else
	point P[nx*ny];
#endif
	double val;
	for (int i=0; i<nx; i++)
	{
		for (int j=0; j<ny; j++)
		{
#ifndef USE_STACK
			point pTmp;
			pTmp.X = xmin + i*h;
			pTmp.Y = ymin + j*h;
			P.push_back(pTmp);
#else
			P[i*ny+j].X = xmin + i*h;
			P[i*ny+j].Y = ymin + j*h;
#endif
		}
	}


	// Interpolate scalarField values onto bg grid
	int n = nx*ny;
	int ix, iy;
	double sum = 0;
	for (int i=0; i<n; i++)
	{
		mesh.getQuad(P[i], ix, iy);
		const vector<int>& bndquad = mesh.getQuad(ix, iy, false);
		int bqSize = bndquad.size();
		// Point definitely in / out domain?
		if (bqSize == 0)
		{
			const vector<int>& quad = mesh.getQuad(ix, iy);
			if (quad.size() != 0)
			{
				sum += data.interpolateLS(P[i]);
			}
		}
		// No? Check in/out with normals
		else
		{
			// Find nearest bnd point
			double minDist = 1e100;
			int minPos = -1;
			for (int j=0; j<bqSize; j++)
			{
				if (minDist > mesh.P(bndquad[j]).dist(P[i]))
				{
					minDist = mesh.P(bndquad[j]).dist(P[i]);
					minPos = bndquad[j];
				}
			}
			double vecX = P[i].X - mesh.P(minPos).X;
			double vecY = P[i].Y - mesh.P(minPos).Y;

			double nDir = mesh.P(minPos).Nx*vecX + mesh.P(minPos).Ny*vecY;
			if (nDir <= 0)
			{
				sum += data.interpolateLS(P[i]);
			}
		}
	}

	sum *= h*h;

	return sum;

}