Exemple #1
0
double IFunctional::fx(const DoubleVector &pv) const
{
    IFunctional* ifunc = const_cast<IFunctional*>(this);

    ifunc->fromVector(pv, ifunc->mParameter);
    //functional->mParameter.fromVector(prms);
    ifunc->forward->setParameter(mParameter);
    ifunc->backward->setParameter(mParameter);

    DoubleMatrix u;
    vector<ExtendedSpaceNode2D> info;
    ifunc->forward->calculateMVD(u, info, true);

    double intgrl = integral(u);

    u.clear();

    return intgrl + regEpsilon*norm() + r*penalty(info);
}
Exemple #2
0
void BackwardParabolicIBVP::gridMethod(DoubleMatrix &p, SweepMethodDirection direction) const
{
    typedef void (*t_algorithm)(const double*, const double*, const double*, const double*, double*, unsigned int);
    t_algorithm algorithm = &tomasAlgorithm;
    if (direction == ForwardSweep) algorithm = &tomasAlgorithmL2R;
    if (direction == BackwardSweep) algorithm = &tomasAlgorithmR2L;

    Dimension time = mtimeDimension;
    Dimension dim1 = mspaceDimension.at(0);

    double ht = time.step();
    unsigned int minM = time.min();
    unsigned int maxM = time.max();
    unsigned int M = maxM-minM;

    double hx = dim1.step();
    unsigned int minN = dim1.min();
    unsigned int maxN = dim1.max();
    unsigned int N = maxN-minN;

    double h = ht/(hx*hx);

    p.clear();
    p.resize(M+1, N+1);

    double *ka = (double*) malloc(sizeof(double)*(N-1));
    double *kb = (double*) malloc(sizeof(double)*(N-1));
    double *kc = (double*) malloc(sizeof(double)*(N-1));
    double *kd = (double*) malloc(sizeof(double)*(N-1));
    double *rx = (double*) malloc(sizeof(double)*(N-1));

    /* initial condition */
    SpaceNodePDE isn;
    for (unsigned int n=0; n<=N; n++)
    {
        isn.i = n+minN;
        isn.x = isn.i*hx;
        p[M][n] = initial(isn);
    }
    layerInfo(p, M);

    SpaceNodePDE lsn;
    lsn.i = minN;
    lsn.x = minN*hx;

    SpaceNodePDE rsn;
    rsn.i = maxN;
    rsn.x = maxN*hx;

    TimeNodePDE tn;
    for (unsigned int m=M-1; m!=UINT32_MAX; m--)
    {
        tn.i = m+minM;
        tn.t = tn.i*ht;

        for (unsigned int n=1; n<=N-1; n++)
        {
            isn.i = n+minN;
            isn.x = isn.i*hx;

            double alpha = -a(isn,tn)*h;
            double betta = 1.0 - 2.0*alpha;

            ka[n-1] = alpha;
            kb[n-1] = betta;
            kc[n-1] = alpha;
            kd[n-1] = p[m+1][n] - ht * f(isn, tn);
        }

        ka[0]   = 0.0;
        kc[N-2] = 0.0;

        /* border conditions */
        p[m][0] = boundary(lsn, tn);
        p[m][N] = boundary(rsn, tn);

        kd[0]   += a(lsn,tn) * h * p[m][0];
        kd[N-2] += a(rsn,tn) * h * p[m][N];

        (*algorithm)(ka, kb, kc, kd, rx, N-1);

        for (unsigned int n=1; n<=N-1; n++) p[m][n] = rx[n-1];

        layerInfo(p, m);
    }

    free(ka);
    free(kb);
    free(kc);
    free(kd);
    free(rx);
}
Exemple #3
0
void DiscreteHeat::calculateP(const DoubleVector &f, const DoubleVector &u, DoubleMatrix &psi, DoubleVector &g)
{
    C_UNUSED(f);
    C_UNUSED(g);

    double lamda = -(a*ht)/(hx*hx);
    double k = 1.0-2.0*lamda;

    psi.clear();
    psi.resize(M+1, N+1);

    DoubleVector a1(N-1);
    DoubleVector b1(N-1);
    DoubleVector c1(N-1);
    DoubleVector d1(N-1);
    DoubleVector x1(N-1);

    for (unsigned int m=0; m<=M; m++)
    {
        unsigned int j = M-m;

        if (j==M)
        {
            for (unsigned int i=1; i<=N-1; i++)
            {
                a1[i-1] = lamda;
                b1[i-1] = k;
                c1[i-1] = lamda;
                d1[i-1] = -2.0*hx*(u[i]-U[i]);
            }
            a1[0]   = 0.0;
            c1[N-2] = 0.0;
            tomasAlgorithm(a1.data(), b1.data(), c1.data(), d1.data(), x1.data(), x1.size());

            for (unsigned int i=1; i<=N-1; i++)
            {
                psi[j][i] = x1[i-1];
            }
            psi[j][0] = -lamda*psi[j][1]   -2.0*hx*0.5*(u[0]-U[0]);
            psi[j][N] = -lamda*psi[j][N-1] -2.0*hx*0.5*(u[N]-U[N]);
        }
        else if (j==0)
        {
            psi[j][0] = -lamda*psi[j][1];
            psi[j][N] = -lamda*psi[j][N-1];

            for (unsigned int i=1; i<=N-1; i++)
            {
                psi[j][i] = psi[j+1][i];
            }
        }
        else
        {
            for (unsigned int i=1; i<=N-1; i++)
            {
                a1[i-1] = lamda;
                b1[i-1] = k;
                c1[i-1] = lamda;
                d1[i-1] = +psi[j+1][i];
            }
            a1[0]   = 0.0;
            c1[N-2] = 0.0;
            tomasAlgorithm(a1.data(), b1.data(), c1.data(), d1.data(), x1.data(), x1.size());

            for (unsigned int i=1; i<=N-1; i++)
            {
                psi[j][i] = x1[i-1];
            }
            psi[j][0] = -lamda*psi[j][1];
            psi[j][N] = -lamda*psi[j][N-1];
        }
    }
    a1.clear();
    b1.clear();
    c1.clear();
    d1.clear();
    x1.clear();
}