Распределение Al И O

Тема в разделе "C/C++/C#", создана пользователем -, 14 фев 2012.

Статус темы:
Закрыта.
  1. Гость

    Учусь на металлургии. В си++ не шарю.
    Задача: при различных концентрациях Al и O могут образовываться : глинозем, герценит и шлак. Образование герценита и глинозема решить методом половинного деления, шлак-методом Ньютона. В итоге должна получиться программа, которая при разных концентрациях Al и O будет определять что образуется.

    Вот что у нас получилось. Не работает только метод половинного деления. Во всем остальном ошибки не выдает. При if (F(a)*F(B))<0 выдает ошибку "функция не задана". Как я понимаю он не воспринимает F так как я хочу. Но как именно исправить не могу понять.
    Код (Text):
    //библиотеки---------------------------------------------------------------------------

    #include <vcl.h>
    #include <math.h>
    #include <fstream.h>
    #include <stdio.h>

    //исходные данные---------------------------------------------------------------------------
    #pragma argsused
    #pragma hdrstop

    double FPD(double,double,double,double); // прототип функции
    double NewTon(double,double,double,double); // прототип функции


    int main(int argc, char* argv[])     // главная функция
    {
    double m,h=0.00001,CAl=0,CO=0,CFe=1,mAl=26.092,mO=15.999,KAl2O3=3.5E-24,Kgerc=9E-28,Kshlak=2.23E-3,mAl2O3=101.9612,mgerc=173.8106,mFeO=71.8464,a=0,b=1,MAl,MO,R;

    double F(double m,double CAl, double CO);
    {return pow(CAl-m*2*mAl/mAl2O3,2)*pow(CO-m*3*mO/mAl2O3,3)-KAl2O3;} // функция для нахождения Al2O3
    double Fg(double m,double CAl, double CO);
    {return pow(CAl-m*2*mAl/mgerc,2)*pow(CO-m*4*mO/mgerc,4)*(CFe-(m-CO-CAl))-Kgerc;} // функция для нахождения FEO*Al2O3 (герценит)
    //-------------------------------------------

    //Метод половинного деления------------------
    double FPD(double m,double CAl,double CO,double h); // функция для нахождения корная методом половинного деления
    {
    double a=0,b=1,F,m; // объявление концов отрезков
    while (fabs(b-a)>h) // пока длина отрезка больше допустимой точности (fabs возвращает абсолютное значение)
    {
    if (F(a)*F(b))<0 // проверка на то, чтобы знаки функции в этих точках были разные - это одно из улосвий применения данного метода
    {
    m=(a+b)/2;

    {
    if (F(a)*F(m)>0) // если концы отрезка в точке a и середине отрезка имеют одинаковые знаки, т.е. проверка какую границу взять за начальную точку
    {
    a=m; // перенести точку a в середину отрезка
    }
    else     // иначе
    {
    b=m; // перенести точку b в середину отрезка
    }
    }
    }

    else
    {return -777;} // если отрезки имеют одинаковые знаки вернуть ошибку, т.е. F(a)*F(b)>0
    }

    return m;
    }

    // Метод Ньютона-----------------------
    double NewTon(double CAl,double CO, double x, double m);
    {
    double X[2],X0[2],A[2],F[2],Fd[2][2],N[2][2],x0,m0,x;
    do
    {
    X0[0]=0.5;
    X0[1]=0.5;
    x0=X0[0];
    m0=X0[1];
    double h=0.00001;
    // элементы матрицы F[2][1]
    F[0]=pow(CAl-m*x*(2*mAl/mAl2O3),2)*pow(CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mFeO),3)-KAl2O3*x; // функция f1 (расчет константы равновесия Al2O3 в шлаке)
    F[1]=CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mFeO)-(1-x)*Kshlak; // функция f2 (расчет константы равновесия FeO в шлаке)

    // элементы матрица Fd[2][2]
    Fd[0][0]=2*(CAl-m*x*(2*mAl/mAl2O3))*(-m*(2*mAl/mAl2O3))*pow(CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mAl2O3),3)-pow(CAl-m*x*(2*mAl/mAl2O3),2)*3*pow(CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mFeO),2)*(-m*(3*mO/mAl2O3)+m*(mO/mFeO))-KAl2O3; // функция f1x (производная по х для Al2O3 в шлаке)
    Fd[0][1]=2*(CAl-m*x*(2*mAl/mAl2O3))*(-x*(2*mAl/mAl2O3))*pow(CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mAl2O3),3)-pow(CAl-m*x*(2*mAl/mAl2O3),2)*3*pow(CO-m*x*(3*mO/mAl2O3)-m*(1-x)*(mO/mFeO),2)*(-x*(3*mO/mAl2O3)-(1-x)*(mO/mFeO)); //функция f1m (производная по m AL2O3 в шлаке)
    Fd[1][0]=(-3*mO/mAl2O3)*m+(mO/mFeO)*m+Kshlak; // функция f2x (производная по х для FeO в шлаке)
    Fd[1][1]=(-3*mO/mAl2O3)*x+(mO/mFeO)*(1-x); // функция f2m (производная по m FeO в шлаке)
    double DetFd; // нахождение определтеля матрицы F"
    DetFd=Fd[0][0]*Fd[1][1]-Fd[1][0]*Fd[0][1]; // формула для определителя
    if (DetFd==0) // проверка на то, что определитель не равен 0, т.к. на ноль делить нельзя
    return -7777; // если определитель равен 0, то выдает ошибку
    N[0][0]=Fd[1][1]/DetFd; // формирование элементов обратной матрицы
    N[0][1]=Fd[0][1]/DetFd;
    N[1][0]=Fd[1][0]/DetFd;
    N[1][1]=Fd[1][1]/DetFd;
    A[0]=N[0][0]*F[0]+N[0][1]*F[1]; // формирование элементов умноженной матрицы
    A[1]=N[1][0]*F[0]+N[1][1]*F[1];
    X[0]=X0[0]-A[0]; // X=X0-A, где N=(F")-1 (обратная матрица)
    X[1]=X0[1]-A[1];
    x=X[0]; // X - матрица столбец с элементами x и m
    m=X[1];
    }
    while (fabs(x-x0)>h&&fabs(m-m0)>h); // условие достижения заданной точности
    return m; // когда достигается заданная точность выдает ответ m- масса шлака
    }
    // Программа вычисляющая что получится (алгоритм)--------------
    MAl=CAl; // исходные данные
    MO=CO; // т.к. расчет ведется на 1 кг, то доли этих комнонетов совпадают с массами
    if ((pow(CAl-m*2*mAl/mAl2O3,2)*pow(CO-m*3*mO/mAl2O3,3))>(3.5E-24))
    {
    m=FPD(CAl,CO,h,1); // то масса образовавшегося Al2O3 будет находиться с помощью метода половинного деления
    if(m>0)
    {
    MAl=CAl-m*2*mAl/mAl2O3;
    MO=CO-m*3*mO/mAl2O3;
    R=1;
    };
    };

    if ((pow(CAl-m*2*mAl/mgerc,2)*pow(CO-m*4*mO/mgerc,4)*(CFe-(m-CO-CAl)))>(9.0E-28))
    {
    m=FPD(CAl,CO,h,2); // то масса образовавшегося Al2O3 будет находиться с помощью метода половинного деления
    if(m>0)
    {
    MAl=CAl-m*2*mAl/mgerc;
    MO=CO-m*4*mO/mgerc;
    R=2;
    }

    else
    {
    m=NewTon(CAl,CO,m,3);
    if(m>0)
    {
    m=NewTon(CAl,CO,m,3); // то масса образовавшегося шлака будет находиться с помощью метода Ньютона
    R=3;
    }
    else R=0;
    }
    }




    return -77777;
    }
     
Загрузка...
Похожие Темы - Распределение
  1. Antoni
    Ответов:
    2
    Просмотров:
    945
  2. alexstudent
    Ответов:
    2
    Просмотров:
    1.475
Статус темы:
Закрыта.

Поделиться этой страницей