gvitbsord před 10 měsíci
rodič
revize
d03cdb12d5
14 změnil soubory, kde provedl 224 přidání a 143 odebrání
  1. 16
    7
      Makefile
  2. 9
    8
      draghilevinout.cpp
  3. 4
    3
      draghilevinout.h
  4. 11
    11
      funcdrag.cpp
  5. 15
    18
      main.cpp
  6. 11
    11
      octaveplg.cpp
  7. 2
    1
      octaveplg.h
  8. 13
    5
      solver.cpp
  9. 4
    8
      solver.h
  10. 83
    42
      sysdiffeqn.cpp
  11. 9
    5
      sysdiffeqn.h
  12. 26
    10
      sysosndan.cpp
  13. 20
    13
      sysosndan.h
  14. 1
    1
      test/Drag_example_8

+ 16
- 7
Makefile Zobrazit soubor

@@ -1,10 +1,13 @@
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
CFLAGS := -std=c++11 -O2 -Wall
mathgl := n
oct := n
CFLAGS = -std=c++11 -O2 -Wall
mathgl = n
oct = n

all: Draghilev

debug: CFLAGS += -g
debug: Draghilev

main.o: main.cpp
g++ -c -I ./include $? $(CFLAGS)

@@ -12,19 +15,25 @@ ifeq ($(mathgl),y)
draghilevinout.o: draghilevinout.cpp
g++ -c -DMATHGL -I ./include $? $(CFLAGS)
Draghilev: main.o libmathgl.so sysosndan.o sysdiffeqn.o solver.o octaveplg.o funcdrag.o draghilevinout.o
g++ -L ./ $? -lcln -lmathgl -ldl $(CFLAGS) -o Draghilev
g++ -L ./ $? -lcln -lmathgl -ldl $(CFLAGS) -o $@
else
draghilevinout.o: draghilevinout.cpp
g++ -c -I ./include $? $(CFLAGS)
Draghilev: main.o sysosndan.o sysdiffeqn.o solver.o octaveplg.o funcdrag.o draghilevinout.o
g++ -L ./ $? -lginac -lcln -ldl $(CFLAGS) -o Draghilev
g++ -L ./ $? -lginac -lcln -ldl $(CFLAGS) -o $@
endif

draghilev_oct.o: main.cpp
CXXFLAGS="-O2 -std=c++11 -DOCTAVE" mkoctfile -c -o draghilev_oct.o $? -lcln -lginac
CXXFLAGS="-O2 -std=c++11 -DOCTAVE" mkoctfile -c -o $@ $? -lcln -lginac

draghilev_oct: draghilev_oct.o sysosndan.o solver.o
CXXFLAGS="-O2 -std=c++11" mkoctfile -o draghilev_oct $? -lcln -lginac
CXXFLAGS="-O2 -std=c++11" mkoctfile -o $@ $? -lcln -lginac

poverx_oct.o: poverx.cpp
CXXFLAGS="-O2 -std=c++11 -DOCTAVE" mkoctfile -c -o $@ $? -lcln -lginac

poverx_oct: poverx_oct.o sysosndan.o solver.o sysdiffeqn.o funcdrag.o
CXXFLAGS="-O2 -std=c++11" mkoctfile -o $@ $? -lcln -lginac

sysosndan.o: sysosndan.cpp
g++ -c -fPIC $? $(CFLAGS)

+ 9
- 8
draghilevinout.cpp Zobrazit soubor

@@ -11,12 +11,13 @@ draghilevinout::draghilevinout(int argc, char *argv[]) :
mathgl("m", "mathgl", "Вывод графики через Mathgl", cmd, false),
#endif
nodel("n", "nodel", "Не удалять сду", cmd, false),
exit("e", "exit", "Завершение работы при возвращении в начальное положение", cmd, false),
nocomp("c", "nocomp", "Не компилировать сду, если она существует", cmd, false),
nocpp("p", "nocpp", "Не удалять сду-файл, если он существует", cmd, false),
benchmark("b", "benchmark", "Формирование m-файла для тестирования производительности", cmd, false),
inp_file("inp_file", "Чтение из входного файла", false, "example.txt", "входной файл", cmd),
out_file("o", "outfile","Запись в выходной файл", false, "", "выходной файл", cmd),
oct_file("O", "oct_file", "Создание скриптового m-файла для octave", false, "", "octave m-файл", cmd)
oct_file("O", "oct_file", "Создание скриптового m-файла для octave", false, "", "octave m-файл", cmd),
exit("e", "exit", "Завершение работы при возвращении в начальное положение", false, -1, "точность", cmd)
{
cmd.parse(argc, argv);
std::ifstream myfilein ( inp_file.getValue() );
@@ -31,15 +32,15 @@ void draghilevinout::checkdel()
std::cout<<"Ошибка при удалении сду"<< std::flush;
}

void draghilevinout::write_out_text(sys_diff_equation &sde, solver_diff_eqn &sofe)
void draghilevinout::write_out_text(sys_osn_dan &sod)
{
if ( out_file.isSet() )
{
std::ofstream outst ( out_file.getValue() );
//std::vector<double>::const_iterator it=sofe.get_coord().begin();
auto it = sofe.get_coord().begin();
int N_var=sde.get_par_diff().nv;
while( it != sofe.get_coord().end() )
auto it = sod.get_resOUT().begin();
int N_var=sod.get_par_diff().nv;
while( it != sod.get_resOUT().end() )
{
std::copy(it, it+N_var, std::ostream_iterator<double>(outst, " "));
outst<<std::endl;
@@ -49,11 +50,11 @@ void draghilevinout::write_out_text(sys_diff_equation &sde, solver_diff_eqn &sof
}
}

void draghilevinout::write_octave_m(sys_diff_equation &sde)
void draghilevinout::write_octave_m(sys_osn_dan &sod, sys_diff_equation &sde)
{
if ( oct_file.isSet() )
{
octaveplg Octm(sde, oct_file.getValue(), benchmark.getValue());
octaveplg Octm(sod, sde, oct_file.getValue(), benchmark.getValue());
Octm.octave_m();
}
}

+ 4
- 3
draghilevinout.h Zobrazit soubor

@@ -17,15 +17,16 @@ class draghilevinout
TCLAP::SwitchArg mathgl;
#endif
TCLAP::SwitchArg nodel;
TCLAP::SwitchArg exit;
TCLAP::SwitchArg nocomp;
TCLAP::SwitchArg nocpp;
TCLAP::SwitchArg benchmark;
TCLAP::UnlabeledValueArg<std::string> inp_file;
TCLAP::ValueArg<std::string> out_file;
TCLAP::ValueArg<std::string> oct_file;
TCLAP::ValueArg<int> exit;
void checkdel();
void write_out_text(sys_diff_equation &, solver_diff_eqn &);
void write_octave_m(sys_diff_equation &);
void write_out_text(sys_osn_dan &);
void write_octave_m(sys_osn_dan &, sys_diff_equation &);
void write_mathgl_disp(sys_diff_equation &, solver_diff_eqn &);
};


+ 11
- 11
funcdrag.cpp Zobrazit soubor

@@ -6,12 +6,13 @@ GiNaC::ex sys_diff_equation::eval_line(const GiNaC::ex &p1, const GiNaC::ex &p2)

if (p1.info(GiNaC::info_flags::posint) && p2.info(GiNaC::info_flags::posint))
{
GiNaC::numeric _p1=GiNaC::ex_to<GiNaC::numeric>(p1), _p2=GiNaC::ex_to<GiNaC::numeric>(p2);
vp_num.push_back(_p1.to_int());
vp_num.push_back(_p2.to_int());
int _p1=GiNaC::ex_to<GiNaC::numeric>(p1).to_int(), _p2=GiNaC::ex_to<GiNaC::numeric>(p2).to_int();
vp_num.push_back(_p1);
vp_num.push_back(_p2);
// пока at, доделать проверку max(p1,p2)*dim_line<var_name.size() -1(+a)
GiNaC::ex temp;
for (unsigned i=0;i<dim_line;i++)
temp += (var_name[_p1.to_int()*dim_line-(i+1)] - var_name[_p2.to_int()*dim_line-(i+1)])*(var_name[_p1.to_int()*dim_line-(i+1)] - var_name[_p2.to_int()*dim_line-(i+1)]);
temp += (var_name.at(_p1*dim_line-(i+1)) - var_name.at(_p2*dim_line-(i+1)))*(var_name.at(_p1*dim_line-(i+1)) - var_name.at(_p2*dim_line-(i+1)));
return temp;
}
return 0;
@@ -45,11 +46,10 @@ GiNaC::ex sys_diff_equation::eval_circle3(const GiNaC::ex &p1, const GiNaC::ex &

p2.print(GiNaC::print_dflt(_temp));
_temp>>_ch1>>_ch2;
p[0]=p1;
_ax1 = _ch1-'0';
_ax2 = _ch2-'0';
_ax1 = _ch1-'w';
_ax2 = _ch2-'w';

p[0]=p1;
p[_ax1]=1;
p[_ax1+3]=p3;
p[_ax2]=1;
@@ -70,7 +70,7 @@ GiNaC::ex sys_diff_equation::eval_ellipse3(const GiNaC::exvector &p)
if (p[i].info(GiNaC::info_flags::nonnegative))
{
_check++;
if (p[i] == 1 || p[i] == 0)
if (p[i] == 1)
_iscircle++;
}

@@ -78,11 +78,11 @@ GiNaC::ex sys_diff_equation::eval_ellipse3(const GiNaC::exvector &p)
{
GiNaC::numeric _p0=GiNaC::ex_to<GiNaC::numeric>(p[0]);
GiNaC::ex temp;
if (_iscircle == dim_line)
if (_iscircle == 2)
{
circ_num.push_back(_p0.to_int());
for (unsigned i=1;i<dim_line+1;i++)
if (p[i] == 1)
if (p[i] == 1 && GiNaC::is_a<GiNaC::numeric>(p[i+3]))
circ_coord.push_back(GiNaC::ex_to<GiNaC::numeric>(p[i+3]).to_double());
else circ_coord.push_back(0);
}

+ 15
- 18
main.cpp Zobrazit soubor

@@ -10,19 +10,19 @@
int main(int argc, char* argv[])
{
draghilevinout Dinout(argc, argv);
sys_osn_dan DATA(Dinout.mystreamin);
sys_osn_dan DATA(Dinout.mystreamin, Dinout.nocomp.getValue(), Dinout.nocpp.getValue());
sys_diff_equation A(DATA);
//double t0=clock();//START_TIMER;

solver_diff_eqn B(DATA, Dinout.nocomp.getValue(), Dinout.exit.getValue());
solver_diff_eqn B(DATA, Dinout.exit.getValue());
Dinout.checkdel();
//STOP_TIMER
//std::cout << (clock()-t0)/CLOCKS_PER_SEC<< '\t' <<N<< std::endl;
Dinout.write_out_text(A, B);
Dinout.write_octave_m(A);
Dinout.write_mathgl_disp(A, B);
Dinout.write_out_text(DATA);
Dinout.write_octave_m(DATA, A);
Dinout.write_mathgl_disp(A, B);

return 0;
}
@@ -39,7 +39,10 @@ DEFUN_DLD (draghilev_oct, args, , "Draghilev method")
std::stringstream buffer;
buffer << octfilein.rdbuf();
octfilein.close();
sys_osn_dan DATA(buffer);

bool not_comp=args.length() == 0 || (args.length() != 0 && args(0).int_value() != 1), //компилировать если аргумент равен 1
not_cpp=true;
sys_osn_dan DATA(buffer, not_comp, not_cpp);

double N=DATA.get_par_diff().N;
int N_var=DATA.get_par_diff().nv;
@@ -51,24 +54,18 @@ DEFUN_DLD (draghilev_oct, args, , "Draghilev method")
dt=args(1).double_value();
DATA.set_par_diff(N,dt);
}
bool not_comp=args.length() == 0 || (args.length() != 0 && args(0).int_value() != 1);

bool exit_=false;
double exit_tol;
double exit_tol=-1;
if ( args.length() == 3)
{
exit_=true;
exit_tol=args(2).double_value();
}
solver_diff_eqn B(DATA, not_comp, exit_, exit_tol);
int nrow=B.get_coord().size()/N_var;
exit_tol=args(2).double_value();

solver_diff_eqn B(DATA, exit_tol);
int nrow=DATA.get_resOUT().size()/N_var;
int t=0;
Matrix res_matrix(nrow, N_var);
for (int i=0;i<nrow;i++)
for (int j=0;j<N_var;j++)
res_matrix(i,j)=B.get_coord()[t++];
res_matrix(i,j)=DATA.get_resOUT()[t++];

retval(0)=res_matrix;
retval(1)=dt;

+ 11
- 11
octaveplg.cpp Zobrazit soubor

@@ -1,14 +1,14 @@
#include "octaveplg.h"

octaveplg::octaveplg(sys_diff_equation &sde_, std::string &name_, bool(_bench_m)): sde(&sde_), octout(name_), bench_m(_bench_m)
octaveplg::octaveplg(sys_osn_dan &sod_, sys_diff_equation &sde_, std::string &name_, bool(_bench_m)): sod(&sod_), sde(&sde_), octout(name_), bench_m(_bench_m)
{
x=sde->get_par_diff().x0;
n_svob=sde->get_par_diff().nsv;
equations=sde->get_par_diff().eqn;
dim_line=sde->get_par_diff().dln;
vp_num=sde->get_graphdata().vpnum;
circ_num=sde->get_graphdata().cnum;
circ_coord=sde->get_graphdata().ccord;
x=sod->get_par_diff().x0;
n_svob=sod->get_par_diff().nsv;
equations=sod->get_par_diff().eqn;
dim_line=sod->get_par_diff().dln;
vp_num=sde->get_ginacdata().vpnum;
circ_num=sde->get_ginacdata().cnum;
circ_coord=sde->get_ginacdata().ccord;
sde->info_eqn_octave(error_stream, eqn_stream);
}

@@ -71,7 +71,7 @@ void octaveplg::write_graphic_tom()//to m-script
out << "\n";
}

out << "h = max(max(abs(diff(sol))))/10;\n";
out << "h = max(mean(abs(diff(sol))))/10;\n";
out << "limits = [";
for (int i=0;i<dim_line;i++)
out << "min(" << coord_nam[i] << "(:)), max(" << coord_nam[i] << "(:))+h, ";
@@ -115,7 +115,7 @@ void octaveplg::write_graphic_tom()//to m-script
out << colour_prt[3];
}

for (auto i = vp_num.begin(); i != vp_num.end(); i+=2)
for (auto i = vp_num.begin(); i != vp_num.end(); i+=2)//линия
{
for (int j=0;j<dim_line;j++)
out << "\t ["<< coord_nam[j] << "(1," << *i << ") " << coord_nam[j] << "(1," << *(i+1) << ")], ";
@@ -133,7 +133,7 @@ void octaveplg::write_graphic_tom()//to m-script

if (n_svob != 1)
out << "num=num/" << n_svob << ";\n";
out << "dn = round (num/10);\n" << "#g_step=1;\n" << "g_step=round (num/120);\n" << "axis (limits,\"equal\");\n" << "#legend({[";
out << "dn = round (num/10);\n" << "#g_step=1;\n" << "g_step=round (num/120);\n" << "axis (\"equal\",1.001*limits);\n" << "axis (limits);\n" << "#legend({[";
for (auto i: equations)
out << "'" << i << "' char(10) ";

+ 2
- 1
octaveplg.h Zobrazit soubor

@@ -4,11 +4,12 @@
class octaveplg
{
public:
octaveplg(sys_diff_equation &, std::string &, bool);
octaveplg(sys_osn_dan &, sys_diff_equation &, std::string &, bool);
void octave_m();

private:
void write_graphic_tom();
sys_osn_dan *sod;
sys_diff_equation *sde;
std::ofstream octout;
std::stringstream out;

+ 13
- 5
solver.cpp Zobrazit soubor

@@ -1,11 +1,13 @@
#include "solver.h"

solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, const bool not_comp_, const bool exit_, double exit_tol):sod(&sod_)
solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, double exit_tol):sod(&sod_)
{
N=sod->get_par_diff().N;
dt=sod->get_par_diff().dt;
x=sod->get_par_diff().x0;
n_svob=sod->get_par_diff().nsv;
not_comp_=sod->get_par_diff().noc;

std::ifstream stream("test.so");

if ( !(stream.good() && not_comp_) )
@@ -14,6 +16,7 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, const bool not_comp_, const
if (systemErr == -1)
std::cerr<<"Ошибка компилирования"<<std::endl;
}
stream.close();

shared_object = dlopen("./test.so", RTLD_NOW);
create_t* load_sys = (create_t*) dlsym(shared_object, "create");
@@ -25,7 +28,7 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, const bool not_comp_, const
coordinate.insert(coordinate.end(), x.begin(), x.end());
const state_type x0=x;

if ( exit_ )
if ( exit_tol>0 )
{
c1_=x;
for (unsigned int i = 0; i < x.size(); i++)
@@ -42,7 +45,7 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, const bool not_comp_, const
i++;
rk.do_step( func[k] , x , l_dt , r_dt );
coordinate.insert(coordinate.end(), x.begin(), x.end());
if ( exit_ )
if ( exit_tol>0 )
{
for (unsigned int i = 0; i < x.size(); i++)
{
@@ -62,8 +65,13 @@ solver_diff_eqn::solver_diff_eqn(sys_osn_dan &sod_, const bool not_comp_, const
}
}
}
sod->set_resIN(coordinate);
unload_sys(func_sys);

closeso=true; //исправить sysosndan
// if (closeso)
// dlclose(shared_object);

}

solver_diff_eqn::~solver_diff_eqn(){ dlclose(shared_object); }
solver_diff_eqn::~solver_diff_eqn(){ dlclose(shared_object); }//вызывает segmentation fault

+ 4
- 8
solver.h Zobrazit soubor

@@ -3,30 +3,26 @@

#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <dlfcn.h>
#include "sysdiffeqn.h"
#include "virteqn.h"
#include "sysosndan.h"

typedef std::vector < double > state_type;
typedef void (*func_t)(const state_type &, state_type &, const double );

class solver_diff_eqn
{
public:
solver_diff_eqn(sys_osn_dan &, const bool, const bool, double exit_tol=2e-3);
solver_diff_eqn(sys_osn_dan &, double);
~solver_diff_eqn();
const state_type &get_coord() { return coordinate; }
bool closeso;
private:
sys_diff_equation *sde;
sys_osn_dan *sod;
state_type x, coordinate, c1_, c_diff, max_x;
std::vector<func_t> func;
boost::numeric::odeint::runge_kutta4< state_type > rk;
double dt, N, m_pos;
double dt, N, m_pos;
state_type::iterator m_diff;
int n_svob;
void *shared_object;
bool not_comp_;
};

#endif

+ 83
- 42
sysdiffeqn.cpp Zobrazit soubor

@@ -11,8 +11,8 @@ std::vector<GiNaC::symbol> sys_diff_equation::var_name ={};
sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
{
std::string str, str_sm, dimension;

std::stringstream _isstemp, mystreamin;
std::vector<GiNaC::symbol> uprav_par_ex;
// for (std::string str; std::getline(mystreamin_, str);)
// if (!str.empty())
// mystreamin << str << '\n';
@@ -25,6 +25,7 @@ sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
// std::getline(mystreamin, str);
// std::getline(mystreamin, str);
x=sod->get_par_diff().x0;
uprav_par=sod->get_par_diff().up;
// _isstemp.str(str);
// for (double temp; _isstemp>>temp;)
// x.push_back(temp);
@@ -32,46 +33,80 @@ sys_diff_equation::sys_diff_equation(sys_osn_dan &sod_): sod(&sod_)
//чтение нач. коорд. преобразование для ginac согласно 5.15.2 Expression input
for (unsigned i=0;i<x.size();i++)
{
str=str_sm + "["+ std::to_string(i)+ "]";
str=str_sm + "_"+ std::to_string(i)+ "_";
var_name.push_back(GiNaC::symbol(str));
table[str]=var_name[i];
}
var_name.push_back(GiNaC::symbol("a"));
table["a"]=var_name.back();
// var_name.push_back(GiNaC::symbol("a"));
//table["a"]=var_name.back();//проверку на наличия сделать здесь
//for (std::vector<std::string>::iterator it = uprav_par.begin(); it != uprav_par.end(); it++)
// table[*it]=GiNaC::symbol(*it);
table["xy"]=GiNaC::symbol("xy");//в функцую + проверять есть circle3
table["xz"]=GiNaC::symbol("xz");
table["yx"]=GiNaC::symbol("yx");
table["yz"]=GiNaC::symbol("yz");
table["zx"]=GiNaC::symbol("zx");
table["zy"]=GiNaC::symbol("zy");

for (unsigned i=0;i<uprav_par.size();i++)
{
uprav_par_ex.push_back(GiNaC::symbol(uprav_par[i]));
table[uprav_par[i]]=uprav_par_ex[i];
}
// GiNaC::ex cc=GiNaC::symbol("a");
// table["a"]=cc;

GiNaC::parser reader(table, true); //если есть различие между переменными в уравнениях и объявлении, то true выдает ошибку

equations=sod->get_par_diff().eqn;
equations_svob=sod->get_par_diff().eqn_svob;
est_uprav=false; //по умолчанию считаем
for (auto it = equations.begin(); it != equations.end(); it++)
expr_in.push_back(reader(*it));
{
expr_in.push_back(reader(*it));
for (size_t j=0; j<uprav_par_ex.size(); j++)
est_uprav=est_uprav || GiNaC::has(expr_in.back(),uprav_par_ex[j]);
}

equations.insert(equations.end(), equations_svob.begin(), equations_svob.end());

for (auto it = equations_svob.begin(); it != equations_svob.end(); it++)
expr_svob.push_back(reader(*it));
{
expr_svob.push_back(reader(*it));
for (size_t j=0; j<uprav_par_ex.size(); j++)
est_uprav=est_uprav || GiNaC::has(expr_svob.back(),uprav_par_ex[j]);
}

if (x.size()-expr_in.size() != 1 && (expr_svob.size() == 0 || expr_svob.size() % (x.size()-expr_in.size()-1) != 0))
{
_isstemp.str("");
_isstemp << "Неправильное число данных. Число начальных координат " << x.size() << " число постоянных уравнений " << expr_in.size() << " число уравнений для степени свободы больше одной " << expr_svob.size();
throw std::invalid_argument(_isstemp.str());
}
n_svob=sod->get_par_diff().nsv;

N_var=x.size();
n_svob=sod->get_par_diff().nsv;
N_var=sod->get_par_diff().nv;
N_ex=expr_in.size(); //число уравнений
det_comp();
if (!sod->get_par_diff().npp)
det_comp();
}

void sys_diff_equation::det_comp()
{
int N_var=x.size();
std::ofstream ofst{"test.cpp"}; // текстовая форма сду

ofst << "#include <cmath> " << std::endl;
ofst << "#include \"virteqn.h\"" << std::endl;
ofst << "#include \"virteqn.h\"" << '\n' << std::endl;
ofst << "class funcinst : public diffeqninterface {" << std::endl << "public:" <<std::endl;
ofst << "virtual std::vector<syseqn> funcv();" << std::endl;
// ofst << "virtual void set_par_a(double &_a) {a=_a;}" <<std::endl;
// ofst << "static double a;" << std::endl;

for (std::vector<std::string>::iterator it = uprav_par.begin(); it != uprav_par.end(); it++)
ofst << "static double "<< *it <<";" << std::endl;
//ofst << "virtual void set_par_a(double &_a) {a=_a;}" <<std::endl;
ofst << "private:" << std::endl;
GiNaC::ex temp_1=expr_in.back();
//bool check_t=false;
@@ -88,7 +123,8 @@ void sys_diff_equation::det_comp()
ofst << "extern \"C\" diffeqninterface* create() {" << "return new funcinst;" << "}"<<std::endl;

ofst << "extern \"C\" void destroy(diffeqninterface *p) {" << "delete p;" << "}"<<std::endl <<std::endl;
//ofst << "double funcinst::a=-.2;" << std::endl;
for (std::vector<std::string>::iterator it = uprav_par.begin(); it != uprav_par.end() && est_uprav; it++)
ofst << "double funcinst::"<< *it << "=0;" << std::endl;

ofst << "std::vector<syseqn> funcinst::funcv() {" << std::endl;
ofst << "std::vector<syseqn> temp_;" << std::endl;
@@ -122,35 +158,25 @@ void sys_diff_equation::det_comp()
b_temp(0,i)=A_mat(count,i);
A_mat(count,i)=b_mat(0,i);
}
GiNaC::determinant(A_mat).print(GiNaC::print_csrc_double(ofst));
ofst << ");" << std::endl;
std::stringstream prav_ch; //правая часть
GiNaC::determinant(A_mat).print(GiNaC::print_csrc_double(prav_ch));
ofst << vnut_pred(prav_ch).rdbuf() << ");" << std::endl;
for (int i=0; i<N_var-1;i++)
A_mat(count,i)=b_temp(0,i);
}
ofst << "f[" << N_var-1 << "] = (";
GiNaC::determinant(A_mat).print(GiNaC::print_csrc_double(ofst));
ofst << ");" << std::endl << "}" << std::endl;
std::stringstream prav_ch; //правая часть
GiNaC::determinant(A_mat).print(GiNaC::print_csrc_double(prav_ch));
ofst << vnut_pred(prav_ch).rdbuf() << ");" << std::endl << "}" << std::endl;
}
if (n_svob == 1)
expr_in.push_back(temp_1);
ofst.close();
}

soldif sys_diff_equation::get_par_diff()
ginacdata sys_diff_equation::get_ginacdata()
{
soldif A;
A.N=N;
A.dt=dt;
A.x0=x;
A.nsv=n_svob;
A.nv=N_var;
A.eqn=equations;
A.dln=dim_line;
return A;
}

graphdata sys_diff_equation::get_graphdata()
{
graphdata A;
ginacdata A;
A.vpnum=vp_num;
A.cnum=circ_num;
A.ccord=circ_coord;
@@ -160,13 +186,13 @@ graphdata sys_diff_equation::get_graphdata()
void sys_diff_equation::info_eqn_octave(std::stringstream &error_stream, std::stringstream &eqn_stream)
{
eqn_stream<<"#{\n";
std::regex regSn(":");
std::regex regz("\\*|\\^|\\/");
std::regex regSn(":"), regz("\\*|\\^|\\/");

for (size_t i=0; i<expr_in.size(); i++)
{
std::stringstream strsm;
expr_in[i].print(GiNaC::print_dflt(strsm));
std::stringstream strsm,strsm_;
expr_in[i].print(GiNaC::print_dflt(strsm_));
strsm << vnut_pred(strsm_).rdbuf();
std::string str(strsm.str());
const char coord_name[]="xyz";
std::size_t pos_l = str.find('[', 0)+1;//следующий символ цифра
@@ -185,8 +211,23 @@ void sys_diff_equation::info_eqn_octave(std::stringstream &error_stream, std::st
eqn_stream << "eqn(:," << i+1 << ")=" << str << ";" << std::endl;
error_stream << "error_eqn(:," << i+1 << ")=" << str << " - (" <<regex_replace(str, regSn, "1") << ");" <<std::endl;
}

eqn_stream << "#}\n";
error_stream << "max_error=max(abs(error_eqn));\n\n";
if (uprav_par.size() == 0)
{
eqn_stream << "#}\n";
error_stream << "max_error=max(abs(error_eqn));\n\n";
}
else
error_stream << "max_error=max(abs(error_eqn));\n#}\n\n";
}

std::stringstream &sys_diff_equation::vnut_pred(std::stringstream &prav_ch)
{
std::string input=prav_ch.str();
std::regex left_s("_([[:d:]]+)"), right_s("([[:d:]]+)_");

input=regex_replace(input,left_s,"[$1");
input=regex_replace(input,right_s,"$1]");
prav_ch.str("");
prav_ch << input;
return prav_ch;
}

+ 9
- 5
sysdiffeqn.h Zobrazit soubor

@@ -8,11 +8,12 @@
#include <vector>
#include "sysosndan.h"

struct graphdata
struct ginacdata
{
std::vector<int> vpnum;
std::vector<int> cnum;
std::vector<double> ccord;
std::vector<int> vpnum;//линии
std::vector<int> cnum;//круги
std::vector<double> ccord;//
bool up;//управляемый параметр
};

//класс, дающий конечную систему ду в текстовой форме и в компилируемой
@@ -32,7 +33,7 @@ class sys_diff_equation
void det_comp(); //вычисление детерминанта, запись в файл
void info_eqn_octave(std::stringstream &, std::stringstream &);
soldif get_par_diff();
graphdata get_graphdata();
ginacdata get_ginacdata();
static GiNaC::ex eval_line(const GiNaC::ex &, const GiNaC::ex &);
static GiNaC::ex print_line(const GiNaC::ex &, const GiNaC::ex &);
static GiNaC::ex eval_circle(const GiNaC::ex &, const GiNaC::ex &, const GiNaC::ex &);
@@ -50,11 +51,14 @@ class sys_diff_equation
GiNaC::matrix b_mat; // получается из lst_svb
GiNaC::matrix b_temp; // временной столбец, служит для возвращении A_mat исходного значения
std::string dimension; //dimension 2-ух, 3-х мерное
std::stringstream &vnut_pred(std::stringstream &);//x_ to x[]
std::vector<std::string> uprav_par;//управляющие параметры
static std::vector<int> circ_num;
static std::vector<double> circ_coord;
int n_svob; //число свободных переменных
int N_var;
int N_ex; //число уравнений
bool est_uprav;//Наличие управляющих параметров
sys_osn_dan *sod;
};


+ 26
- 10
sysosndan.cpp Zobrazit soubor

@@ -1,20 +1,31 @@
#include "sysosndan.h"
#include <algorithm>
#include <regex>

unsigned sys_osn_dan::dim_line=2;
sys_osn_dan::sys_osn_dan(std::stringstream &mystreamin_)
sys_osn_dan::sys_osn_dan(std::stringstream &mystreamin_, const bool nocomp_, const bool nocpp_): nocomp(nocomp_), nocpp(nocpp_)
{
isxod_dan(mystreamin_);
}

void sys_osn_dan::isxod_dan(std::stringstream &mystreamin_)
{
std::string str;
std::stringstream _isstemp, mystreamin;

for (std::string str; std::getline(mystreamin_, str);)
if (!str.empty())
mystreamin << str << '\n';

mystreamin>>str_sm>>dt>>N>>dimension;
dim_line=dimension[0]-'0';

std::getline(mystreamin, str);
std::getline(mystreamin, str);
std::stringstream _iss(str);
for (std::string sub; _iss>>sub;)
uprav_par.push_back(sub);

std::getline(mystreamin, str);
_isstemp.str(str);
for (double temp; _isstemp>>temp;)
x.push_back(temp);
@@ -24,10 +35,10 @@ sys_osn_dan::sys_osn_dan(std::stringstream &mystreamin_)
if (str.find("+sv:") != std::string::npos)
{
for (std::string str; std::getline(mystreamin, str, '\n');)
equations_svob.push_back(str);
equations_svob.push_back(razdto_(str));
break;
}
equations.push_back(str);
equations.push_back(razdto_(str));
}

N_var=x.size(); //число переменных
@@ -38,9 +49,8 @@ sys_osn_dan::sys_osn_dan(std::stringstream &mystreamin_)
n_svob=equations_svob.size();
}

soldif sys_osn_dan::get_par_diff()
soldif &sys_osn_dan::get_par_diff()
{
soldif A;
A.N=N;
A.dt=dt;
A.x0=x;
@@ -50,11 +60,17 @@ soldif sys_osn_dan::get_par_diff()
A.eqn_svob=equations_svob;
A.dln=dim_line;
A.str_sm=str_sm;
A.npp=nocpp;
A.noc=nocomp;
A.up=uprav_par;
return A;
}

void sys_osn_dan::set_par_diff(double N_, double dt_)
std::string &sys_osn_dan::razdto_(std::string &s)
{
N=N_;
dt=dt_;
std::string razd="[]";

for (size_t i=0;i<razd.length();i++)
std::replace( s.begin(), s.end(), razd[i], '_');
return s;
}

+ 20
- 13
sysosndan.h Zobrazit soubor

@@ -3,43 +3,50 @@

#include <fstream>
#include <sstream>
#include <ginac/ginac.h>
#include <string>
#include <vector>

typedef std::vector < double > state_type;
typedef void (*func_t)(const state_type &, state_type &, const double );

struct soldif
{
double N; //число шагов
double dt; //точность
int dln; //размерность пространства
std::string str_sm; //название переменной
state_type x0; //начальное положение
int nsv; //число свободных переменных
int nv; //размерность вектора начального положения
std::vector<std::string> eqn; //уравнения
std::vector<std::string> eqn_svob; //уравнения свободных недоопределенной системы nsv=2,3..
int dln; //размерность пространства
std::string str_sm; //название переменной
std::vector<std::string> up; //управляющие параметры
bool npp; //не перезаписывать cpp-файл
bool noc; //не компилировать cpp-файл
};

class sys_osn_dan
{
public:
sys_osn_dan(std::stringstream &); // исходные данные
void set_par_diff(double , double );
soldif get_par_diff();
sys_osn_dan(std::stringstream &, const bool, const bool); // исходные данные
//sys_osn_dan(draghilevinout &); // исходные данные
void set_par_diff(double &_N, double &_dt){N=_N; dt=_dt;};
void set_coord(state_type &_x) {x=_x;};
void set_resIN(state_type &_coord) {res=_coord;};
state_type &get_resOUT() {return res;};
soldif &get_par_diff();
private:
void isxod_dan(std::stringstream &); // исходные данные
std::string &razdto_(std::string &); //замена разделителей на _
soldif A;
int n_svob; //число свободных переменных
int N_var;
std::string dimension, str_sm;
static unsigned dim_line;
state_type x, coordinate;
state_type x, res;//res - полученное решение
double dt, N;
std::vector<std::string> equations, equations_svob;
bool nocomp, nocpp;
std::vector<std::string> equations, equations_svob, uprav_par;
};






#endif

+ 1
- 1
test/Drag_example_8 Zobrazit soubor

@@ -1,6 +1,6 @@
x 1e-3 1.1e3 3d
0 3.265 -0.157 -3.052 0 0
circle3(1,23,0,1.001)#x-1, y-2, z-3
circle3(1,yz,0,1.001)#xy,yz,xz
x[0]
x[4]
x[5]

Načítá se…
Zrušit
Uložit