コード例 #1
0
int partialGradMatEntry(const pointSet& mesh, int pnb, const Array& active, Array& gradX, Array& gradY, int order)
{
    int orderFac;
    int NP = mesh.getNIDX(pnb);
    int cntNP = 0;
    for (int i=0; i<NP; i++)
    {
        if (active(i)>0.5)
            cntNP++;
    }

    if (order==1 & cntNP>=4)
        orderFac = 4;
    else if (order==2 & cntNP>=7)
        orderFac = 7;
    else if (order==3 & cntNP>=11)
        orderFac = 11;
    else if (order==4 & cntNP>=16)
        orderFac = 16;
    else
        throw mfpmExcept(20);

    double b[2*NP];
    double A[16*NP];
    double weight[NP];
    int entryArray[NP];

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

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


    int diagEntry;
    int idx, mi, cnt;
    double h, k;
    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 );
                h /= alpha;
                k /= alpha;
                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] = k*k * weight[cnt];
                    A[mi+6] = h*k * weight[cnt];
                }
                entryArray[cnt] = i;
                cnt++;
            }
        }
        else
        {
            diagEntry = i;
            weight[i] = 1.0;
            A[mi+0] = 1.0;
            A[mi+1] = 1.0;
            for (int j=2; j<orderFac; j++)
                A[mi+j] = 0.0;
            entryArray[cnt] = i;
            cnt++;
        }
    }

    // GradX
    b[0] = 0.0;
    b[1] = 0.0;
    b[2] = 1.0 / alpha;
    for (int i=3; i<orderFac; i++)
        b[i] = 0.0;

    // GradY
    b[cnt+0] = 0.0;
    b[cnt+1] = 0.0;
    b[cnt+2] = 0.0;
    b[cnt+3] = 1.0 / alpha;
    for (int i=4; i<orderFac; i++)
        b[cnt+i] = 0.0;

    int n = orderFac;
    int m = cnt;
    int workl = 3*(m+n);
    double work[workl];
    int info;
    int nrhs = 2;
    char TN[] = "N";
    dgels_(TN, &n, &m, &nrhs, A, &n, b, &m, work, &workl, &info);
    cout << "NP: " << cnt << endl;

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

    gradX = 0;
    gradY = 0;
    for (int i=0; i<cnt; i++)
    {
        gradX(entryArray[i]) = b[i]*weight[i];
        gradY(entryArray[i]) = b[cnt+i]*weight[i];
    }

    return 0;



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

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

    b[0] = -10.0 / pow(mesh.getSL(pnb),2);
    b[1] = 0.0;
    b[2] = 0.0;
    b[3] = 0.0;
    b[4] = 2.0;
    b[5] = 2.0;
    b[6] = 0.0;

    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 = 7*i;
        if (idx!=pnb)
        {
            h = mesh.x(idx) - mesh.x(pnb);
            k = mesh.y(idx) - mesh.y(pnb);
            weight[i] = exp(-3.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];
            A[mi+4] = h*h * weight[i];
            A[mi+5] = k*k * weight[i];
            A[mi+6] = h*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;
            A[mi+4] = 0.0;
            A[mi+5] = 0.0;
            A[mi+6] = 0.0;
        }
    }

    int n = 7;
    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];
    }

    //~ // Check for diagonally dominance
    //~ double diagEnt = abs(entries(diagEntry));
    //~ double sumte = 0;
    //~ cout << "Entry: " << pnb << endl;
    //~ for (int i=0; i<NP; i++)
    //~ {
    //~ if ( i != diagEntry )
    //~ {
    //~ sumte += abs(entries(i));
    //~ cout << entries(i) << " ";
    //~ }
    //~ else
    //~ cout << " * " << entries(i) << " * ";
    //~ }
    //~ cout << endl;
    //~ cout << "LAPDiff: " << diagEnt << " > " << sumte << " = " << (sumte < diagEnt) << endl;



    // 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 )
    {
        return -2;
    }

    return 0;


}
コード例 #3
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;

}
コード例 #4
0
int gradMatEntry(const pointSet& mesh, int pnb, Array& gradX, Array& gradY, int order)
{
    int orderFac;
    int NP = mesh.getNIDX(pnb);

    if (order==1 & NP>=4)
        orderFac = 4;
    else if (order==2 & NP>=7)
        orderFac = 7;
    else if (order==3 & NP>=11)
        orderFac = 11;
    else if (order==4 & NP>=16)
        orderFac = 16;
    else
        throw mfpmExcept(20);

    double b[2*NP];
    double A[16*NP];
    double weight[NP];

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

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

    // GradX
    b[0] = 0.0;
    b[1] = 0.0;
    b[2] = 1.0 / alpha;
    for (int i=3; i<orderFac; i++)
        b[i] = 0.0;

    // GradY
    b[NP+0] = 0.0;
    b[NP+1] = 0.0;
    b[NP+2] = 0.0;
    b[NP+3] = 1.0 / alpha;
    for (int i=4; i<orderFac; i++)
        b[NP+i] = 0.0;

    int diagEntry;
    int idx, mi;
    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 );
            h /= alpha;
            k /= alpha;
            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];
                A[mi+6] = h*k * weight[i];
            }
            if (orderFac>7)
            {
                A[mi+7]  = h*h*h *weight[i];
                A[mi+8]  = h*h*k *weight[i];
                A[mi+9]  = h*k*k *weight[i];
                A[mi+10] = k*k*k *weight[i];
            }
            if (orderFac>11)
            {
                A[mi+11] = h*h*h*h *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];
                A[mi+15] = k*k*k*k *weight[i];
            }


        }
        else
        {
            diagEntry = i;
            weight[i] = 1.0;
            A[mi+0] = 1.0;
            A[mi+1] = 1.0;
            for (int i=2; i<orderFac; i++)
                A[mi+i] = 0.0;

        }
    }

    int n = orderFac;
    int m = NP;
    int workl = 3*(m+n);
    double work[workl];
    int info;
    int nrhs = 2;
    char TN[] = "N";
    dgels_(TN, &n, &m, &nrhs, 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++)
    {
        gradX(i) = b[i]*weight[i];
        gradY(i) = b[NP+i]*weight[i];
    }

    // Test operator:
    double sum1 = 0;
    double sum2 = 0;
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        sum1 += gradX(i)*(mesh.x(idx)+mesh.y(idx));
        sum2 += gradY(i)*(mesh.x(idx)+mesh.y(idx));
    }
    if ( (sum1 - 1.0) > 1e-7 )
    {
        return -1;
    }
    if ( (sum2 - 1.0) > 1e-7 )
    {
        return -2;
    }


    return 0;



}
コード例 #5
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;

}
コード例 #6
0
int biLaplaceMatEntry(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] = 0.0;		// hh
    b[4] = 0.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] = 24.0;	// hhhh
    b[11] = 24.0;	// kkkk
    b[12] = 0.0;	// hhhk
    b[13] = 8.0;	// hhkk
    b[14] = 0.0;	// hkkk

    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 );

        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)*(pow(mesh.x(idx),4)+pow(mesh.y(idx),4));
    }
    if ( abs(sum - 48.0) > 1e-7 )
    {
        cout << pnb << "   " << sum << endl;
        return -2;
    }


    return 0;


}
コード例 #7
0
int approximationXYMatEntry(const pointSet& mesh, int pnb, double xp, double yp, Array& entries, int order)
{
    int orderFac = 3;
    int NP = mesh.getNIDX(pnb);
    double b[NP];
    double A[7*NP];
    double weight[NP];
    int arrayEntry[NP];

    if (order == 1)
        orderFac = 3;
    else
        orderFac = 6;

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

    b[0] = 1.0;
    b[1] = 0.0;
    b[2] = 0.0;

    b[3] = 0.0;
    b[4] = 0.0;
    b[5] = 0.0;


    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 = i*orderFac;
        h = mesh.x(idx) - xp;
        k = mesh.y(idx) - yp;
        weight[i] = exp(-3.0 * (h*h+k*k)/sl2 );
        A[mi+0] = 1.0 * weight[i];
        A[mi+1] = h   * weight[i];
        A[mi+2] = k   * weight[i];
        if (orderFac > 3)
        {
            A[mi+3] = h*h   * weight[i];
            A[mi+4] = k*k   * weight[i];
            A[mi+5] = h*k   * weight[i];
        }

    }



    int n = orderFac;
    int m = NP;
    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);
    }

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


    return 0;


}
コード例 #8
0
int divLambdaGradMatEntry(const pointSet& mesh, int pnb, double lambda, double DxLambda, double DyLambda, const Array& larr, Array& entries)
{
    int NP = mesh.getNIDX(pnb);
    double b[NP];
    double A[7*NP];
    double weight[NP];

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

    double nx = DxLambda;
    double ny = DyLambda;
    double nabs = sqrt(nx*nx+ny*ny);
    if ( nabs > 1e-5 )
    {
        nx /= nabs;
        ny /= nabs;
    }
    else
    {
        nx = 1.0;
        ny = 0.0;
    }
    double tx = -ny;
    double ty = nx;

    b[0] = -10 / pow(mesh.getSL(pnb),2);
    b[1] = 0.0;
    b[2] = DxLambda;
    b[3] = DyLambda;
    b[4] = 2.0*lambda;
    b[5] = 2.0*lambda;
    b[6] = 0.0;

    double alphaL = 3.0;
    double alphaR = 10.0;



    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 = 7*i;
        if (idx!=pnb)
        {
            h = mesh.x(idx) - mesh.x(pnb);
            k = mesh.y(idx) - mesh.y(pnb);
            double hN = h*nx + k*ny;
            double hT = h*tx + k*ty;
            weight[i] = exp(-alphaL*hT*hT/sl2 );
            double alpha = alphaL;
            // TODO: Only for particular test case!!!!!
            if ( lambda < 0.1 )
                if ( hN > 0)
                    alpha = alphaR;
                else
                    alpha = alphaL;
            else if (hN > 0)
                alpha = alphaL;
            else
                alpha = alphaR;
            weight[i] *= exp(-alpha*hN*hN/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];
            A[mi+4] = h*h * weight[i];
            A[mi+5] = k*k * weight[i];
            A[mi+6] = h*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;
            A[mi+4] = 0.0;
            A[mi+5] = 0.0;
            A[mi+6] = 0.0;
        }
    }

    int n = 7;
    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];
    }

    // Check for diagonally dominance
    double diagEnt = abs(entries(diagEntry));
    double sum = 0;
    cout << "Entry: " << pnb << endl;
    for (int i=0; i<NP; i++)
    {
        if ( i != diagEntry )
        {
            sum += abs(entries(i));
            cout << entries(i) << " ";
        }
        else
            cout << " * " << entries(i) << " * ";
    }
    cout << endl;
    cout << "Diff: " << diagEnt << " > " << sum << " = " << (sum < diagEnt) << endl;


    return 0;


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

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

    b[0] = -10.0 / pow(mesh.getSL(pnb),2);
    b[1] = 0.0;
    b[2] = 0.0;
    b[3] = 0.0;
    b[4] = 2.0;
    b[5] = 2.0;
    b[6] = 0.0;

    int diagEntry;
    int idx, mi, cnt;
    double h, k;
    double sl2 = pow(mesh.getSL(pnb),2);
    cnt = 0;
    // Store matrix in Fortran format
    for (int i=0; i<NP; i++)
    {
        idx = mesh.getIDX(pnb,i);
        mi = cnt*7;
        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(-3.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];
                A[mi+4] = h*h * weight[cnt];
                A[mi+5] = k*k * weight[cnt];
                A[mi+6] = h*k * weight[cnt];
                arrayEntry[cnt] = i;
                cnt++;
            }
        }
        else
        {
            diagEntry = i;
            weight[cnt] = 1.0;
            A[mi+0] = 1.0;
            A[mi+1] = 1.0;
            A[mi+2] = 0.0;
            A[mi+3] = 0.0;
            A[mi+4] = 0.0;
            A[mi+5] = 0.0;
            A[mi+6] = 0.0;
            arrayEntry[cnt] = i;
            cnt++;
        }
    }

    if (cnt < 7)
        throw mfpmExcept(20);


    int n = 7;
    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);
    }

    for (int i=0; i<cnt; i++)
    {
        entries(arrayEntry[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 )
    //~ {
    //~ return -2;
    //~ }

    return 0;


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

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

    int orderFac = 6;

    b[0] = 1.0;
    b[1] = 0.0;
    b[2] = 0.0;
    if (orderFac > 3)
    {
        b[3] = 0.0;
        b[4] = 0.0;
        b[5] = 0.0;
    }

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

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


    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);
    }

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


    return 0;


}