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

  • Автор темы Guest
  • Дата начала
Статус
Закрыто для дальнейших ответов.
G

Guest

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

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

#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;
}
 
Статус
Закрыто для дальнейших ответов.