コード例 #1
0
void approximatedNormals(const pointSet& mesh, vector<int> neighb, int pnb, double& nx_out, double& ny_out)
{

    if (mesh.getBND(pnb)==0)
        throw mfpmExcept(0);

    int NP = neighb.size();
    double sl2 = mesh.getSL(pnb);


    // New approach
    double sumX = 0, sumY = 0;
    double nx, ny;
    int count = 0;
    for (int i=0; i<NP; i++)
    {
        if (pnb!=neighb[i] )
        {
            nx = (mesh.y(pnb)-mesh.y(neighb[i]));
            ny = -(mesh.x(pnb)-mesh.x(neighb[i]));
            double weight = exp(-5.0* (nx*nx+ny*ny) / sl2);

            double length = sqrt(nx*nx+ny*ny);
            nx /= length;
            ny /= length;
            if ( nx*mesh.getNormal(0,pnb) + ny*mesh.getNormal(1,pnb) < 0)
            {
                nx *= -1.0;
                ny *= -1.0;
            }
            sumX += nx*weight;
            sumY += ny*weight;
        }
    }
    sumX /= NP-1;
    sumY /= NP-1;
    double length = sqrt(sumX*sumX+sumY*sumY);
    if (length==0)
        throw mfpmExcept(1000);
    nx_out = sumX / length;
    ny_out = sumY / length;


}
コード例 #2
0
int partialNeumannMatEntry(const pointSet& mesh, int pnb, const Array& active, Array& entries, bool forceLowOrder)
{
    int NP = mesh.getNIDX(pnb);
    double b[NP];
    double A[6*NP];
    double weight[NP];
    int arrayEntry[NP];

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

    double sl2 = pow(mesh.getSL(pnb),2);

    b[0] = 0*3.0 / mesh.getSL(pnb);
    b[1] = 0.0;
    b[2] = mesh.getNormal(0,pnb);
    b[3] = mesh.getNormal(1,pnb);
    b[4] = 0.0;
    b[5] = 0.0;
    b[6] = 0.0;
    int orderFac = 6;
    if (NP<6 | forceLowOrder)
        orderFac = 4;

    int idx, mi;
    int diagEntry=0;
    double h, k;
    int cnt = 0;
    // Store matrix in Fortran format
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        mi = orderFac*cnt;
        if (idx!=pnb)
        {
            if (active(i) > 0.5)
            {
                h = mesh.x(idx) - mesh.x(pnb);
                k = mesh.y(idx) - mesh.y(pnb);
                weight[cnt] = exp(-2.0 * (h*h+k*k)/sl2 );
                A[mi+0] = 0.0;
                A[mi+1] = 1.0 * weight[cnt];
                A[mi+2] = h   * weight[cnt];
                A[mi+3] = k   * weight[cnt];
                if (orderFac>4)
                {
                    A[mi+4] = h*h * weight[cnt];
                    A[mi+5] = h*k * weight[cnt];
                    A[mi+6] = k*k * weight[cnt];
                }
                arrayEntry[cnt] = i;
                cnt++;
            }
        }
        else
        {
            weight[cnt] = 1.0;
            A[mi+0] = 1.0;
            A[mi+1] = 1.0;
            A[mi+2] = 0.0;
            A[mi+3] = 0.0;
            if (orderFac>4)
            {
                A[mi+4] = 0.0;
                A[mi+5] = 0.0;
            }
            arrayEntry[cnt] = i;
            cnt++;
        }
    }

    int n = orderFac;
    int m = cnt;
    double work[2*(m+n)];
    int info, workl = 2*(m+n);
    int one = 1;
    char TN[] ="N";


    dgels_(TN, &n, &m, &one, A, &n, b, &m, work, &workl, &info);

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

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


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

    return 0;

}
コード例 #3
0
int neumannMatEntry(const pointSet& mesh, int pnb, Array& entries, bool forceLowOrder)
{
    int NP = mesh.getNIDX(pnb);
    double b[NP];
    double A[6*NP];
    double weight[NP];

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

    double sl2 = pow(mesh.getSL(pnb),2);

    b[0] = 3.0 / mesh.getSL(pnb);
    b[1] = 0.0;
    b[2] = mesh.getNormal(0,pnb);
    b[3] = mesh.getNormal(1,pnb);
    b[4] = 0.0;
    b[5] = 0.0;
    int orderFac = 6;
    if (NP<6 | forceLowOrder)
        orderFac = 4;

    int idx, mi;
    int diagEntry=0;
    double h, k;
    // Store matrix in Fortran format
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        mi = orderFac*i;
        if (idx!=pnb)
        {
            h = mesh.x(idx) - mesh.x(pnb);
            k = mesh.y(idx) - mesh.y(pnb);
            weight[i] = exp(-2.0 * (h*h+k*k)/sl2 );
            A[mi+0] = 0.0;
            A[mi+1] = 1.0 * weight[i];
            A[mi+2] = h   * weight[i];
            A[mi+3] = k   * weight[i];
            if (orderFac>4)
            {
                A[mi+4] = h*h * weight[i];
                A[mi+5] = k*k * weight[i];
            }
        }
        else
        {
            diagEntry = i;
            weight[i] = 1.0;
            A[mi+0] = 1.0;
            A[mi+1] = 1.0;
            A[mi+2] = 0.0;
            A[mi+3] = 0.0;
            if (orderFac>4)
            {
                A[mi+4] = 0.0;
                A[mi+5] = 0.0;
            }
        }
    }

    int n = orderFac;
    int m = NP;
    double work[m+n];
    int info, workl = m+n;
    int one = 1;
    char TN[] ="N";
    dgels_(TN, &n, &m, &one, A, &n, b, &m, work, &workl, &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 tmp = entries(diagEntry);
    for (int i=0; i<NP; i++)
    {
        if (abs(entries(i))>tmp)
        {
            //cout << "Invalid Neumann matrix entries!!" << endl;
            //return -1;
        }
    }
    double sum = 0;
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        sum += entries(i)*(mesh.x(idx)+mesh.y(idx));
    }
    if ( (sum - mesh.getNormal(0,pnb) - mesh.getNormal(1,pnb)) > 1e-7 )
    {
        //cout << "Invalid Neumann matrix entries!!" << endl;
        return -2;
    }

    return 0;

}