diff --git a/src/Neighbor.cpp b/src/Neighbor.cpp --- a/src/Neighbor.cpp +++ b/src/Neighbor.cpp @@ -29,11 +29,11 @@ Neighbor::Neighbor(void): cell(NULL), nb1(NULL), nb2(NULL){} Neighbor::Neighbor(Cell *c, Node *n1, Node *n2): - cell(c), nb1(n1), nb2(n2){} + cell(c), nb1(n1), nb2(n2){} Neighbor::Neighbor(const Neighbor &src): cell(src.cell), nb1(src.nb1), nb2(src.nb2){} // copy constructor - + bool Neighbor::CellEquals(int i) const { return cell->Index() == i; } bool Neighbor::Cmp(Neighbor &c) const { return cell->Index() < c.cell->Index(); } // Compare cell indices not pointers. bool Neighbor::Eq(Neighbor &c) const { return cell->Index() == c.cell->Index(); } @@ -42,5 +42,6 @@ Cell* Neighbor::getCell(void) const { re bool neighbor_cell_eq(const Neighbor &n1, const Neighbor &n2) { return (n1.getCell())->Index() == (n2.getCell())->Index(); // Compare cell indices not pointers. } - -// finis + +/* finis */ + diff --git a/src/Neighbor.h b/src/Neighbor.h --- a/src/Neighbor.h +++ b/src/Neighbor.h @@ -50,7 +50,7 @@ class Neighbor { Neighbor(void); Neighbor(Cell*, Node*, Node*); Neighbor(const Neighbor&); - + bool CellEquals(int) const; bool Cmp(Neighbor&) const; bool Eq(Neighbor&) const; @@ -68,4 +68,5 @@ bool neighbor_cell_eq(const Neighbor &n1 #endif -// finis +/* finis */ + diff --git a/src/OptionFileDialog.cpp b/src/OptionFileDialog.cpp --- a/src/OptionFileDialog.cpp +++ b/src/OptionFileDialog.cpp @@ -27,23 +27,24 @@ using namespace std; static const std::string _module_id("$Id$"); -OptionFileDialog::OptionFileDialog(QWidget *parent, const char *name, bool modal) : Q3FileDialog(parent, name, modal) { +OptionFileDialog::OptionFileDialog(QWidget *parent, const char *name, bool modal) : Q3FileDialog(parent, name, modal) +{ + //cerr << "This is an OptionFileDialog\n"; + geometrycheck = new QCheckBox("geometry",this); + geometrycheck -> setCheckState(Qt::Checked); - //cerr << "This is an OptionFileDialog\n"; - geometrycheck = new QCheckBox("geometry",this); - geometrycheck -> setCheckState(Qt::Checked); - - parcheck = new QCheckBox("parameters", this); - parcheck -> setCheckState(Qt::Checked); - - addToolButton(geometrycheck); - addToolButton(parcheck); + parcheck = new QCheckBox("parameters", this); + parcheck -> setCheckState(Qt::Checked); + addToolButton(geometrycheck); + addToolButton(parcheck); }; -OptionFileDialog::OptionFileDialog ( const QString & dirName, const QString & filter , QWidget * parent, const char * name , bool modal ) : - Q3FileDialog(dirName, filter, parent, name, modal) { - - cerr << "This is an OptionFileDialog\n"; - - }; +OptionFileDialog::OptionFileDialog ( const QString & dirName, const QString & filter , + QWidget * parent, const char * name , bool modal ) : + Q3FileDialog(dirName, filter, parent, name, modal) { + + cerr << "This is an OptionFileDialog\n"; +}; + +/* finis */ diff --git a/src/OptionFileDialog.h b/src/OptionFileDialog.h --- a/src/OptionFileDialog.h +++ b/src/OptionFileDialog.h @@ -27,17 +27,20 @@ #include class OptionFileDialog : public Q3FileDialog { - Q_OBJECT -public: - OptionFileDialog(QWidget *parent = 0, const char *name = 0, bool modal = false); - OptionFileDialog ( const QString & dirName, const QString & filter = QString(), QWidget * parent = 0, const char * name = 0, bool modal = false ); - - bool readGeometryP(void) const { return geometrycheck->checkState()==Qt::Checked; } - bool readParametersP(void) const { return parcheck->checkState()==Qt::Checked; } + Q_OBJECT + public: + OptionFileDialog(QWidget *parent = 0, const char *name = 0, bool modal = false); + OptionFileDialog ( const QString & dirName, const QString & filter = QString(), + QWidget * parent = 0, const char * name = 0, bool modal = false ); -private: - QCheckBox *geometrycheck; - QCheckBox *parcheck; + bool readGeometryP(void) const { return geometrycheck->checkState()==Qt::Checked; } + bool readParametersP(void) const { return parcheck->checkState()==Qt::Checked; } + + private: + QCheckBox *geometrycheck; + QCheckBox *parcheck; }; #endif + +/* finis */ diff --git a/src/UniqueMessage.cpp b/src/UniqueMessage.cpp --- a/src/UniqueMessage.cpp +++ b/src/UniqueMessage.cpp @@ -32,54 +32,53 @@ static const std::string _module_id("$Id using namespace std; UniqueMessageBox::UniqueMessageBox ( /* Icon icon,*/ - const QString & title, - const QString & text, - QWidget * parent , - Qt::WindowFlags f ) : -QDialog(parent, f) { - - label = new QLabel(text); - boxtext = text; - - show_again = new QCheckBox(tr("Do not show this message again")); - okButton = new QPushButton(tr("Ok")); - - if (issued_messages.contains(boxtext) ) { - - cerr << "Saw message before\n"; - display = false; - } else { - display=true; - } - - connect(okButton, SIGNAL(clicked()), this, SLOT(close()) ); - QHBoxLayout *hlayout = new QHBoxLayout; - hlayout->addWidget(label); - hlayout->addWidget(okButton); - QVBoxLayout *layout = new QVBoxLayout; - layout->addLayout(hlayout); - layout->addWidget(show_again); - setLayout(layout); - setWindowTitle(title); + const QString & title, + const QString & text, + QWidget * parent , + Qt::WindowFlags f ) : + QDialog(parent, f) { + + label = new QLabel(text); + boxtext = text; + + show_again = new QCheckBox(tr("Do not show this message again")); + okButton = new QPushButton(tr("Ok")); + + if (issued_messages.contains(boxtext) ) { + + cerr << "Saw message before\n"; + display = false; + } else { + display=true; + } + + connect(okButton, SIGNAL(clicked()), this, SLOT(close()) ); + QHBoxLayout *hlayout = new QHBoxLayout; + hlayout->addWidget(label); + hlayout->addWidget(okButton); + QVBoxLayout *layout = new QVBoxLayout; + layout->addLayout(hlayout); + layout->addWidget(show_again); + setLayout(layout); + setWindowTitle(title); }; - + UniqueMessageBox::~UniqueMessageBox(void) { - - if (show_again->checkState() == Qt::Checked ) { - cerr << "Message won't be shown again\n"; - issued_messages << boxtext; - } + if (show_again->checkState() == Qt::Checked ) { + cerr << "Message won't be shown again\n"; + issued_messages << boxtext; + } } int UniqueMessageBox::exec(void) { - - if (display) - return QDialog::exec(); - else { - return 1; - } + if (display) + return QDialog::exec(); + else { + return 1; + } } - + QStringList UniqueMessageBox::issued_messages; - + +/* finis */ diff --git a/src/UniqueMessage.h b/src/UniqueMessage.h --- a/src/UniqueMessage.h +++ b/src/UniqueMessage.h @@ -31,24 +31,26 @@ #include class UniqueMessageBox : public QDialog { - Q_OBJECT - -public: - UniqueMessageBox ( /* Icon icon,*/ - const QString & title, - const QString & text, - /* StandardButtons buttons = Ok, */ - QWidget * parent = 0 , Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint ); - ~UniqueMessageBox(); - int exec(void); - -private: - static QStringList issued_messages; - bool display; - QCheckBox *show_again; - QPushButton *okButton; - QLabel *label; - QString boxtext; + Q_OBJECT + + public: + UniqueMessageBox ( /* Icon icon,*/ + const QString & title, + const QString & text, + /* StandardButtons buttons = Ok, */ + QWidget * parent = 0 , Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint ); + ~UniqueMessageBox(); + int exec(void); + + private: + static QStringList issued_messages; + bool display; + QCheckBox *show_again; + QPushButton *okButton; + QLabel *label; + QString boxtext; }; #endif + +/* finis */ diff --git a/src/VirtualLeaf.cpp b/src/VirtualLeaf.cpp --- a/src/VirtualLeaf.cpp +++ b/src/VirtualLeaf.cpp @@ -77,10 +77,10 @@ public: class EdgeSource { - + public: void operator() (Cell &c) { - + if (c.AtBoundaryP()) { cerr << "Cell " << c.Index() << " is a source cell.\n"; c.SetSource(0,par.source); @@ -118,7 +118,7 @@ public: if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) { if (m.ShowToolTipsP()) { QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr()); - + info_string += "\n" + c.printednodelist(); c.Draw(&canvas, info_string); } else { @@ -138,10 +138,11 @@ public: Mesh mesh; bool batch=false; -void MainBase::Plot(int resize_stride) { - +void MainBase::Plot(int resize_stride) +{ + clear(); - + static int count=0; if (resize_stride) { if ( !((++count)%resize_stride) ) { @@ -149,58 +150,58 @@ void MainBase::Plot(int resize_stride) { } } mesh.LoopCells(DrawCell(),canvas,*this); - + if (ShowNodeNumbersP()) mesh.LoopNodes( bind2nd (mem_fun_ref ( &Node::DrawIndex), &canvas ) ) ; if (ShowCellNumbersP()) mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawIndex), &canvas ) ) ; - + if (ShowCellAxesP()) mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawAxis), &canvas ) ); - + if (ShowCellStrainP()) mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawStrain), &canvas ) ); - + if (ShowWallsP()) mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::Draw ), &canvas ) ); - + if (ShowApoplastsP()) mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) ); - + if (ShowMeshP()) mesh.DrawNodes(&canvas); - + if (ShowBoundaryOnlyP()) mesh.DrawBoundary(&canvas); if ( ( batch || MovieFramesP() )) { - + static int frame = 0; // frame numbers are sequential for the most frequently written file type. // for the less frequently written file type they match the other type if (!(count%par.storage_stride) ) { - + stringstream fname; fname << par.datadir << "/leaf."; fname.fill('0'); fname.width(6); - + fname << frame << ".jpg"; if (par.storage_stride <= par.xml_storage_stride) { frame++; } - + // Write high-res JPG snapshot every plot step Save(fname.str().c_str(), "JPEG",1024,768); } - + if (!(count%par.xml_storage_stride)) { stringstream fname; fname << par.datadir << "/leaf."; fname.fill('0'); fname.width(6); fname << frame << ".xml"; - + if (par.xml_storage_stride < par.storage_stride) { frame++; } @@ -213,81 +214,73 @@ void MainBase::Plot(int resize_stride) { INIT { - + //mesh.SetSimPlugin(plugin); if (leaffile) { xmlNode *settings; mesh.XMLRead(leaffile, &settings); - + main_window->XMLReadSettings(settings); xmlFree(settings); main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str())); - + } else { mesh.StandardInit(); } } TIMESTEP { - + static int i=0; static int t=0; static int ncells; - + if (!batch) { UserMessage(QString("Time: %1").arg(mesh.getTimeHours().c_str()),0); } - + ncells=mesh.NCells(); - - + + double dh; - + if(DynamicCellsP()) { dh = mesh.DisplaceNodes(); - + // Only allow for node insertion, cell division and cell growth // if the system has equillibrized // i.e. cell wall tension equillibrization is much faster // than biological processes, including division, cell wall yielding // and cell expansion mesh.InsertNodes(); // (this amounts to cell wall yielding) - + if ( (-dh) < par.energy_threshold) { - + mesh.IncreaseCellCapacityIfNecessary(); mesh.DoCellHouseKeeping(); //mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division - + // Reaction diffusion mesh.ReactDiffuse(par.rd_dt); - t++; - Plot(par.resize_stride); - } - } else { - mesh.ReactDiffuse(par.rd_dt); - Plot(par.resize_stride); - } - i++; return mesh.getTime(); - } - - - + + + /* Called if a cell is clicked */ -void Cell::OnClick(QMouseEvent *e) { +void Cell::OnClick(QMouseEvent *e) +{ e = NULL; // use assignment merely to obviate compilation warning } - + /* Custom message handler - Default appends a newline character to the end of each line. */ void vlMessageOutput(QtMsgType type, const char *msg) @@ -311,23 +304,19 @@ void vlMessageOutput(QtMsgType type, con abort(); } } - + Parameter par; - + int main(int argc,char **argv) { - + try { - - int c; - - char *leaffile=0; char *modelfile=0; - + while (1) { - + //int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { @@ -335,30 +324,30 @@ int main(int argc,char **argv) { {"leaffile", required_argument, NULL, 'l'}, {"model", required_argument, NULL, 'm'} }; - + // short option 'p' creates trouble for non-commandline usage on MacOSX. Option -p changed to -P (capital) static char *short_options = "blm"; c = getopt_long (argc, argv, "bl:m:", long_options, &option_index); if (c == -1) break; - - + + if (c==0) { printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); - + c = short_options[option_index]; } - + switch (c) { case 'b': cerr << "Running in batch mode\n"; batch=true; break; - + case 'l': leaffile=strdup(optarg); if (!leaffile) { @@ -373,16 +362,16 @@ int main(int argc,char **argv) { throw("Out of memory"); } break; - + case '?': break; - + default: printf ("?? getopt returned character code 0%o ??\n", c); } } - - + + if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) @@ -393,9 +382,9 @@ int main(int argc,char **argv) { bool useGUI = !batch; qInstallMsgHandler(vlMessageOutput); // custom message handler QApplication app(argc,argv,useGUI); - + - + QPalette tooltippalette = QToolTip::palette(); QColor transparentcolor = QColor(tooltippalette.brush(QPalette::Window).color()); @@ -404,7 +393,7 @@ int main(int argc,char **argv) { QGraphicsScene canvas(0,0,8000,6000); - + if (useGUI) { main_window=new Main(canvas, mesh); if ( QApplication::desktop()->width() > ((Main *)main_window)->width() + 10 @@ -417,11 +406,8 @@ int main(int argc,char **argv) { } } else { main_window=new MainBase(canvas, mesh); - } - - canvas.setSceneRect(QRectF()); if (!batch) { QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) ); @@ -432,16 +418,15 @@ int main(int argc,char **argv) { if (useGUI) model_catalogue.PopulateModelMenu(); model_catalogue.InstallFirstModel(); - if (leaffile) main_window->Init(leaffile); - + Cell::SetMagnification(1); Cell::setOffset(0,0); - + main_window->FitLeafToCanvas(); - + main_window->Plot(); if (batch) { @@ -449,11 +434,9 @@ int main(int argc,char **argv) { do { t = main_window->TimeStep(); } while (t < par.maxt); - } else return app.exec(); - - + } catch (const char *message) { if (batch) { cerr << "Exception caught:" << endl; @@ -477,3 +460,5 @@ int main(int argc,char **argv) { } } } + +/* finis */ diff --git a/src/apoplastitem.cpp b/src/apoplastitem.cpp --- a/src/apoplastitem.cpp +++ b/src/apoplastitem.cpp @@ -32,44 +32,44 @@ static const std::string _module_id("$Id$"); ApoplastItem::ApoplastItem( Wall *w, QGraphicsScene *canvas ) -: QGraphicsLineItem( 0, canvas ), SimItemBase( w, canvas){ - - setColor(); - - // line with "PIN1"is a bit inside the cell wall - Vector edgevec = (*(w->N2())) - (*(w->N1())); - Vector perp = edgevec.Normalised().Perp2D(); - - Vector offs = Cell::Offset(); - double factor = Cell::Factor(); - - Vector from = ( offs + *(w->N1()) ) * factor; - Vector to = ( offs + *(w->N2()) ) *factor; - - - setLine(( from.x ), - ( from.y ), - ( to.x ), - ( to.y ) ); - setZValue(12); + : QGraphicsLineItem( 0, canvas ), SimItemBase( w, canvas){ + + setColor(); + + // line with "PIN1"is a bit inside the cell wall + Vector edgevec = (*(w->N2())) - (*(w->N1())); + Vector perp = edgevec.Normalised().Perp2D(); + + Vector offs = Cell::Offset(); + double factor = Cell::Factor(); + + Vector from = ( offs + *(w->N1()) ) * factor; + Vector to = ( offs + *(w->N2()) ) *factor; + + + setLine(( from.x ), + ( from.y ), + ( to.x ), + ( to.y ) ); + setZValue(12); } void ApoplastItem::setColor(void) { - - QColor diffcolor; - static const QColor purple("Purple"); - static const QColor blue("blue"); - - Wall *w=&getWall(); - double val = w->getApoplast(2); + + QColor diffcolor; + static const QColor purple("Purple"); + static const QColor blue("blue"); - diffcolor.setRgb( 0,0,(int)( ( val / (1 + val) )*255.)); - setPen (QPen(diffcolor, 20) ); + Wall *w=&getWall(); + double val = w->getApoplast(2); + diffcolor.setRgb( 0,0,(int)( ( val / (1 + val) )*255.)); + setPen (QPen(diffcolor, 20) ); } void ApoplastItem::OnClick(QMouseEvent *e) { e = NULL; // merely to obviate compilation warnings } +/* finis*/ diff --git a/src/apoplastitem.h b/src/apoplastitem.h --- a/src/apoplastitem.h +++ b/src/apoplastitem.h @@ -23,6 +23,7 @@ #ifndef _APOPLASTITEM_H_ #define _APOPLASTITEM_H_ + #include #include #include @@ -35,14 +36,16 @@ class ApoplastItem : public QGraphicsLineItem, public SimItemBase { -public: - ApoplastItem( Wall *n, QGraphicsScene *canvas ); - virtual ~ApoplastItem() {} - Wall &getWall(void) const { return *class_cast(obj); } - void OnClick(QMouseEvent *e); - void setColor(void); -private: - int wn; + public: + ApoplastItem( Wall *n, QGraphicsScene *canvas ); + virtual ~ApoplastItem() {} + Wall &getWall(void) const { return *class_cast(obj); } + void OnClick(QMouseEvent *e); + void setColor(void); + private: + int wn; }; #endif + +/* finis*/ diff --git a/src/build_models/auxingrowthplugin.cpp b/src/build_models/auxingrowthplugin.cpp --- a/src/build_models/auxingrowthplugin.cpp +++ b/src/build_models/auxingrowthplugin.cpp @@ -37,238 +37,235 @@ bool batch = false; // To be executed after cell division -void AuxinGrowthPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { +void AuxinGrowthPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) +{ parent_info = NULL; // merely to obviate compile time error - // Auxin distributes between parent and daughter according to area - double area1 = daughter1->Area(), area2 = daughter2->Area(); - double tot_area = area1 + area2; + // Auxin distributes between parent and daughter according to area + double area1 = daughter1->Area(), area2 = daughter2->Area(); + double tot_area = area1 + area2; - daughter1->SetChemical(0,daughter1->Chemical(0)*(area1/tot_area)); - daughter2->SetChemical(0,daughter2->Chemical(0)*(area2/tot_area)); + daughter1->SetChemical(0,daughter1->Chemical(0)*(area1/tot_area)); + daughter2->SetChemical(0,daughter2->Chemical(0)*(area2/tot_area)); - // After divisions, parent and daughter cells get a standard stock of PINs. - daughter1->SetChemical(1, par->initval[1]); - daughter2->SetChemical(1, par->initval[1]); + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); - // Reset transporter values of parent and daughter - QList walls; - foreach(WallBase *w, walls) { - w->setTransporter(daughter1, 1, 0.); - } - + // Reset transporter values of parent and daughter + QList walls; + foreach(WallBase *w, walls) { + w->setTransporter(daughter1, 1, 0.); + } } -void AuxinGrowthPlugin::SetCellColor(CellBase *c, QColor *color) { +void AuxinGrowthPlugin::SetCellColor(CellBase *c, QColor *color) +{ - // Red: PIN1 - // Green: Auxin - if (c->CellType()==1) color->setNamedColor("Blue"); - else color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.),/* (chem[2]/(1+chem[2]) *255.) */ 0); - + // Red: PIN1 + // Green: Auxin + if (c->CellType()==1) + color->setNamedColor("Blue"); + else + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); } -void AuxinGrowthPlugin::CellHouseKeeping(CellBase *c) { - - if (c->Boundary()==CellBase::None) { - if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { - c->SetChemical(0,0); - c->Divide(); - } - if (c->Chemical(0)>0.6) { - c->SetCellType(1); - } - // expand according to auxin concentration - c->EnlargeTargetArea(par->auxin_dependent_growth?(c->Chemical(0)/(1.+c->Chemical(0)))*par->cell_expansion_rate:par->cell_expansion_rate); - } - - +void AuxinGrowthPlugin::CellHouseKeeping(CellBase *c) +{ + if (c->Boundary()==CellBase::None) { + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { + c->SetChemical(0,0); + c->Divide(); + } + if (c->Chemical(0)>0.6) { + c->SetCellType(1); + } + // expand according to auxin concentration + c->EnlargeTargetArea(par->auxin_dependent_growth?(c->Chemical(0)/(1.+c->Chemical(0)))*par->cell_expansion_rate:par->cell_expansion_rate); + } } -void AuxinGrowthPlugin::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { +void AuxinGrowthPlugin::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) +{ - // leaf edge is const source of auxin - // (Neumann boundary condition: we specify the influx) - if (w->C2()->BoundaryPolP()) { - if (w->AuxinSource()) { - double aux_flux = par->leaf_tip_source * w->Length(); - dchem_c1[0]+= aux_flux; - return; - } else { - return; - } - } + // leaf edge is const source of auxin + // (Neumann boundary condition: we specify the influx) + if (w->C2()->BoundaryPolP()) { + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0]+= aux_flux; + return; + } else { + return; + } + } - - if (w->C1()->BoundaryPolP()) { + if (w->C1()->BoundaryPolP()) { - if (w->AuxinSource()) { - double aux_flux = par->leaf_tip_source * w->Length(); - dchem_c2[0] += aux_flux; - return; - } else { + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c2[0] += aux_flux; + return; + } else { - if (w->AuxinSink()) { + if (w->AuxinSink()) { - // efflux into Shoot Apical meristem - // we assume all PINs are directed towards shoot apical meristem - dchem_c2[0] -= par->sam_efflux * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)); + // efflux into Shoot Apical meristem + // we assume all PINs are directed towards shoot apical meristem + dchem_c2[0] -= par->sam_efflux * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)); - return; - } else - return; - } + return; + } else + return; } + } - // Passive fluxes (Fick's law) - // only auxin flux now - // flux depends on edge length and concentration difference - int c=0; - double phi = w->Length() * ( par->D[c] ) * ( w->C2()->Chemical(c) - w->C1()->Chemical(c) ); - dchem_c1[c] += phi; - dchem_c2[c] -= phi; + // Passive fluxes (Fick's law) + // only auxin flux now + // flux depends on edge length and concentration difference + int c=0; + double phi = w->Length() * ( par->D[c] ) * ( w->C2()->Chemical(c) - w->C1()->Chemical(c) ); + dchem_c1[c] += phi; + dchem_c2[c] -= phi; - // Active fluxes (PIN1 mediated transport) + // Active fluxes (PIN1 mediated transport) - // (Transporters measured in moles, here) - // efflux from cell 1 to cell 2 - double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); - // efflux from cell 2 to cell 1 - double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); - dchem_c1[0] += trans21 - trans12; - dchem_c2[0] += trans12 - trans21; + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; } -void AuxinGrowthPlugin::WallDynamics(Wall *w, double *dw1, double *dw2) { - - - - // Cells polarize available PIN1 to Shoot Apical Meristem - if (w->C2()->BoundaryPolP()) { - if (w->AuxinSink()) { +void AuxinGrowthPlugin::WallDynamics(Wall *w, double *dw1, double *dw2) +{ + // Cells polarize available PIN1 to Shoot Apical Meristem + if (w->C2()->BoundaryPolP()) { + if (w->AuxinSink()) { - dw1[0] = 0.; dw2[0] = 0.; + dw1[0] = 0.; dw2[0] = 0.; - // assume high auxin concentration in SAM, to convince PIN1 to polarize to it - // exocytosis regulated0 - double nb_auxin = par->sam_auxin; - double receptor_level = nb_auxin * par->r / (par->kr + nb_auxin); + // assume high auxin concentration in SAM, to convince PIN1 to polarize to it + // exocytosis regulated0 + double nb_auxin = par->sam_auxin; + double receptor_level = nb_auxin * par->r / (par->kr + nb_auxin); - dw1[1] = par->k1 * w->C1()->Chemical(1) * receptor_level /( par->km + w->C1()->Chemical(1) ) - par->k2 * w->Transporters1(1); + dw1[1] = par->k1 * w->C1()->Chemical(1) * receptor_level /( par->km + w->C1()->Chemical(1) ) - par->k2 * w->Transporters1(1); - dw2[1] = 0.; - return; + dw2[1] = 0.; + return; - } else { - dw1[0]=dw2[0]=dw1[1]=dw2[1]; - return; - } + } else { + dw1[0]=dw2[0]=dw1[1]=dw2[1]; + return; } + } - if (w->C1()->BoundaryPolP()) { - if (w->AuxinSink()) { + if (w->C1()->BoundaryPolP()) { + if (w->AuxinSink()) { - dw1[0] = 0.; dw2[0] = 0.; + dw1[0] = 0.; dw2[0] = 0.; - // assume high auxin concentration in SAM, to convince PIN1 to polarize to it - // exocytosis regulated - double nb_auxin = par->sam_auxin; - double receptor_level = nb_auxin * par->r / (par->kr + nb_auxin); - dw2[1] = par->k1 * w->C2()->Chemical(1) * receptor_level /( par->km + w->C2()->Chemical(1) ) - par->k2 * w->Transporters2(1); + // assume high auxin concentration in SAM, to convince PIN1 to polarize to it + // exocytosis regulated + double nb_auxin = par->sam_auxin; + double receptor_level = nb_auxin * par->r / (par->kr + nb_auxin); + dw2[1] = par->k1 * w->C2()->Chemical(1) * receptor_level /( par->km + w->C2()->Chemical(1) ) - par->k2 * w->Transporters2(1); - dw1[1] = 0.; - return; + dw1[1] = 0.; + return; - } else { - dw1[0]=dw2[0]=dw1[1]=dw2[1]; - return; - } + } else { + dw1[0]=dw2[0]=dw1[1]=dw2[1]; + return; } + } - // PIN1 localization at wall 1 - // Note: chemical 0 is Auxin (intracellular storage only) - // Chemical 1 is PIN1 (walls and intracellular storage) - //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ - // Note that Pij is measured in term of concentration (mol/L) - // Pi in terms of quantity (mol) + // PIN1 localization at wall 1 + // Note: chemical 0 is Auxin (intracellular storage only) + // Chemical 1 is PIN1 (walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) - double dPijdt1=0., dPijdt2=0.; + double dPijdt1=0., dPijdt2=0.; - // normal cell - double auxin2 = w->C2()->Chemical(0); - double receptor_level1 = auxin2 * par->r / (par->kr + auxin2); + // normal cell + double auxin2 = w->C2()->Chemical(0); + double receptor_level1 = auxin2 * par->r / (par->kr + auxin2); - dPijdt1 = - // exocytosis regulated + dPijdt1 = + // exocytosis regulated par->k1 * w->C1()->Chemical(1) * receptor_level1 / ( par->km + w->C1()->Chemical(1) ) - par->k2 * w->Transporters1(1); - double auxin1 = w->C1()->Chemical(0); - double receptor_level2 = auxin1 * par->r / (par->kr + auxin1); + double auxin1 = w->C1()->Chemical(0); + double receptor_level2 = auxin1 * par->r / (par->kr + auxin1); - // normal cell - dPijdt2 = + // normal cell + dPijdt2 = - // exocytosis regulated - par->k1 * w->C2()->Chemical(1) * receptor_level2 / ( par->km + w->C2()->Chemical(1) ) - par->k2 * w->Transporters2(1); + // exocytosis regulated + par->k1 * w->C2()->Chemical(1) * receptor_level2 / ( par->km + w->C2()->Chemical(1) ) - par->k2 * w->Transporters2(1); - /* PIN1 of neighboring vascular cell inhibits PIN1 endocytosis */ + /* PIN1 of neighboring vascular cell inhibits PIN1 endocytosis */ - dw1[0] = 0.; dw2[0] = 0.; - dw1[1] = dPijdt1; - dw2[1] = dPijdt2; + dw1[0] = 0.; dw2[0] = 0.; + dw1[1] = dPijdt1; + dw2[1] = dPijdt2; } -double AuxinGrowthPlugin::complex_PijAj(CellBase *here, CellBase *nb, Wall *w) { - - // gives the amount of complex "auxinreceptor-Pin1" at the wall (at QSS) - //return here.Chemical(1) * nb.Chemical(0) / ( par->km + here.Chemical(1)); - - double nb_aux = (nb->BoundaryPolP() && w->AuxinSink()) ? par->sam_auxin : nb->Chemical(0); - double receptor_level = nb_aux * par->r / (par->kr + nb_aux); - - return here->Chemical(1) * receptor_level / ( par->km + here->Chemical(1)); - -} -void AuxinGrowthPlugin::CellDynamics(CellBase *c, double *dchem) { - // Note: Pi and Pij measured in numbers of molecules, not concentrations - double dPidt = 0.; - - double sum_Pij = c->SumTransporters( 1 ); - - // exocytosis regulated: +double AuxinGrowthPlugin::complex_PijAj(CellBase *here, CellBase *nb, Wall *w) +{ + // gives the amount of complex "auxinreceptor-Pin1" at the wall (at QSS) + //return here.Chemical(1) * nb.Chemical(0) / ( par->km + here.Chemical(1)); - dPidt = -par->k1 * c->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &AuxinGrowthPlugin::complex_PijAj ) ) + par->k2 * sum_Pij; - - // production of PIN depends on auxin concentration - dPidt += (c->AtBoundaryP()?par->pin_prod_in_epidermis:par->pin_prod) * c->Chemical(0) - c->Chemical(1) * par->pin_breakdown; + double nb_aux = (nb->BoundaryPolP() && w->AuxinSink()) ? par->sam_auxin : nb->Chemical(0); + double receptor_level = nb_aux * par->r / (par->kr + nb_aux); - // no PIN production in SAM - if (c->Boundary() == CellBase::SAM) { - dchem[1]=0.; - dchem[0]= - par->sam_auxin_breakdown * c->Chemical(0); - } else { - - dchem[1] = dPidt; - - - // source of auxin - dchem[0] = par->aux_cons - par->aux_breakdown * c->Chemical(0); - - } - - + return here->Chemical(1) * receptor_level / ( par->km + here->Chemical(1)); } +void AuxinGrowthPlugin::CellDynamics(CellBase *c, double *dchem) +{ + // Note: Pi and Pij measured in numbers of molecules, not concentrations + double dPidt = 0.; + + double sum_Pij = c->SumTransporters( 1 ); + + // exocytosis regulated: + + dPidt = -par->k1 * c->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &AuxinGrowthPlugin::complex_PijAj ) ) + par->k2 * sum_Pij; + + // production of PIN depends on auxin concentration + dPidt += (c->AtBoundaryP()?par->pin_prod_in_epidermis:par->pin_prod) * c->Chemical(0) - c->Chemical(1) * par->pin_breakdown; + + // no PIN production in SAM + if (c->Boundary() == CellBase::SAM) { + dchem[1]=0.; + dchem[0]= - par->sam_auxin_breakdown * c->Chemical(0); + } else { + + dchem[1] = dPidt; + + // source of auxin + dchem[0] = par->aux_cons - par->aux_breakdown * c->Chemical(0); + } +} + Q_EXPORT_PLUGIN2(auxingrowthplugin, AuxinGrowthPlugin) + +/* finis */ diff --git a/src/build_models/auxingrowthplugin.h b/src/build_models/auxingrowthplugin.h --- a/src/build_models/auxingrowthplugin.h +++ b/src/build_models/auxingrowthplugin.h @@ -30,34 +30,36 @@ class AuxinGrowthPlugin : public QObject, SimPluginInterface { - Q_OBJECT - Q_INTERFACES(SimPluginInterface); + Q_OBJECT + Q_INTERFACES(SimPluginInterface); -public: - virtual QString ModelID(void) { return QString( "Auxin accumulation and growth" ); } + public: + virtual QString ModelID(void) { return QString( "Auxin accumulation and growth" ); } - // Executed after the cellular mechanics steps have equillibrized - virtual void CellHouseKeeping (CellBase *c); - // Differential equations describing transport of chemicals from cell to cell - virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); - // Differential equations describing chemical reactions taking place at or near the cell walls - // (e.g. PIN accumulation) - virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); - // Differential equations describing chemical reactions inside the cells - virtual void CellDynamics(CellBase *c, double *dchem); + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); - // to be executed after a cell division - virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); - // to be executed for coloring a cell - virtual void SetCellColor(CellBase *c, QColor *color); - // return number of chemicals - virtual int NChem(void) { return 2; } + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void) { return 2; } -private: - double complex_PijAj(CellBase *here, CellBase *nb, Wall *w); + private: + double complex_PijAj(CellBase *here, CellBase *nb, Wall *w); }; #endif + +/* finis */ diff --git a/src/build_models/meinhardtplugin.cpp b/src/build_models/meinhardtplugin.cpp --- a/src/build_models/meinhardtplugin.cpp +++ b/src/build_models/meinhardtplugin.cpp @@ -41,90 +41,86 @@ void MeinhardtPlugin::OnDivide(ParentInf void MeinhardtPlugin::SetCellColor(CellBase *c, QColor *color) { - if (fpclassify(c->Chemical(0))==FP_NAN) { - // somehow the function isnan doesn't work properly on my system... SuSE Linux - // 10.0 64-bits (isnan seems not be implemented using fpclassify). - MyWarning::warning("Whoops! Numerical instability!!"); - color->setNamedColor("red"); - } else { - double range_min = 0.;//, range_max = 1.; - if (c->Chemical(0)setNamedColor("blue"); - } else { - color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.),(c->Chemical(3)/(1+c->Chemical(3)) *255.) ); - } - - } + if (fpclassify(c->Chemical(0))==FP_NAN) { + // somehow the function isnan doesn't work properly on my system... SuSE Linux + // 10.0 64-bits (isnan seems not be implemented using fpclassify). + MyWarning::warning("Whoops! Numerical instability!!"); + color->setNamedColor("red"); + } else { + double range_min = 0.;//, range_max = 1.; + if (c->Chemical(0)setNamedColor("blue"); + } else { + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.),(c->Chemical(3)/(1+c->Chemical(3)) *255.) ); + } + } } void MeinhardtPlugin::CellHouseKeeping(CellBase *c) { - if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { - c->Divide(); - } + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { + c->Divide(); + } - // cell expansion is inhibited by substrate (chem 3) - if (!par->constituous_expansion_limit || c->NCells()constituous_expansion_limit) { - c->EnlargeTargetArea(par->cell_expansion_rate ); - } else { - if (c->Chemical(0)<0.5) { - double tmp; - c->EnlargeTargetArea((tmp=(1.-par->vessel_inh_level*c->Chemical(3))*par->cell_expansion_rate /* + c->Chemical(4)*/)<0?0:tmp); - } else { - c->EnlargeTargetArea(par->vessel_expansion_rate); - } - } - + // cell expansion is inhibited by substrate (chem 3) + if (!par->constituous_expansion_limit || c->NCells()constituous_expansion_limit) { + c->EnlargeTargetArea(par->cell_expansion_rate ); + } else { + if (c->Chemical(0)<0.5) { + double tmp; + c->EnlargeTargetArea((tmp=(1.-par->vessel_inh_level*c->Chemical(3))*par->cell_expansion_rate /* + c->Chemical(4)*/)<0?0:tmp); + } else { + c->EnlargeTargetArea(par->vessel_expansion_rate); + } + } } void MeinhardtPlugin::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { - // No flux boundaries for all chemicals, except activator: boundary is sink + // No flux boundaries for all chemicals, except activator: boundary is sink if (w->C1()->BoundaryPolP() || w->C2()->BoundaryPolP()) { - if (w->C1()->BoundaryPolP()) { - dchem_c2[1] -= w->Length() * ( par->D[1] ) * ( w->C2()->Chemical(1) ); - } else { - dchem_c1[1] -= w->Length() * ( par->D[1] ) * ( w->C1()->Chemical(1) ); - } - return; - } + if (w->C1()->BoundaryPolP()) { + dchem_c2[1] -= w->Length() * ( par->D[1] ) * ( w->C2()->Chemical(1) ); + } else { + dchem_c1[1] -= w->Length() * ( par->D[1] ) * ( w->C1()->Chemical(1) ); + } + return; + } - // Passive fluxes (Fick's law) - for (int c=0;cLength() * ( par->D[c] ) * ( w->C2()->Chemical(c) - w->C1()->Chemical(c) ); - dchem_c1[c] += phi; - dchem_c2[c] -= phi; - } - - + // Passive fluxes (Fick's law) + for (int c=0;cLength() * ( par->D[c] ) * ( w->C2()->Chemical(c) - w->C1()->Chemical(c) ); + dchem_c1[c] += phi; + dchem_c2[c] -= phi; + } } void MeinhardtPlugin::WallDynamics(Wall *w, double *dw1, double *dw2) { w = NULL; - for (int c = 0;cChemical(0); - double A = c->Chemical(1); - double H = c->Chemical(2); - double S = c->Chemical(3); - + double Y = c->Chemical(0); + double A = c->Chemical(1); + double H = c->Chemical(2); + double S = c->Chemical(3); - - dchem[0] = ( par->d * A - par->e * Y + Y*Y/(1 + par->f * Y*Y ) ); - dchem[1] = ( par->c * A*A*S/H - par->mu * A + par->rho0*Y ); - dchem[2] = ( par->c * A*A*S - par->nu*H + par->rho1*Y ); - dchem[3] = ( par->c0 - par->gamma*S - par->eps * Y * S ); + dchem[0] = ( par->d * A - par->e * Y + Y*Y/(1 + par->f * Y*Y ) ); + dchem[1] = ( par->c * A*A*S/H - par->mu * A + par->rho0*Y ); + dchem[2] = ( par->c * A*A*S - par->nu*H + par->rho1*Y ); + dchem[3] = ( par->c0 - par->gamma*S - par->eps * Y * S ); } Q_EXPORT_PLUGIN2(meinhardtplugin, MeinhardtPlugin) + +/* finis */ diff --git a/src/build_models/meinhardtplugin.h b/src/build_models/meinhardtplugin.h --- a/src/build_models/meinhardtplugin.h +++ b/src/build_models/meinhardtplugin.h @@ -30,31 +30,33 @@ class MeinhardtPlugin : public QObject, SimPluginInterface { - Q_OBJECT - Q_INTERFACES(SimPluginInterface); + Q_OBJECT + Q_INTERFACES(SimPluginInterface); -public: - virtual QString ModelID(void) { return QString( "Meinhardt 1976, with growth" ); } + public: + virtual QString ModelID(void) { return QString( "Meinhardt 1976, with growth" ); } - // Executed after the cellular mechanics steps have equillibrized - virtual void CellHouseKeeping (CellBase *c); - // Differential equations describing transport of chemicals from cell to cell - virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); - // Differential equations describing chemical reactions taking place at or near the cell walls - // (e.g. PIN accumulation) - virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); - // Differential equations describing chemical reactions inside the cells - virtual void CellDynamics(CellBase *c, double *dchem); + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); - // to be executed after a cell division - virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); - // to be executed for coloring a cell - virtual void SetCellColor(CellBase *c, QColor *color); - // return number of chemicals - virtual int NChem(void) { return 4; } + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void) { return 4; } }; #endif + +/* finis */ diff --git a/src/build_models/testplugin.cpp b/src/build_models/testplugin.cpp --- a/src/build_models/testplugin.cpp +++ b/src/build_models/testplugin.cpp @@ -42,21 +42,21 @@ void TestPlugin::OnDivide(ParentInfo *pa void TestPlugin::SetCellColor(CellBase *c, QColor *color) { - static QStringList colors; - if (colors.size()==0) { - colors << "red" << "green" << "blue"; - } - color->setNamedColor(colors[c->Index()%colors.size()]); + static QStringList colors; + if (colors.size()==0) { + colors << "red" << "green" << "blue"; + } + color->setNamedColor(colors[c->Index()%colors.size()]); } void TestPlugin::CellHouseKeeping(CellBase *c) { - c->EnlargeTargetArea(par->cell_expansion_rate); - if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { - c->Divide(); - } + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) { + c->Divide(); + } } void TestPlugin::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { @@ -75,3 +75,5 @@ void TestPlugin::CellDynamics(CellBase * } Q_EXPORT_PLUGIN2(testplugin, TestPlugin) + +/* finis */ diff --git a/src/build_models/testplugin.h b/src/build_models/testplugin.h --- a/src/build_models/testplugin.h +++ b/src/build_models/testplugin.h @@ -30,31 +30,33 @@ class TestPlugin : public QObject, SimPluginInterface { - Q_OBJECT - Q_INTERFACES(SimPluginInterface); + Q_OBJECT + Q_INTERFACES(SimPluginInterface); -public: - virtual QString ModelID(void) { return QString( "Test model" ); } + public: + virtual QString ModelID(void) { return QString( "Test model" ); } - // Executed after the cellular mechanics steps have equillibrized - virtual void CellHouseKeeping (CellBase *c); - // Differential equations describing transport of chemicals from cell to cell - virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2); - // Differential equations describing chemical reactions taking place at or near the cell walls - // (e.g. PIN accumulation) - virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); - // Differential equations describing chemical reactions inside the cells - virtual void CellDynamics(CellBase *c, double *dchem); + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); - // to be executed after a cell division - virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); - // to be executed for coloring a cell - virtual void SetCellColor(CellBase *c, QColor *color); - // return number of chemicals - virtual int NChem(void) { return 0; } + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void) { return 0; } }; #endif + +/* finis */ diff --git a/src/build_models/translate_plugin.pl b/src/build_models/translate_plugin.pl --- a/src/build_models/translate_plugin.pl +++ b/src/build_models/translate_plugin.pl @@ -14,65 +14,67 @@ open cfile,"<$cfilename"; open ocfile,">$ocfname"; while () { - - #s/$hfilename/$ohfname/g; + + #s/$hfilename/$ohfname/g; + + # translate function definitions + if (/[a-zA-Z0-9 ]*::OnDivide/) { + s/ParentInfo &parent_info/ParentInfo *parent_info/g; + s/CellBase &daughter1/CellBase *daughter1/g; + s/CellBase &daughter2/CellBase *daughter2/g; + } - # translate function definitions - if (/[a-zA-Z0-9 ]*::OnDivide/) { - s/ParentInfo &parent_info/ParentInfo *parent_info/g; - s/CellBase &daughter1/CellBase *daughter1/g; - s/CellBase &daughter2/CellBase *daughter2/g; - } - - if (/[a-zA-Z0-9 ]*::SetCellColor/) { - s/CellBase &c/CellBase *c/g; - s/QColor &color/QColor *color/g; - } - - if (/[a-zA-Z0-9 ]*::CellHouseKeeping/) { - s/CellBase &c/CellBase *c/g; - } - - # translate member function calls - s/\bparent_info\b\./parent_info->/g; - s/\bdaughter1\b\./daughter1->/g; - s/\bdaughter2\b\./daughter2->/g; - s/\bc\b\./c->/g; - s/\bcolor\b\./color->/g; - print ocfile; - + if (/[a-zA-Z0-9 ]*::SetCellColor/) { + s/CellBase &c/CellBase *c/g; + s/QColor &color/QColor *color/g; + } + + if (/[a-zA-Z0-9 ]*::CellHouseKeeping/) { + s/CellBase &c/CellBase *c/g; + } + + # translate member function calls + s/\bparent_info\b\./parent_info->/g; + s/\bdaughter1\b\./daughter1->/g; + s/\bdaughter2\b\./daughter2->/g; + s/\bc\b\./c->/g; + s/\bcolor\b\./color->/g; + print ocfile; + } open hfile,"<$hfilename"; open ohfile,">$ohfname"; while () { - if (/[ \t]*virtual[ \t]+void[ \t]+CellHouseKeeping/) { - s/CellBase &c/CellBase *c/g; - } - if (/[ \t]*virtual[ \t]+void[ \t]+OnDivide/) { - s/ParentInfo &parent_info/ParentInfo *parent_info/g; - s/CellBase &daughter1/CellBase *daughter1/g; - s/CellBase &daughter2/CellBase *daughter2/g; - } - if (/[ \t]*virtual[ \t]+void[ \t]+SetCellColor/) { - s/CellBase &c/CellBase *c/g; - s/QColor &color/QColor *color/g; - } - - - print ohfile; - + if (/[ \t]*virtual[ \t]+void[ \t]+CellHouseKeeping/) { + s/CellBase &c/CellBase *c/g; + } + if (/[ \t]*virtual[ \t]+void[ \t]+OnDivide/) { + s/ParentInfo &parent_info/ParentInfo *parent_info/g; + s/CellBase &daughter1/CellBase *daughter1/g; + s/CellBase &daughter2/CellBase *daughter2/g; + } + if (/[ \t]*virtual[ \t]+void[ \t]+SetCellColor/) { + s/CellBase &c/CellBase *c/g; + s/QColor &color/QColor *color/g; + } + + + print ohfile; + } open pfile,"<$pfilename"; open opfile,">$opfname"; while () { - - s/\bplugin\b\.h/plugin_tl\.h/g; - s/\bplugin\b\.cpp/plugin_tl\.cpp/g; - - print opfile; - -} \ No newline at end of file + + s/\bplugin\b\.h/plugin_tl\.h/g; + s/\bplugin\b\.cpp/plugin_tl\.cpp/g; + + print opfile; + +} + +#finis diff --git a/src/canvas.cpp b/src/canvas.cpp --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -19,8 +19,6 @@ * */ -#include - #include #include #include @@ -121,10 +119,10 @@ void FigureEditor::clear() } } - void FigureEditor::wheelEvent(QWheelEvent *event) - { - scaleView(pow((double)2, -event->delta() / 240.0)); - } +void FigureEditor::wheelEvent(QWheelEvent *event) +{ + scaleView(pow((double)2, -event->delta() / 240.0)); +} void FigureEditor::scaleView (qreal scaleFactor) @@ -134,20 +132,20 @@ void FigureEditor::scaleView (qreal scal scale (scaleFactor, scaleFactor); } -void FigureEditor::Save(const char *fname, const char *format, int sizex, int sizey) { - - QImage *image = new QImage(sizex, sizey, QImage::Format_RGB32); - image->fill(QColor(Qt::white).rgb()); - QPainter *painter=new QPainter(image); - - render(painter); - - image->save(QString(fname),format); - delete painter; - delete image; +void FigureEditor::Save(const char *fname, const char *format, int sizex, int sizey) +{ + + QImage *image = new QImage(sizex, sizey, QImage::Format_RGB32); + image->fill(QColor(Qt::white).rgb()); + QPainter *painter=new QPainter(image); + + render(painter); + + image->save(QString(fname),format); + delete painter; + delete image; } -//void FigureEditor::contentsMousePressEvent(QMouseEvent* e) void FigureEditor::mousePressEvent(QMouseEvent* e) { static QList selected; @@ -161,7 +159,7 @@ void FigureEditor::mousePressEvent(QMous qDebug() << "Magnification: " << Cell::Magnification() << endl; qDebug() << "Offsets: " << Cell::Offset() << endl; #endif - + QList l=scene()->items(p); @@ -170,47 +168,46 @@ void FigureEditor::mousePressEvent(QMous qDebug() << "Mouse button modifier: " << e->modifiers() << endl; #endif - if (e->button()==Qt::RightButton || l.size()==0) { - - //cerr << "Drawing an intersection line from " << p.x() << ", " << p.y() << endl; - intersection_line = new QGraphicsLineItem( 0, scene() ); - intersection_line->setPen( QPen( QColor("red"), 3, Qt::DashLine ) ); - intersection_line->setLine( QLineF(p,p) ); - intersection_line->setZValue( 100 ); - intersection_line->show(); - } - - for (QList::Iterator it=l.begin(); it!=l.end(); ++it) { - #ifdef QDEBUG - qDebug() << typeid(**it).name() << endl; - #endif + if (e->button()==Qt::RightButton || l.size()==0) { + + //cerr << "Drawing an intersection line from " << p.x() << ", " << p.y() << endl; + intersection_line = new QGraphicsLineItem( 0, scene() ); + intersection_line->setPen( QPen( QColor("red"), 3, Qt::DashLine ) ); + intersection_line->setLine( QLineF(p,p) ); + intersection_line->setZValue( 100 ); + intersection_line->show(); + } + + for (QList::Iterator it=l.begin(); it!=l.end(); ++it) { +#ifdef QDEBUG + qDebug() << typeid(**it).name() << endl; +#endif + + if ( !strcmp(typeid(**it).name(),"8NodeItem")) { - if ( !strcmp(typeid(**it).name(),"8NodeItem")) { - - stringstream data_strstream; - data_strstream << (dynamic_cast(*it))->getNode(); - dynamic_cast
(parent())->UserMessage(QString(data_strstream.str().c_str())); - - (dynamic_cast(*it))->OnClick(e->button()); + stringstream data_strstream; + data_strstream << (dynamic_cast(*it))->getNode(); + dynamic_cast
(parent())->UserMessage(QString(data_strstream.str().c_str())); + + (dynamic_cast(*it))->OnClick(e->button()); + } + else + if ( !strcmp(typeid(**it).name(),"8CellItem") ) { + + Cell &c=((dynamic_cast(*it))->getCell()); + // OnClick to be defined in end-user code + c.OnClick(e); + } else { + if ( !strcmp(typeid(**it).name(),"8WallItem") ) { + (dynamic_cast(*it))->OnClick(e); + } } - else - if ( !strcmp(typeid(**it).name(),"8CellItem") ) { - - Cell &c=((dynamic_cast(*it))->getCell()); - // OnClick to be defined in end-user code - c.OnClick(e); - } else { - if ( !strcmp(typeid(**it).name(),"8WallItem") ) { - (dynamic_cast(*it))->OnClick(e); - } - } - } + } FullRedraw(); moving = 0; } - -//void FigureEditor::contentsMouseMoveEvent(QMouseEvent* e) + void FigureEditor::mouseMoveEvent(QMouseEvent* e) { @@ -224,19 +221,19 @@ void FigureEditor::mouseMoveEvent(QMouse // get object's center of mass QPointF rotation_midpoint = mesh.Centroid()*Cell::Factor() - Cell::Offset(); - - + + // calculate rotation angle double dy = (rotation_midpoint.y() - p.y()); double dx = (rotation_midpoint.x() - p.x()); double new_rot_angle = atan2(dx, dy); double d_alpha = new_rot_angle - rot_angle; rot_angle = new_rot_angle; - + mesh.Rotate(d_alpha, ( Vector(rotation_midpoint) + Cell::Offset() ) / Cell::Factor() ); - + dynamic_cast
(parent())->Plot(0); - FullRedraw(); + FullRedraw(); return; } if ( moving ) { @@ -246,36 +243,36 @@ void FigureEditor::mouseMoveEvent(QMouse p.y() - moving_start.y()); moving_start = p; scene()->update(); - + } - + //cerr << "event"; - + // keep track of intersection line to interactively cut a growing leaf - + if ( intersection_line ) { - + QPointF sp = intersection_line -> line().p1(); // startpoint QPointF ep = mapToScene(e->pos()); // endpoint intersection_line -> setLine( QLineF(sp, ep) ); scene()->update(); // Need this for Mac FullRedraw(); - } + } } //void FigureEditor::contentsMouseReleaseEvent(QMouseEvent* e) void FigureEditor::mouseReleaseEvent(QMouseEvent* e) { - + emit MouseReleased(); // intersection line for leaf was finished now. - + if (e->button()==Qt::LeftButton) { if (intersection_line ) { - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Trying to cut leaf" << endl; - #endif +#endif QPointF sp = intersection_line -> line().p1(); // startpoint QPointF ep = mapToScene(e->pos()); @@ -283,55 +280,55 @@ void FigureEditor::mouseReleaseEvent(QMo intersection_line -> show(); vector intersected_cells = getIntersectedCells(); - + // no cells selected, do nothing if (intersected_cells.size()==0) { - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "No cells detected :-(" << endl; - #endif +#endif return; } - - + + Vector startpoint = Vector(sp.x(), sp.y()) / Cell::Factor() - Cell::Offset(); Vector endpoint = Vector(ep.x(), ep.y()) / Cell::Factor() - Cell::Offset(); - + NodeSet *node_set = new NodeSet; - + for (vector::iterator it = intersected_cells.begin(); it != intersected_cells.end(); it++) { - + (*it)->setBrush(QBrush("purple")); - + Cell &c=(*it)->getCell(); - + // sometimes the cell hasn't properly divided yet before the // next division is called? so check for it? let's find a way // to do this later. Note that this functionality currently // might result in a segmentation fault for users who are // quickly dragging and releasing division lines... scene()->update(); - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << "Dividing Cell " << c.Index() << endl; - #endif +#endif c.DivideOverGivenLine( startpoint, endpoint, true, node_set); } - + node_set->CleanUp(); mesh.AddNodeSet(node_set); - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << "Done DivideOverGivenLine" << endl; - #endif +#endif mesh.TestIllegalWalls(); // Do the actual cutting and removing if (intersected_cells.size()) { mesh.CutAwayBelowLine( startpoint, endpoint ); - + // Correct flags of nodeset for ( NodeSet::iterator i = node_set->begin(); @@ -355,36 +352,36 @@ void FigureEditor::mouseReleaseEvent(QMo - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Done CutAwayBelowLine" << endl; - #endif +#endif mesh.TestIllegalWalls(); mesh.RepairBoundaryPolygon(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Done RepairBoundaryPolygon" << endl; - #endif +#endif mesh.TestIllegalWalls(); mesh.CleanUpWalls(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Done CleanUpWalls" << endl; - #endif +#endif mesh.TestIllegalWalls(); } - + dynamic_cast
(parent())->Plot(); - - #ifdef QDEBUG - qDebug() << "NodeSet of cutting line: " << *node_set << endl; - #endif + +#ifdef QDEBUG + qDebug() << "NodeSet of cutting line: " << *node_set << endl; +#endif } } else if (e->button()==Qt::RightButton) { - + if (intersection_line /* && !angle_line*/) { - + QPointF p = mapToScene(e->pos()); QPointF sp = intersection_line->line().p1(); - + viewport()->setMouseTracking( TRUE ); } } @@ -392,37 +389,37 @@ void FigureEditor::mouseReleaseEvent(QMo // returns a vector of pointer to cells colliding with intersection line -vector FigureEditor::getIntersectedCells(void) { - +vector FigureEditor::getIntersectedCells(void) +{ vector colliding_cells; - + QList l = intersection_line->collidingItems( ); - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << "l.size() = " << l.size() << endl; - #endif +#endif for (QList::Iterator it=l.begin(); it!=l.end(); ++it) { - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << typeid(**it).name() << endl; - #endif - +#endif + if ( !strcmp(typeid(**it).name(),"8CellItem") ) { colliding_cells.push_back(dynamic_cast(*it)); } } - + delete intersection_line; intersection_line = 0; return colliding_cells; - } -void FigureEditor::FullRedraw(void) { - QList rl; - rl << sceneRect(); - updateScene(rl); +void FigureEditor::FullRedraw(void) +{ + QList rl; + rl << sceneRect(); + updateScene(rl); } @@ -465,53 +462,53 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q { editor = new FigureEditor(canvas,mesh, this); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Interactive = " << editor->isEnabled(); - #endif +#endif working_dir = 0; QObject::connect( editor, SIGNAL(MousePressed()), this, SLOT(PauseIfRunning())); QObject::connect( editor, SIGNAL(MouseReleased()), this, SLOT(ContIfRunning())); QMenuBar* menu = menuBar(); - + Q3PopupMenu* file = new Q3PopupMenu( menu ); - file->insertItem("&Read leaf", this, SLOT(readStateXML())); - file->insertItem("&Save leaf", this, SLOT(saveStateXML())); - file->insertItem("Snapshot", this, SLOT(snapshot()), Qt::CTRL+Qt::SHIFT+Qt::Key_S); + file->insertItem("&Read leaf", this, SLOT(readStateXML())); + file->insertItem("&Save leaf", this, SLOT(saveStateXML())); + file->insertItem("Snapshot", this, SLOT(snapshot()), Qt::CTRL+Qt::SHIFT+Qt::Key_S); + + file->insertSeparator(); + file->insertItem("Read next leaf", this, SLOT(readNextStateXML()), Qt::Key_PageDown); + file->insertItem("Read previous leaf", this, SLOT(readPrevStateXML()), Qt::Key_PageUp); + file->insertItem("Read last leaf", this, SLOT(readLastStateXML()), Qt::Key_End); + file->insertItem("Read first leaf", this, SLOT(readFirstStateXML()), Qt::Key_Home); - file->insertSeparator(); - file->insertItem("Read next leaf", this, SLOT(readNextStateXML()), Qt::Key_PageDown); - file->insertItem("Read previous leaf", this, SLOT(readPrevStateXML()), Qt::Key_PageUp); - file->insertItem("Read last leaf", this, SLOT(readLastStateXML()), Qt::Key_End); - file->insertItem("Read first leaf", this, SLOT(readFirstStateXML()), Qt::Key_Home); - - file->insertSeparator(); - file->insertItem("&Print...", this, SLOT(print()), Qt::CTRL+Qt::Key_P); - file->insertSeparator(); - file->insertItem("E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q); - menu->insertItem("&File", file); - - Q3PopupMenu* edit = new Q3PopupMenu( menu ); + file->insertSeparator(); + file->insertItem("&Print...", this, SLOT(print()), Qt::CTRL+Qt::Key_P); + file->insertSeparator(); + file->insertItem("E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q); + menu->insertItem("&File", file); + + Q3PopupMenu* edit = new Q3PopupMenu( menu ); edit->insertItem("Reset Chemicals and Transporters", this, SLOT( CleanMesh()), Qt::CTRL+Qt::Key_R ); - edit->insertItem("Reset Chemicals", this, SLOT( CleanMeshChemicals()) ); - edit->insertItem("Reset Transporters", this, SLOT( CleanMeshTransporters()) ); + edit->insertItem("Reset Chemicals", this, SLOT( CleanMeshChemicals()) ); + edit->insertItem("Reset Transporters", this, SLOT( CleanMeshTransporters()) ); edit->insertItem("Randomize PIN1 Transporters", this, SLOT( RandomizeMesh()) ); edit->insertItem("Cut away SAM", this, SLOT( CutSAM() )); menu->insertItem("&Edit", edit); run = new Q3PopupMenu( menu ); running = false; - paused_id = run->insertItem("&Simulation paused", this, SLOT(togglePaused()), Qt::Key_S); + paused_id = run->insertItem("&Simulation paused", this, SLOT(togglePaused()), Qt::Key_S); run->setItemChecked(paused_id, FALSE); menu->insertItem("&Run", run); - + view = new Q3PopupMenu( menu ); - view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Equal); + view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Equal); view->insertItem("Zoom &out", this, SLOT(zoomOut()), Qt::CTRL+Qt::Key_Minus); - view->insertSeparator(); - com_id = view->insertItem("Show cell ¢ers", this, SLOT(toggleShowCellCenters())); + view->insertSeparator(); + com_id = view->insertItem("Show cell ¢ers", this, SLOT(toggleShowCellCenters())); view->setItemChecked(com_id, FALSE); mesh_id = view->insertItem("Show &nodes", this, SLOT(toggleShowNodes()), Qt::CTRL+Qt::SHIFT+Qt::Key_N); @@ -530,37 +527,37 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q fluxes_id = view->insertItem("Show &fluxes", this, SLOT(toggleShowFluxes())); view->setItemChecked(fluxes_id, FALSE); cell_walls_id = view->insertItem("Show transporters", this, SLOT(toggleShowWalls())); - view->setItemChecked(cell_walls_id, FALSE); - apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts())); + view->setItemChecked(cell_walls_id, FALSE); + apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts())); view->setItemChecked(apoplasts_id, FALSE); - view->insertSeparator(); - only_boundary_id = view->insertItem("Show only leaf &boundary", this, SLOT(toggleLeafBoundary())); - view->insertSeparator(); - movie_frames_id = view->insertItem("Start saving movie &frames", this, SLOT(toggleMovieFrames())); + view->insertSeparator(); + only_boundary_id = view->insertItem("Show only leaf &boundary", this, SLOT(toggleLeafBoundary())); + view->insertSeparator(); + movie_frames_id = view->insertItem("Start saving movie &frames", this, SLOT(toggleMovieFrames())); view->setItemChecked(movie_frames_id, par.movie); - - view->setItemChecked(only_boundary_id, FALSE); + + view->setItemChecked(only_boundary_id, FALSE); menu->insertItem("&View", view); - - + + options = new Q3PopupMenu( menu ); dyn_cells_id = options->insertItem("Cell growth", this, SLOT(toggleDynCells())); options->setItemChecked(dyn_cells_id, true); options->insertItem("Edit ¶meters", this, SLOT(EditParameters()), Qt::CTRL+Qt::Key_E); - + rotation_mode_id = options->insertItem("Rotate leaf", this, SLOT(EnterRotationMode()), Qt::CTRL + Qt::SHIFT + Qt::Key_R); options->setItemChecked(rotation_mode_id, false); menu->insertItem("&Options",options); - - // Menu of models - modelmenu = new QMenu( menu ); - menu->insertItem("&Models", modelmenu); - - + + // Menu of models + modelmenu = new QMenu( menu ); + menu->insertItem("&Models", modelmenu); + + menu->insertSeparator(); - + helpmenu = new Q3PopupMenu( menu ); tooltips_id = helpmenu->insertItem("Show Cell&Info", this, SLOT(Refresh())); helpmenu->setItemChecked(tooltips_id, true); @@ -572,44 +569,41 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q setCentralWidget(editor); printer = 0; init(); - + // Start timer which repetitively invokes // a simulation time step timer = new QTimer( this ); connect( timer, SIGNAL(timeout()), SLOT(TimeStepWrap()) ); - + stopSimulation(); statusBar()->addWidget(new QLabel("Ready.")); setCaption(caption); gifanim = 0; - - infobar = new InfoBar(); - addDockWindow(infobar); + infobar = new InfoBar(); + addDockWindow(infobar); } -void Main::RefreshInfoBar(void) { - infobar->SetText(mesh.ModelID()); +void Main::RefreshInfoBar(void) +{ + infobar->SetText(mesh.ModelID()); } -void Main::UserMessage(QString message, int timeout) { - +void Main::UserMessage(QString message, int timeout) +{ statusBar()->showMessage(message, timeout); - } void Main::init() { clear(); - + static int r=24; srand(++r); - + mainCount++; - - } Main::~Main() @@ -630,21 +624,22 @@ void Main::newView() } -void Main::EditParameters() { - +void Main::EditParameters() +{ + ParameterDialog *pardial = new ParameterDialog(this, "stridediag"); // Make sure the values in the parameter dialog are updated after a file is read // each method changing the parameters (reading XML or PAR files) should // emit this signal QObject::connect( this, SIGNAL( ParsChanged() ), pardial, SLOT( Reset() ) ); - } -void Main::savePars() { - +void Main::savePars() +{ + stopSimulation(); - + Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE ); fd->setMode( Q3FileDialog::AnyFile ); fd->setFilter( "Parameter files (*.par)"); @@ -657,13 +652,13 @@ void Main::savePars() { } startSimulation(); - } -void Main::readPars() { - +void Main::readPars() +{ + stopSimulation(); - + Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE ); fd->setMode( Q3FileDialog::ExistingFile ); fd->setFilter( "Parameter files (*.par)"); @@ -673,22 +668,22 @@ void Main::readPars() { fileName = fd->selectedFile(); par.Read((const char *)fileName); } - + emit ParsChanged(); /* if (timer_active) timer->start( 0 );*/ - } -void Main::saveStateXML() { - +void Main::saveStateXML() +{ + stopSimulation(); Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE ); fd->setMode( Q3FileDialog::AnyFile ); fd->setFilter( "XML (*.xml)"); QString fileName; - + if ( fd->exec() == QDialog::Accepted ) { fileName = fd->selectedFile(); if ( QFile::exists( fileName ) && @@ -701,27 +696,27 @@ void Main::saveStateXML() { tr("&Yes"), tr("&No"), QString::null, 1, 1 ) ) { return saveStateXML(); - + } else { - + mesh.XMLSave((const char *)fileName, XMLSettingsTree()); - + } } - } -void Main::snapshot() { - - +void Main::snapshot() +{ + + stopSimulation(); Q3FileDialog *fd = new Q3FileDialog( this, "Save snapshot", TRUE ); fd->setMode( Q3FileDialog::AnyFile ); - + QString fileName; - + if ( fd->exec() == QDialog::Accepted ) { fileName = fd->selectedFile(); if ( QFile::exists( fileName ) && @@ -734,37 +729,37 @@ void Main::snapshot() { tr("&Yes"), tr("&No"), QString::null, 1, 1 ) ) { return snapshot(); - + } else { - + // extract extension from filename - QString extension = getExtension(fileName); - - // Save bitmaps at 1024x768 - Save((const char *)fileName, extension, 1024, 768); + QString extension = getExtension(fileName); + + // Save bitmaps at 1024x768 + Save((const char *)fileName, extension, 1024, 768); } } - } - + -void Main::readPrevStateXML() { - +void Main::readPrevStateXML() +{ + // if we have already read a file, read the next file if (!currentFile.isEmpty() && working_dir) { QString next_file; - + QStringList xml_files = working_dir->entryList("*.xml"); QString currentFile_nopath = currentFile.section( '/', -1 ); QString currentFile_path = currentFile.section( '/', 0, -2 ); - + QList::iterator f = xml_files.find( currentFile_nopath ); - + if (f == xml_files.end()) { return; } - + if (f==xml_files.begin()) { QMessageBox mb( "Read previous leaf", "No more files", @@ -777,38 +772,39 @@ void Main::readPrevStateXML() { } next_file = *(--f); next_file = currentFile_path+"/"+next_file; - + readStateXML((const char *)next_file); - + } } -int Main::readStateXML(const char *filename, bool geometry, bool pars, bool simtime) { - +int Main::readStateXML(const char *filename, bool geometry, bool pars, bool simtime) +{ + try { xmlNode *settings; mesh.XMLRead((const char *)filename, &settings, geometry, pars, simtime); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Reading done."<< endl; - #endif +#endif XMLReadSettings(settings); xmlFree(settings); Cell::SetMagnification(1); Cell::setOffset(0,0); - + FitLeafToCanvas(); - + currentFile = QString(filename); - + Plot(); QString status_message = QString("Successfully read leaf from file %1. Time is %2 h.").arg(currentFile).arg(mesh.getTimeHours().c_str()); cerr << status_message.toStdString() << endl; - setCaption(caption_with_file.arg(filename)); + setCaption(caption_with_file.arg(filename)); statusBar()->message(status_message); emit ParsChanged(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Done. Returning 0." << endl; - #endif +#endif return 0; } catch (const char *error_message) { QMessageBox mb( "Read leaf from XML file", @@ -820,27 +816,27 @@ int Main::readStateXML(const char *filen mb.exec(); return 1; } - } -void Main::readNextStateXML() { - +void Main::readNextStateXML() +{ + // if we have already read a file, read the next file if (!currentFile.isEmpty() && working_dir) { QString next_file; - + QStringList xml_files = working_dir->entryList("*.xml"); QString currentFile_nopath = currentFile.section( '/', -1 ); QString currentFile_path = currentFile.section( '/', 0, -2 ); - - + + QList::iterator f = xml_files.find( currentFile_nopath ); - + if (f == xml_files.end()) { return; } - + ++f; if (f==xml_files.end()) { QMessageBox mb( "Read next leaf", @@ -857,61 +853,58 @@ void Main::readNextStateXML() { readStateXML((const char*)next_file); } - - } -void Main::readLastStateXML() { - +void Main::readLastStateXML() +{ + // if we have already read a file, read the next file if (!currentFile.isEmpty() && working_dir) { QString next_file; - + QStringList xml_files = working_dir->entryList("*.xml"); QString currentFile_nopath = currentFile.section( '/', -1 ); QString currentFile_path = currentFile.section( '/', 0, -2 ); - - + + next_file = xml_files.back(); - + next_file = currentFile_path+"/"+next_file; readStateXML((const char*)next_file); } - - } -void Main::readFirstStateXML() { - +void Main::readFirstStateXML() +{ + // if we have already read a file, read the next file if (!currentFile.isEmpty() && working_dir) { QString next_file; - + QStringList xml_files = working_dir->entryList("*.xml"); QString currentFile_nopath = currentFile.section( '/', -1 ); QString currentFile_path = currentFile.section( '/', 0, -2 ); - - + + next_file = xml_files.front(); - + next_file = currentFile_path+"/"+next_file; readStateXML((const char*)next_file); } - - } -void Main::readStateXML() { +void Main::readStateXML() +{ // extern Mesh mesh; stopSimulation(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Trying to open an OptionFileDialog" << endl; - #endif +#endif OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE ); fd->setMode( OptionFileDialog::ExistingFile ); fd->setFilter( "XML files (*.xml)"); @@ -920,13 +913,13 @@ void Main::readStateXML() { } QString fileName; if ( fd->exec() == QDialog::Accepted ) { - + fileName = fd->selectedFile(); if (working_dir) { delete working_dir; } working_dir = fd->dir(); - + if (readStateXML((const char *)fileName,fd->readGeometryP(), fd->readParametersP()) ) return readStateXML(); // user can try again } @@ -947,7 +940,7 @@ void Main::help() "Leaf growth computer model
" "(c) 2005-2007, Roeland Merks
" "VIB Department Plant Systems Biology
" - "Ghent, Belgium
" + "Ghent, Belgium
" "(c) 2008-2009, Roeland Merks
" "CWI/NCSB, Amsterdam, Netherlands
" "Pilot release for WUR/Biometris, 21-10-2009
", @@ -956,294 +949,315 @@ void Main::help() about->show(); } - void Main::aboutQt() - { - QMessageBox::aboutQt( this, "Virtual Leaf" ); - } +void Main::aboutQt(){ + QMessageBox::aboutQt( this, "Virtual Leaf" ); +} - void Main::toggleShowCellCenters() - { - Plot(); - } +void Main::toggleShowCellCenters() +{ + Plot(); +} - void Main::toggleShowWalls() - { - Plot(); - } +void Main::toggleShowWalls() +{ + Plot(); +} + void Main::toggleShowApoplasts() { - Plot(); + Plot(); } - void Main::toggleShowNodes() - { - Plot(); - } + +void Main::toggleShowNodes() +{ + Plot(); +} - void Main::toggleNodeNumbers(void) { - Plot(); - } +void Main::toggleNodeNumbers(void) +{ + Plot(); +} - void Main::toggleCellNumbers(void) { - Plot(); - } +void Main::toggleCellNumbers(void) +{ + Plot(); +} - void Main::toggleCellAxes(void) { - Plot(); - } - - void Main::toggleCellStrain(void) { - Plot(); - } +void Main::toggleCellAxes(void) +{ + Plot(); +} - void Main::toggleShowFluxes(void) { - Plot(); - } +void Main::toggleCellStrain(void) +{ + Plot(); +} - void Main::toggleShowBorderCells(){ - Plot(); - } +void Main::toggleShowFluxes(void) +{ + Plot(); +} -void Main::toggleHideCells(void) { - Plot(); - editor->FullRedraw(); +void Main::toggleShowBorderCells() +{ + Plot(); } - void Main::toggleMovieFrames(){} - void Main::toggleLeafBoundary(){} +void Main::toggleHideCells(void) +{ + Plot(); + editor->FullRedraw(); +} + +void Main::toggleMovieFrames(){} + +void Main::toggleLeafBoundary(){} + +void Main::toggleDynCells() {} - void Main::toggleDynCells() {} - - void Main::startSimulation(void) { - timer->start( 0 ); - statusBar()->message("Simulation started"); - running = true; - } +void Main::startSimulation(void) +{ + timer->start( 0 ); + statusBar()->message("Simulation started"); + running = true; +} - void Main::stopSimulation(void) { - timer->stop(); - cerr << "Stopping simulation" << endl; - statusBar()->message("Simulation paused"); - running = false; +void Main::stopSimulation(void) +{ + timer->stop(); + cerr << "Stopping simulation" << endl; + statusBar()->message("Simulation paused"); + running = false; +} + +void Main::togglePaused() +{ + bool s = run->isItemChecked(paused_id); + if (s) { + cerr << "Calling start simulation" << endl; + startSimulation(); + } else { + cerr << "Calling stop simulation" << endl; + stopSimulation(); } +} - void Main::togglePaused() - { - bool s = run->isItemChecked(paused_id); - if (s) { - cerr << "Calling start simulation" << endl; - startSimulation(); - } else { - cerr << "Calling stop simulation" << endl; - stopSimulation(); - } - } - - void Main::setFluxArrowSize(int size) { - - flux_arrow_size = size/100.; - } +void Main::setFluxArrowSize(int size) +{ + flux_arrow_size = size/100.; +} - void Main::enlarge() - { - canvas.setSceneRect( QRectF( 0,0, canvas.width()*4./3., canvas.height()*4./3.) ); - } +void Main::enlarge() +{ + canvas.setSceneRect( QRectF( 0,0, canvas.width()*4./3., canvas.height()*4./3.) ); +} - void Main::shrink() - { - canvas.setSceneRect( QRectF( 0,0, canvas.width()*3/4, canvas.height()*3/4) ); - } +void Main::shrink() +{ + canvas.setSceneRect( QRectF( 0,0, canvas.width()*3/4, canvas.height()*3/4) ); +} - void Main::scale(double factor) { - QMatrix m = editor->matrix(); - m.scale(factor, factor); - editor->setMatrix( m ); - } +void Main::scale(double factor) +{ + QMatrix m = editor->matrix(); + m.scale(factor, factor); + editor->setMatrix( m ); +} - void Main::zoomIn() - { - QMatrix m = editor->matrix(); - m.scale( 1.1, 1.1 ); - editor->setMatrix( m ); - } +void Main::zoomIn() +{ + QMatrix m = editor->matrix(); + m.scale( 1.1, 1.1 ); + editor->setMatrix( m ); +} - void Main::zoomOut() - { - QMatrix m = editor->matrix(); - m.scale( 0.9, 0.9 ); - editor->setMatrix( m ); - } +void Main::zoomOut() +{ + QMatrix m = editor->matrix(); + m.scale( 0.9, 0.9 ); + editor->setMatrix( m ); +} - void Main::print() - { - if ( !printer ) printer = new QPrinter; - - if ( printer->setup(this) ) { - - // extern Mesh mesh; - Vector bbll,bbur; - mesh.BoundingBox(bbll,bbur); +void Main::print() +{ + if ( !printer ) printer = new QPrinter; + + if ( printer->setup(this) ) { + + // extern Mesh mesh; + Vector bbll,bbur; + mesh.BoundingBox(bbll,bbur); - #ifdef QDEBUG - qDebug() << "bbll = " << bbll << endl; - qDebug() << "bbur = " << bbur << endl; - #endif - double cw = (bbur.x - bbll.x); - double ch = (bbur.y - bbll.y); - QPainter pp(printer); - QRect vp=pp.viewport(); - #ifdef QDEBUG - qDebug() << "Paper width = " << vp.width() << " x " << vp.height() << endl; - #endif +#ifdef QDEBUG + qDebug() << "bbll = " << bbll << endl; + qDebug() << "bbur = " << bbur << endl; +#endif + double cw = (bbur.x - bbll.x); + double ch = (bbur.y - bbll.y); + QPainter pp(printer); + QRect vp=pp.viewport(); +#ifdef QDEBUG + qDebug() << "Paper width = " << vp.width() << " x " << vp.height() << endl; +#endif - // Note that Cell is also translated... - pp.translate(-bbur.x,-bbur.y); - if (cw>ch) { - pp.scale(vp.width()/(2*cw*Cell::Magnification()), vp.width()/(2*cw*Cell::Magnification())); - } else { - pp.scale(vp.height()/(2*ch*Cell::Magnification()), vp.height()/(2*ch*Cell::Magnification())); - } - canvas.render(&pp, QRectF(), QRectF(0.,0.,canvas.width(),canvas.height())); + // Note that Cell is also translated... + pp.translate(-bbur.x,-bbur.y); + if (cw>ch) { + pp.scale(vp.width()/(2*cw*Cell::Magnification()), vp.width()/(2*cw*Cell::Magnification())); + } else { + pp.scale(vp.height()/(2*ch*Cell::Magnification()), vp.height()/(2*ch*Cell::Magnification())); } + canvas.render(&pp, QRectF(), QRectF(0.,0.,canvas.width(),canvas.height())); } +} - void Main::TimeStepWrap(void) { - - static int t=0; - TimeStep(); - t++; - // check number of timesteps - if (t==par.nit) { - emit SimulationDone(); - } +void Main::TimeStepWrap(void) +{ + static int t=0; + TimeStep(); + t++; + // check number of timesteps + if (t==par.nit) { + emit SimulationDone(); } +} - void Main::RestartSim(void) { - - stopSimulation(); - if ( QMessageBox::question( - this, - tr("Restart simulation?"), - tr("Restart simulation.\n" - "Are you sure?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::Yes ) { +void Main::RestartSim(void) +{ - cerr << "Restarting simulation" << endl; - // extern Mesh mesh; - mesh.Clear(); - Init(); - Plot(); - editor->FullRedraw(); - } - //startSimulation(); - } + stopSimulation(); + if ( QMessageBox::question( + this, + tr("Restart simulation?"), + tr("Restart simulation.\n" + "Are you sure?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::Yes ) { + + cerr << "Restarting simulation" << endl; + // extern Mesh mesh; + mesh.Clear(); + Init(); + Plot(); + editor->FullRedraw(); + } + //startSimulation(); +} -void Main::FitCanvasToWindow(void) { - +void Main::FitCanvasToWindow(void) +{ + double scale_factor_x = (double)editor->width()/(double)canvas.width(); double scale_factor_y = (double)editor->height()/(double)canvas.height(); double scale_factor = scale_factor_x > scale_factor_y ? scale_factor_x : scale_factor_y; QMatrix m = editor->matrix(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "editor->width() = " << editor->width() << endl; qDebug() << "editor->height() = " << editor->height() << endl; - + qDebug() << "scale_factor = " << scale_factor << endl; qDebug() << "scale_factor_x = " << scale_factor_x << endl; qDebug() << "scale_factor_y = " << scale_factor_y << endl; - #endif +#endif m.scale( scale_factor, scale_factor ); editor->setMatrix( m ); editor->show(); } - void Main::PauseIfRunning(void) { - if (running) { - timer->stop(); - } +void Main::PauseIfRunning(void) +{ + if (running) { + timer->stop(); } +} - void Main::ContIfRunning(void) { - if (running) { - timer->start( 0 ); - } +void Main::ContIfRunning(void) +{ + if (running) { + timer->start( 0 ); } +} -void Main::FitLeafToCanvas(void) { +void Main::FitLeafToCanvas(void) +{ Vector ll,ur; mesh.BoundingBox(ll, ur); - + ll*=Cell::Magnification(); ur*=Cell::Magnification(); - + // give the leaf some space Vector border = ((ur-ll)/5.); - + QRectF bb( ll.x - border.x, ll.y - border.y, ur.x-ll.x + 2*border.x, ur.y-ll.y + 2*border.y ); - - + + // cerr << ur << ", " << ll << endl; editor->fitInView(bb, Qt::KeepAspectRatio); } -void Main::CleanMesh(void) { - vector clean_chem(Cell::NChem()); - vector clean_transporters(Cell::NChem()); +void Main::CleanMesh(void) +{ + vector clean_chem(Cell::NChem()); + vector clean_transporters(Cell::NChem()); - for (int i=0;iFullRedraw(); + for (int i=0;iFullRedraw(); } -void Main::CleanMeshChemicals(void) { - - vector clean_chem(Cell::NChem()); +void Main::CleanMeshChemicals(void) +{ + + vector clean_chem(Cell::NChem()); - for (int i=0;iFullRedraw(); + for (int i=0;iFullRedraw(); } -void Main::CleanMeshTransporters(void) { - vector clean_transporters(Cell::NChem()); - for (int i=0;iFullRedraw(); +void Main::CleanMeshTransporters(void) +{ + vector clean_transporters(Cell::NChem()); + for (int i=0;iFullRedraw(); } -void Main::RandomizeMesh(void) { - +void Main::RandomizeMesh(void) +{ + vector max_chem(Cell::NChem()); vector max_transporters(Cell::NChem()); - + for (int i=0;isetItemChecked(com_id, showcentersp); @@ -1274,10 +1289,11 @@ void Main::XMLReadSettings(xmlNode *sett view->setItemChecked(hide_cells_id, hidecellsp); options->setItemChecked(dyn_cells_id, dynamicscellsp); view->setItemChecked( cell_walls_id, showwallsp); - view->setItemChecked( apoplasts_id, showapoplastsp); + view->setItemChecked( apoplasts_id, showapoplastsp); } -xmlNode *Main::XMLSettingsTree(void) { +xmlNode *Main::XMLSettingsTree(void) +{ showcentersp = view->isItemChecked(com_id); showmeshp = view->isItemChecked(mesh_id); @@ -1291,11 +1307,10 @@ xmlNode *Main::XMLSettingsTree(void) { showfluxesp = view->isItemChecked(fluxes_id); dynamicscellsp = options->isItemChecked(dyn_cells_id); showwallsp = view->isItemChecked( cell_walls_id); - showapoplastsp = view->isItemChecked( apoplasts_id); + showapoplastsp = view->isItemChecked( apoplasts_id); hidecellsp = view->isItemChecked( hide_cells_id); return MainBase::XMLSettingsTree(); } /* finis */ - diff --git a/src/canvas.h b/src/canvas.h --- a/src/canvas.h +++ b/src/canvas.h @@ -53,9 +53,9 @@ #include #if defined(Q_OS_MAC) - #define PREFIX "cmd" +#define PREFIX "cmd" #else - #define PREFIX "crtl" +#define PREFIX "crtl" #endif @@ -68,13 +68,13 @@ class FigureEditor : public QGraphicsVie Q_OBJECT friend class Main; - public: + public: FigureEditor(QGraphicsScene&, Mesh&, QWidget* parent=0, const char* name=0, Qt::WFlags f=0); void clear(); void Save(const char *fname, const char *format, int sizex=640, int sizey=480); void FullRedraw(void); -protected: + protected: void mousePressEvent(QMouseEvent*); void mouseMoveEvent(QMouseEvent*); void mouseReleaseEvent(QMouseEvent*); @@ -96,7 +96,7 @@ protected: //NodeItem* moving; SimItemBase *moving; QPointF moving_start; - + QGraphicsLineItem *intersection_line; bool rotation_mode; bool insert_mode; @@ -105,8 +105,8 @@ protected: class Main : public Q3MainWindow, public MainBase { Q_OBJECT - friend class ModelCatalogue; // needs to populate menu item models - public: + friend class ModelCatalogue; // needs to populate menu item models + public: Main(QGraphicsScene&, Mesh&, QWidget* parent=0, const char* name=0, Qt::WFlags f=0); ~Main(); virtual bool ShowCentersP(void) {return view->isItemChecked(com_id);} @@ -120,7 +120,7 @@ class Main : public Q3MainWindow, public virtual bool MovieFramesP(void) {return view->isItemChecked(movie_frames_id);} virtual bool ShowBoundaryOnlyP(void) {return view->isItemChecked(only_boundary_id);} virtual bool ShowWallsP(void) {return view->isItemChecked(cell_walls_id);} - virtual bool ShowApoplastsP(void) { return view->isItemChecked(apoplasts_id);} + virtual bool ShowApoplastsP(void) { return view->isItemChecked(apoplasts_id);} virtual bool ShowFluxesP(void) { return view->isItemChecked(fluxes_id); } virtual bool DynamicCellsP(void) { return options->isItemChecked(dyn_cells_id); } virtual bool RotationModeP(void) { return options->isItemChecked(rotation_mode_id); } @@ -128,10 +128,11 @@ class Main : public Q3MainWindow, public virtual bool ShowToolTipsP(void) { return helpmenu->isItemChecked(tooltips_id); } virtual bool HideCellsP(void) { return view->isItemChecked(hide_cells_id); } void scale(double factor); - virtual double getFluxArrowsize(void) { + virtual double getFluxArrowsize(void) + { return flux_arrow_size; } - + void FitCanvasToWindow(); void FitLeafToCanvas(void); @@ -162,7 +163,8 @@ class Main : public Q3MainWindow, public void stopSimulation(void); void RefreshInfoBar(void); - void EnterRotationMode(void) { + void EnterRotationMode(void) + { UserMessage("Rotation mode. Click mouse to exit."); if (editor) { @@ -171,9 +173,10 @@ class Main : public Q3MainWindow, public // Exit rotation mode if mouse is clicked connect(editor, SIGNAL(MousePressed()), this, SLOT(ExitRotationMode())); } - + } - void ExitRotationMode(void) { + void ExitRotationMode(void) + { UserMessage("Exited rotation mode.",2000); options->setItemChecked(rotation_mode_id, false); @@ -186,7 +189,7 @@ class Main : public Q3MainWindow, public void PauseIfRunning(void); void ContIfRunning(void); virtual void XMLReadSettings(xmlNode *settings); - + private slots: void aboutQt(); void newView(); @@ -209,27 +212,27 @@ class Main : public Q3MainWindow, public void shrink(); void zoomIn(); void zoomOut(); - + void CleanMesh(); - void CleanMeshChemicals(void); - void CleanMeshTransporters(void); - + void CleanMeshChemicals(void); + void CleanMeshTransporters(void); + void RandomizeMesh(); signals: void SimulationDone(void); void ParsChanged(void); - + protected: Mesh &mesh; - + private: NodeSet *node_set; FigureEditor *editor; Q3PopupMenu* options; Q3PopupMenu *view; Q3PopupMenu *run; - QMenu *modelmenu; + QMenu *modelmenu; Q3PopupMenu *helpmenu; QPrinter* printer; @@ -247,7 +250,7 @@ class Main : public Q3MainWindow, public int cell_strain_id; // view->Show cell strain int only_boundary_id; // view ->Show only leaf boundary int cell_walls_id; // view -> Show transporters - int apoplasts_id; // view -> Show apoplasts + int apoplasts_id; // view -> Show apoplasts int tooltips_id; // help -> Show Cell Info int hide_cells_id; // view->Hide Cells double flux_arrow_size; @@ -262,10 +265,9 @@ class Main : public Q3MainWindow, public virtual xmlNode *XMLSettingsTree(void); static const QString caption; static const QString caption_with_file; - InfoBar *infobar; - + InfoBar *infobar; }; - +#endif -#endif +/* finis*/ diff --git a/src/cell.cpp b/src/cell.cpp --- a/src/cell.cpp +++ b/src/cell.cpp @@ -40,1510 +40,1461 @@ extern Parameter par; double Cell::factor=1.; double Cell::offset[3]={0,0,0}; -Cell::Cell(void) : CellBase() { - - m=0; - +Cell::Cell(void) : CellBase() +{ + m=0; } -Cell::Cell(double x, double y, double z) : CellBase(x,y,z) { - - m=0; - +Cell::Cell(double x, double y, double z) : CellBase(x,y,z) +{ + m=0; } -Cell::Cell(const Cell &src) : CellBase(src) { - - m=src.m; +Cell::Cell(const Cell &src) : CellBase(src) +{ + m=src.m; } bool Cell::Cmp(Cell *c) const { return this->Index() < c->Index(); } bool Cell::Eq(Cell *c) const { return this->Index() == c->Index(); } -Cell Cell::operator=(const Cell &src) { - CellBase::operator=(src); - m=src.m; - return *this; +Cell Cell::operator=(const Cell &src) +{ + CellBase::operator=(src); + m=src.m; + return *this; } //Cell(void) : CellBase() {} -void Cell::DivideOverAxis(Vector axis) { - - // Build a wall - // -> find the position of the wall - - // better look for intersection with a simple line intersection algorithm as below? - // this leads to some exceptions: e.g. dividing a horizontal rectangle. - // leaving it like this for the time being - - if (dead) return; - - Vector centroid=Centroid(); - double prev_cross_z=(axis * (centroid - *(nodes.back()) ) ).z ; - - ItList new_node_locations; - - for (list::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - // cross product to detect position of division - Vector cross = axis * (centroid - *(*i)); - - if (cross.z * prev_cross_z < 0 ) { - - new_node_locations.push_back(i); - - } - prev_cross_z=cross.z; - } - - DivideWalls(new_node_locations, centroid, centroid+axis); - +void Cell::DivideOverAxis(Vector axis) +{ + // Build a wall + // -> find the position of the wall + + // better look for intersection with a simple line intersection algorithm as below? + // this leads to some exceptions: e.g. dividing a horizontal rectangle. + // leaving it like this for the time being + + if (dead) return; + + Vector centroid=Centroid(); + double prev_cross_z=(axis * (centroid - *(nodes.back()) ) ).z ; + + ItList new_node_locations; + + for (list::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + // cross product to detect position of division + Vector cross = axis * (centroid - *(*i)); + + if (cross.z * prev_cross_z < 0 ) { + + new_node_locations.push_back(i); + + } + prev_cross_z=cross.z; + } + + DivideWalls(new_node_locations, centroid, centroid+axis); } -double Cell::MeanArea(void) { - return m->MeanArea(); + +double Cell::MeanArea(void) +{ + return m->MeanArea(); } -void Cell::Apoptose(void) { - - // First kill walls - #ifdef QDEBUG - qDebug() << "This is cell " << Index() << endl; - qDebug() << "Number of walls: " << walls.size() << endl; - #endif - for (list::iterator w=walls.begin(); w!=walls.end(); w++) { - #ifdef QDEBUG - qDebug() << "Before apoptosis, wall " << (*w)->Index() << " says: c1 = " - << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; - #endif - } - for (list::iterator w=walls.begin(); - w!=walls.end(); - w++) { - - bool illegal_flag = false; - if ((*w)->c1 == (*w)->c2 ) - illegal_flag=true; - if ((*w)->c1 == this) { - - // invert wall? - (*w)->c1 = (*w)->c2; - (*w)->c2 = m->boundary_polygon; - - Node *n1 = (*w)->n1; - (*w)->n1 = (*w)->n2; - (*w)->n2 = n1; - - } else { - (*w)->c2 = m->boundary_polygon; - } - - #ifdef QDEBUG - if (illegal_flag && (*w)->c1==(*w)->c2) { - qDebug() << "I created an illegal wall." << endl; - } - #endif +void Cell::Apoptose(void) +{ + // First kill walls +#ifdef QDEBUG + qDebug() << "This is cell " << Index() << endl; + qDebug() << "Number of walls: " << walls.size() << endl; +#endif + for (list::iterator w=walls.begin(); w!=walls.end(); w++) { +#ifdef QDEBUG + qDebug() << "Before apoptosis, wall " << (*w)->Index() << " says: c1 = " + << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; +#endif + } + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + + bool illegal_flag = false; + if ((*w)->c1 == (*w)->c2 ) + illegal_flag=true; + if ((*w)->c1 == this) { - if ( ((*w)->N1()->DeadP() || (*w)->N2()->DeadP()) || - ((*w)->C1() == (*w)->C2() ) ){ - // kill wall - #ifdef QDEBUG - qDebug() << "Killing wall." << endl; - #endif - (*w)->Kill(); + // invert wall? + (*w)->c1 = (*w)->c2; + (*w)->c2 = m->boundary_polygon; + + Node *n1 = (*w)->n1; + (*w)->n1 = (*w)->n2; + (*w)->n2 = n1; + + } else { + (*w)->c2 = m->boundary_polygon; + } + +#ifdef QDEBUG + if (illegal_flag && (*w)->c1==(*w)->c2) { + qDebug() << "I created an illegal wall." << endl; + } +#endif + + if ( ((*w)->N1()->DeadP() || (*w)->N2()->DeadP()) || + ((*w)->C1() == (*w)->C2() ) ){ + // kill wall +#ifdef QDEBUG + qDebug() << "Killing wall." << endl; +#endif + (*w)->Kill(); - #ifdef QDEBUG - if ((*w)) { - qDebug() << "Wall " << (*w)->Index() << " says: c1 = " - << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; - } - #endif - (*w)=0; - } else { - #ifdef QDEBUG - qDebug() << "Not killing wall." << endl; - qDebug() << "Wall " << (*w)->Index() << " says: c1 = " - << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; - #endif - } - - } - walls.remove(0); - - // Unregister me from my nodes, and delete the node if it no longer belongs to any cells - list superfluous_nodes; - for (list::iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - - Node &no(*(*n)); - // locate myself in the node's owner list - list::iterator cellpos; - bool cell_found=false; - for (list::iterator nb=no.owners.begin(); - nb!=no.owners.end(); - nb++) { - if (nb->cell == this) { - cellpos = nb; - cell_found = true; - break; - } - } - - if (!cell_found) { - // I think this cannot happen; but if I am wrong, unpredictable things would happen. So throw an exception. - throw ("Cell not found in CellBase::Apoptose()\n\rPlease correct the code to handle this situation."); - } - - Neighbor tmp = *cellpos; - no.owners.erase(cellpos); - - // if node has no owners left, or only has a connection to special cell -1 (outside world), mark it as dead. - - if (no.owners.size()==0 || (no.owners.size()==1 && no.owners.front().cell->BoundaryPolP()) ) { - no.MarkDead(); - } else { - // register node with outside world - if (find_if( no.owners.begin(), no.owners.end(), - bind2nd ( mem_fun_ref(&Neighbor::CellEquals), m->boundary_polygon->Index() ) ) == no.owners.end() ) { - - tmp.cell = m->boundary_polygon; - no.owners.push_back(tmp); - } - } - } - - - - // mark cell as dead - MarkDead(); +#ifdef QDEBUG + if ((*w)) { + qDebug() << "Wall " << (*w)->Index() << " says: c1 = " + << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; + } +#endif + (*w)=0; + } else { +#ifdef QDEBUG + qDebug() << "Not killing wall." << endl; + qDebug() << "Wall " << (*w)->Index() << " says: c1 = " + << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; +#endif + } + } + walls.remove(0); + + // Unregister me from my nodes, and delete the node if it no longer belongs to any cells + list superfluous_nodes; + for (list::iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + + Node &no(*(*n)); + // locate myself in the node's owner list + list::iterator cellpos; + bool cell_found=false; + for (list::iterator nb=no.owners.begin(); + nb!=no.owners.end(); + nb++) { + if (nb->cell == this) { + cellpos = nb; + cell_found = true; + break; + } + } + + if (!cell_found) { + // I think this cannot happen; but if I am wrong, unpredictable things would happen. So throw an exception. + throw ("Cell not found in CellBase::Apoptose()\n\rPlease correct the code to handle this situation."); + } + + Neighbor tmp = *cellpos; + no.owners.erase(cellpos); + + // if node has no owners left, or only has a connection to special cell -1 (outside world), mark it as dead. + + if (no.owners.size()==0 || (no.owners.size()==1 && no.owners.front().cell->BoundaryPolP()) ) { + no.MarkDead(); + } else { + // register node with outside world + if (find_if( no.owners.begin(), no.owners.end(), + bind2nd ( mem_fun_ref(&Neighbor::CellEquals), m->boundary_polygon->Index() ) ) == no.owners.end() ) { + + tmp.cell = m->boundary_polygon; + no.owners.push_back(tmp); + } + } + } + + // mark cell as dead + MarkDead(); } -void Cell::ConstructConnections(void) { - - // Tie up the nodes of this cell, assuming they are correctly ordered - - //cerr << "Constructing connections of cell " << index << endl; - - for (list::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - //cerr << "Connecting node " << *i << endl; - //cerr << "Node " << *i << endl << " = " << *(*i) << endl; - // 1. Tidy up existing connections (which are part of this cell) - if ((*i)->owners.size()>0) { - list::iterator neighb_with_this_cell= - // remove myself from the neighbor list of the node - find_if((*i)->owners.begin(), - (*i)->owners.end(), - bind2nd(mem_fun_ref( &Neighbor::CellEquals ),this->Index() ) ); - if (neighb_with_this_cell!=(*i)->owners.end()) - (*i)->owners.erase(neighb_with_this_cell); - } - - Node *previous; - if (i!=nodes.begin()) { - list::iterator previous_iterator=i; - previous_iterator--; - previous=*previous_iterator; - } else { - previous=nodes.back(); - } - - Node *next; - list::iterator next_iterator=i; - next_iterator++; - if (next_iterator==nodes.end()) { - next=nodes.front(); - } else { - next=*next_iterator; - } - - //cerr << "[" << *i << "]"; - //if (*i==10 || *i==11) { - //cerr << "previous = " << previous << ", next = " << next << endl; - //} - //if (*i!=10 && *i!=11) - //cerr << "Node " << *i << endl << " = " << *(*i) << endl; - (*i)->owners.push_back( Neighbor( this, previous, next ) ); - // if (*i==50 || *i==51) { - //cerr << "Node " << *i << ".size() = " << (*i)->owners.size() << endl; - // } +void Cell::ConstructConnections(void) +{ + // Tie up the nodes of this cell, assuming they are correctly ordered + + //cerr << "Constructing connections of cell " << index << endl; + + for (list::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + //cerr << "Connecting node " << *i << endl; + //cerr << "Node " << *i << endl << " = " << *(*i) << endl; + // 1. Tidy up existing connections (which are part of this cell) + if ((*i)->owners.size()>0) { + list::iterator neighb_with_this_cell= + // remove myself from the neighbor list of the node + find_if((*i)->owners.begin(), + (*i)->owners.end(), + bind2nd(mem_fun_ref( &Neighbor::CellEquals ),this->Index() ) ); + if (neighb_with_this_cell!=(*i)->owners.end()) + (*i)->owners.erase(neighb_with_this_cell); + } + + Node *previous; + if (i!=nodes.begin()) { + list::iterator previous_iterator=i; + previous_iterator--; + previous=*previous_iterator; + } else { + previous=nodes.back(); } + + Node *next; + list::iterator next_iterator=i; + next_iterator++; + if (next_iterator==nodes.end()) { + next=nodes.front(); + } else { + next=*next_iterator; + } + (*i)->owners.push_back( Neighbor( this, previous, next ) ); + } } +bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwall, NodeSet *node_set ) +{ + if (dead) return false; + + // check each edge for intersection with the line + ItList new_node_locations; + +#ifdef QDEBUG + qDebug() << "Cell " << Index() << " is doing DivideOverGivenLine" << endl; +#endif + for (list::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + Vector v3 = *(*i); + list::iterator nb=i; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + Vector v4 = *(*nb); + + double denominator = + (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); + + double ua = + ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; + double ub = + ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; + -/*! \brief Divide the cell over the line v1-v2. - - \param v1: First vertex of line. - \param v2: Second vertex of line. - \param fixed_wall: If true: wall will be set to "fixed" (i.e. not motile) - \return: true if the cell divided, false if not (i.e. no intersection between v1 and v2, and the cell) - */ -bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwall, NodeSet *node_set ) { - - if (dead) return false; - - - - // check each edge for intersection with the line - ItList new_node_locations; - - #ifdef QDEBUG - qDebug() << "Cell " << Index() << " is doing DivideOverGivenLine" << endl; - #endif - for (list::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - Vector v3 = *(*i); - list::iterator nb=i; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - Vector v4 = *(*nb); - - double denominator = - (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - - double ua = - ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = - ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; - - - //cerr << "Edge " << *i << " to " << *nb << ": ua = " << ua << ", ub = " << ub << ": "; - // this construction with "TINY" should simulate open/closed interval <0,1] - if ( ( TINY < ua && ua < 1.+TINY ) && ( TINY < ub && ub < 1.+TINY ) ) { - // yes, intersection detected. Push the location to the list of iterators - new_node_locations.push_back(nb); - - } - } - - #ifdef QDEBUG - if (new_node_locations.size()<2) { - qDebug() << "Line does not intersect with two edges of Cell " << Index() << endl; - qDebug() << "new_node_locations.size() = " << new_node_locations.size() << endl; - return false; - } - - ItList::iterator i = new_node_locations.begin(); - list< Node *>::iterator j; - qDebug() << "-------------------------------" << endl; - qDebug() << "Location of new nodes: " << (**i)->Index() << " and "; + //cerr << "Edge " << *i << " to " << *nb << ": ua = " << ua << ", ub = " << ub << ": "; + // this construction with "TINY" should simulate open/closed interval <0,1] + if ( ( TINY < ua && ua < 1.+TINY ) && ( TINY < ub && ub < 1.+TINY ) ) { + // yes, intersection detected. Push the location to the list of iterators + new_node_locations.push_back(nb); + + } +} + +#ifdef QDEBUG + if (new_node_locations.size()<2) { + qDebug() << "Line does not intersect with two edges of Cell " << Index() << endl; + qDebug() << "new_node_locations.size() = " << new_node_locations.size() << endl; + return false; + } - ++i; - j = *i; - if (j==nodes.begin()) j=nodes.end(); j--; - - qDebug() << (*j)->Index() << endl; - qDebug() << "-------------------------------" << endl; - - if ( **new_node_locations.begin() == *j ) { - qDebug() << "Rejecting proposed division (cutting off zero area)." << endl; - return false; - } - #endif +ItList::iterator i = new_node_locations.begin(); +list< Node *>::iterator j; +qDebug() << "-------------------------------" << endl; +qDebug() << "Location of new nodes: " << (**i)->Index() << " and "; + +++i; +j = *i; +if (j==nodes.begin()) j=nodes.end(); j--; - DivideWalls(new_node_locations, v1, v2, fix_cellwall, node_set); - - return true; - +qDebug() << (*j)->Index() << endl; +qDebug() << "-------------------------------" << endl; + +if ( **new_node_locations.begin() == *j ) { + qDebug() << "Rejecting proposed division (cutting off zero area)." << endl; + return false; + } +#endif + +DivideWalls(new_node_locations, v1, v2, fix_cellwall, node_set); + +return true; } // Core division procedure -void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vector to, bool fix_cellwall, NodeSet *node_set) { - - if (dead) return; - - bool boundary_touched_flag=false; - - // Step 0: keep some data about the parent before dividing - - ParentInfo parent_info; - parent_info.polarization = ReduceCellAndWalls( PINdir ); - parent_info.polarization.Normalise(); - parent_info.PINmembrane = SumTransporters(1); - parent_info.PINendosome = Chemical(1); - - //cerr << "Parent polarization before division: " << parent_info.polarization << endl; - - // Step 1: create a daughter cell - Cell *daughter=m->AddCell(new Cell()); - - // Step 2: Copy the basics of parent cell to daughter - for (int i=0;ichem[i]=chem[i]; - } - - daughter->cell_type = cell_type; - - for (int i=0;inew_chem[i]=new_chem[i]; - } - - - daughter->boundary=boundary; - daughter->m=m; - - daughter->target_area=target_area/2.; - - target_area/=2; - daughter->cellvec=cellvec; - - - // Division currently only works for convex cells: i.e. if the division line - // intersects the cells at two points only. - if (new_node_locations.size()!=2) { - - // Note: if you would add the possibility of dividing non-convex - // cells, remember to update the code below. There are some - // fixed-size arrays over there! - - cerr << "Warning in Cell::Division: division of non-convex cells not fully implemented" << endl; - - // Reject the daughter cell and decrement the amount of cells - // again. We can do this here because it is the last cell added. - // Never, ever try to fully erase a cell elsewhere, because we - // make heavy use of cell indices in this project; if you erase a - // Cell somewhere in the middle of Mesh::Cells the indices will - // get totally messed up...! (e.g. the indices used in Nodes::cells) - - #ifdef QDEBUG - qDebug() << "new_node_locations.size() = " << new_node_locations.size() <index = " << daughter->index << endl; - qDebug() << "cells.size() = " << m->cells.size() << endl; - #endif +void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vector to, bool fix_cellwall, NodeSet *node_set) +{ + + if (dead) return; + + bool boundary_touched_flag=false; + + // Step 0: keep some data about the parent before dividing + + ParentInfo parent_info; + parent_info.polarization = ReduceCellAndWalls( PINdir ); + parent_info.polarization.Normalise(); + parent_info.PINmembrane = SumTransporters(1); + parent_info.PINendosome = Chemical(1); + + //cerr << "Parent polarization before division: " << parent_info.polarization << endl; + + // Step 1: create a daughter cell + Cell *daughter=m->AddCell(new Cell()); + + // Step 2: Copy the basics of parent cell to daughter + for (int i=0;ichem[i]=chem[i]; + } + + daughter->cell_type = cell_type; + + for (int i=0;inew_chem[i]=new_chem[i]; + } + + daughter->boundary=boundary; + daughter->m=m; + + daughter->target_area=target_area/2.; + + target_area/=2; + daughter->cellvec=cellvec; + + // Division currently only works for convex cells: i.e. if the division line + // intersects the cells at two points only. + if (new_node_locations.size()!=2) { + + // Note: if you would add the possibility of dividing non-convex + // cells, remember to update the code below. There are some + // fixed-size arrays over there! + + cerr << "Warning in Cell::Division: division of non-convex cells not fully implemented" << endl; + + // Reject the daughter cell and decrement the amount of cells + // again. We can do this here because it is the last cell added. + // Never, ever try to fully erase a cell elsewhere, because we + // make heavy use of cell indices in this project; if you erase a + // Cell somewhere in the middle of Mesh::Cells the indices will + // get totally messed up...! (e.g. the indices used in Nodes::cells) + +#ifdef QDEBUG + qDebug() << "new_node_locations.size() = " << new_node_locations.size() <index = " << daughter->index << endl; + qDebug() << "cells.size() = " << m->cells.size() << endl; +#endif - m->cells.pop_back(); - Cell::NCells()--; - m->shuffled_cells.pop_back(); - return; - } - - - // We can be sure we only need two positions here because divisions - // of non-convex cells are rejected above. - Vector new_node[2]; - Node *new_node_ind[2]; - - int new_node_flag[2]; - Edge div_edges[2]; - - int nnc=0; - - Wall *div_wall[4]; - double orig_length[2]; - for (int i=0;i<4;i++) { div_wall[i]=0; orig_length[i/2] = 0.; } - - // construct new Nodes at the intersection points - // unless they coincide with existing points - for ( ItList::const_iterator i=new_node_locations.begin(); - i!=new_node_locations.end(); - i++) { - - // intersection between division axis - // and line from this node to its predecessor - - // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - Vector v1 = from; - Vector v2 = to; - Vector v3 = *(**i); - - // get previous node - list::iterator nb=*i; - if (nb == nodes.begin()) { - nb = nodes.end(); - } - nb--; - Vector v4=*( *nb ); - - double denominator = - (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - - double ua = - ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - - double intersec_x = v1.x + ua*(v2.x-v1.x); - double intersec_y = v1.y + ua*(v2.y-v1.y); - - // construct a new node at intersec - // we construct a vector temporarily, - // until we are sure we are going to keep the node... - // Node count is damaged if we construct superfluous nodes - Vector *n=new Vector(intersec_x,intersec_y,0); - - div_edges[nnc].first=*nb; - div_edges[nnc].second=**i; - - // Insert this new Node if it is far enough (5% of element length) - // from one of the two existing nodes, else use existing node - // - // old, fixed value was: par.collapse_node_threshold = 0.05 - double collapse_node_threshold = 0.05; + m->cells.pop_back(); + Cell::NCells()--; + m->shuffled_cells.pop_back(); + return; + } + + // We can be sure we only need two positions here because divisions + // of non-convex cells are rejected above. + Vector new_node[2]; + Node *new_node_ind[2]; + + int new_node_flag[2]; + Edge div_edges[2]; + + int nnc=0; + + Wall *div_wall[4]; + double orig_length[2]; + for (int i=0;i<4;i++) { div_wall[i]=0; orig_length[i/2] = 0.; } + + // construct new Nodes at the intersection points + // unless they coincide with existing points + for ( ItList::const_iterator i=new_node_locations.begin(); + i!=new_node_locations.end(); + i++) { + + // intersection between division axis + // and line from this node to its predecessor + + // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ + Vector v1 = from; + Vector v2 = to; + Vector v3 = *(**i); + + // get previous node + list::iterator nb=*i; + if (nb == nodes.begin()) { + nb = nodes.end(); + } + nb--; + Vector v4=*( *nb ); + + double denominator = + (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); + + double ua = + ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; + + double intersec_x = v1.x + ua*(v2.x-v1.x); + double intersec_y = v1.y + ua*(v2.y-v1.y); + + // construct a new node at intersec + // we construct a vector temporarily, + // until we are sure we are going to keep the node... + // Node count is damaged if we construct superfluous nodes + Vector *n=new Vector(intersec_x,intersec_y,0); + + div_edges[nnc].first=*nb; + div_edges[nnc].second=**i; + + // Insert this new Node if it is far enough (5% of element length) + // from one of the two existing nodes, else use existing node + // + // old, fixed value was: par.collapse_node_threshold = 0.05 + double collapse_node_threshold = 0.05; #ifdef FLEMING - collapse_node_threshold = par.collapse_node_threshold; + collapse_node_threshold = par.collapse_node_threshold; #endif - - double elem_length = ( (*(**i)) - (*(*nb)) ).Norm(); - if ( ( *(**i) - *n ).Norm() < collapse_node_threshold * elem_length ) { - new_node_flag[nnc]=1; - new_node[nnc] = *(**i); - new_node_ind[nnc] = **i; - //cerr << **i << endl ; - } else - if ( (*(*nb) - *n).Norm() < collapse_node_threshold * elem_length ) { - new_node_flag[nnc]=2; - new_node[nnc] = *(*nb); - new_node_ind[nnc] = *nb; - } else { - new_node_flag[nnc]=0; - new_node[nnc] = *n; - } - - nnc++; - delete n; + + double elem_length = ( (*(**i)) - (*(*nb)) ).Norm(); + if ( ( *(**i) - *n ).Norm() < collapse_node_threshold * elem_length ) { + new_node_flag[nnc]=1; + new_node[nnc] = *(**i); + new_node_ind[nnc] = **i; + //cerr << **i << endl ; + } else + if ( (*(*nb) - *n).Norm() < collapse_node_threshold * elem_length ) { + new_node_flag[nnc]=2; + new_node[nnc] = *(*nb); + new_node_ind[nnc] = *nb; + } else { + new_node_flag[nnc]=0; + new_node[nnc] = *n; + } + + nnc++; + delete n; + } + + + for (int i=0;i<2;i++) { + + Cell *neighbor_cell=0; // we need this to split up the "Wall" objects. + + // for both divided edges: + // insert its new node into all cells that own the divided edge + // but only if it really is a new node: + if (new_node_flag[i]!=0) { + if (fix_cellwall) { + (new_node_ind[i])->fixed = true; + + // all this we'll do later for the node set :-) + /* (new_node_ind[i])->boundary = true; + (new_node_ind[i])->sam = true; + boundary = SAM; + daughter->boundary = SAM; + boundary_touched_flag = true; + */ + } + + } else { + + // (Construct a list of all owners:) + // really construct the new node (if this is a new node) + new_node_ind[i] = + m->AddNode(new Node (new_node[i]) ); + + + + // if a new node is inserted into a fixed edge (i.e. in the petiole) + // make the new node fixed as well + (new_node_ind[i])->fixed = (div_edges[i].first)->fixed && + (div_edges[i].second)->fixed; + + // Insert Node into NodeSet if the div_edge is part of it. + if ( + (div_edges[i].first->node_set && div_edges[i].second->node_set) && + (div_edges[i].first->node_set == div_edges[i].second->node_set)) + { + //cerr << "Inserting node into node set\n"; + div_edges[i].first->node_set->AddNode( new_node_ind[i] ); } - - - for (int i=0;i<2;i++) { - - Cell *neighbor_cell=0; // we need this to split up the "Wall" objects. - - // for both divided edges: - // insert its new node into all cells that own the divided edge - // but only if it really is a new node: - if (new_node_flag[i]!=0) { - if (fix_cellwall) { - (new_node_ind[i])->fixed = true; - - // all this we'll do later for the node set :-) - /* (new_node_ind[i])->boundary = true; - (new_node_ind[i])->sam = true; - boundary = SAM; - daughter->boundary = SAM; - boundary_touched_flag = true; - */ - } - - } else { - - // (Construct a list of all owners:) - // really construct the new node (if this is a new node) - new_node_ind[i] = - m->AddNode(new Node (new_node[i]) ); - - - - // if a new node is inserted into a fixed edge (i.e. in the petiole) - // make the new node fixed as well - (new_node_ind[i])->fixed = (div_edges[i].first)->fixed && - (div_edges[i].second)->fixed; - - // Insert Node into NodeSet if the div_edge is part of it. - if ( - (div_edges[i].first->node_set && div_edges[i].second->node_set) && - (div_edges[i].first->node_set == div_edges[i].second->node_set)) - { - //cerr << "Inserting node into node set\n"; - div_edges[i].first->node_set->AddNode( new_node_ind[i] ); - } - - // if the new wall should be fixed (i.e. immobile, or moving as - // solid body), make it so, and make it part of the boundary. Using - // this to make a nice initial condition by cutting off part of a - // growing leaf. - - if (fix_cellwall) { - (new_node_ind[i])->fixed = true; - - // All this we'll do later for the node set only - } - - // if new node is inserted into the boundary - // it will be part of the boundary, too + + // if the new wall should be fixed (i.e. immobile, or moving as + // solid body), make it so, and make it part of the boundary. Using + // this to make a nice initial condition by cutting off part of a + // growing leaf. + + if (fix_cellwall) { + (new_node_ind[i])->fixed = true; + + // All this we'll do later for the node set only + } + + // if new node is inserted into the boundary + // it will be part of the boundary, too + + new_node_ind[i]->UnsetBoundary(); + if ((div_edges[i].first->BoundaryP() && div_edges[i].second->BoundaryP()) && // Both edge nodes are boundary nodes AND + ((m->findNextBoundaryNode(div_edges[i].first))->Index() == div_edges[i].second->Index())){ // The boundary proceeds from first to second. + +#ifdef QDEBUG + qDebug() << "Index of the first node: " << div_edges[i].first->Index() << endl; + qDebug() << "Index of the second node: " << div_edges[i].second->Index() << endl; + qDebug() << "Boundary proceeds from: " << div_edges[i].first->Index() + << "to: " << (m->findNextBoundaryNode(div_edges[i].first))->Index() << endl << endl; +#endif + new_node_ind[i]->SetBoundary(); + + // We will need to repair the boundary polygon later, since we will insert new nodes + //cerr << "Boundary touched for Node " << new_node_ind[i]->Index() << "\n"; + boundary_touched_flag=true; - new_node_ind[i]->UnsetBoundary(); - if ((div_edges[i].first->BoundaryP() && div_edges[i].second->BoundaryP()) && // Both edge nodes are boundary nodes AND - ((m->findNextBoundaryNode(div_edges[i].first))->Index() == div_edges[i].second->Index())){ // The boundary proceeds from first to second. + // and insert it into the boundary_polygon + // find the position of the first node in the boundary + list::iterator ins_pos = find + (m->boundary_polygon->nodes.begin(), + m->boundary_polygon->nodes.end(), + div_edges[i].first); + // ... second node comes before or after it ... + if (*(++ins_pos!=m->boundary_polygon->nodes.end()? + ins_pos:m->boundary_polygon->nodes.begin())!=div_edges[i].second) { - #ifdef QDEBUG - qDebug() << "Index of the first node: " << div_edges[i].first->Index() << endl; - qDebug() << "Index of the second node: " << div_edges[i].second->Index() << endl; - qDebug() << "Boundary proceeds from: " << div_edges[i].first->Index() - << "to: " << (m->findNextBoundaryNode(div_edges[i].first))->Index() << endl << endl; - #endif - new_node_ind[i]->SetBoundary(); + m->boundary_polygon->nodes.insert(((ins_pos--)!=m->boundary_polygon->nodes.begin()?ins_pos:(--m->boundary_polygon->nodes.end())), new_node_ind[i]); - // We will need to repair the boundary polygon later, since we will insert new nodes - //cerr << "Boundary touched for Node " << new_node_ind[i]->Index() << "\n"; - boundary_touched_flag=true; - - // and insert it into the boundary_polygon - // find the position of the first node in the boundary - list::iterator ins_pos = find - (m->boundary_polygon->nodes.begin(), - m->boundary_polygon->nodes.end(), - div_edges[i].first); - // ... second node comes before or after it ... - if (*(++ins_pos!=m->boundary_polygon->nodes.end()? - ins_pos:m->boundary_polygon->nodes.begin())!=div_edges[i].second) { - - m->boundary_polygon->nodes.insert(((ins_pos--)!=m->boundary_polygon->nodes.begin()?ins_pos:(--m->boundary_polygon->nodes.end())), new_node_ind[i]); - - // .. set the neighbors of the new node ... - // in this case e.second and e.first are inverted - } else { - // insert before second node, so leave ins_pos as it is, - // that is: incremented - m->boundary_polygon->nodes.insert(ins_pos, new_node_ind[i]); - // .. set the neighbors of the new node ... - } - } - - list owners; - - // push all cells owning the two nodes of the divides edges - // onto a list + // .. set the neighbors of the new node ... + // in this case e.second and e.first are inverted + } else { + // insert before second node, so leave ins_pos as it is, + // that is: incremented + m->boundary_polygon->nodes.insert(ins_pos, new_node_ind[i]); + // .. set the neighbors of the new node ... + } + } + + list owners; - copy((div_edges[i].first)->owners.begin(), - (div_edges[i].first)->owners.end(), - back_inserter(owners)); - copy((div_edges[i].second)->owners.begin(), - (div_edges[i].second)->owners.end(), - back_inserter(owners)); - - - // find first non-self duplicate in the owners: - // cells owning the same two nodes - // share an edge with me - owners.sort( mem_fun_ref( &Neighbor::Cmp ) ); + // push all cells owning the two nodes of the divides edges + // onto a list + + copy((div_edges[i].first)->owners.begin(), + (div_edges[i].first)->owners.end(), + back_inserter(owners)); + copy((div_edges[i].second)->owners.begin(), + (div_edges[i].second)->owners.end(), + back_inserter(owners)); + + + // find first non-self duplicate in the owners: + // cells owning the same two nodes + // share an edge with me + owners.sort( mem_fun_ref( &Neighbor::Cmp ) ); - #ifdef QDEBUG - list unique_owners; - copy(owners.begin(), owners.end(), back_inserter(unique_owners)); - unique_owners.unique( mem_fun_ref( &Neighbor::Eq ) ); - qDebug() << "The dividing edge nodes: " << div_edges[i].first->Index() << " and " << div_edges[i].second->Index() << " are owned by cells: "; - // spit out each owners' cell index - foreach(Neighbor neighbor, unique_owners){ - qDebug() << neighbor.cell->Index() << " "; - } - qDebug() << endl; - #endif +#ifdef QDEBUG + list unique_owners; + copy(owners.begin(), owners.end(), back_inserter(unique_owners)); + unique_owners.unique( mem_fun_ref( &Neighbor::Eq ) ); + qDebug() << "The dividing edge nodes: " << div_edges[i].first->Index() + << " and " << div_edges[i].second->Index() << " are owned by cells: "; + + // spit out each owners' cell index + foreach(Neighbor neighbor, unique_owners){ + qDebug() << neighbor.cell->Index() << " "; + } + qDebug() << endl; +#endif + + // Search through the sorted list of edge node owners looking for duplicate pairs. Each pair represents an actual edge owner. + list edge_owners; + list::iterator it; + for (it=owners.begin(); it!=owners.end(); it++) { + it = adjacent_find(it, owners.end(), neighbor_cell_eq); + if (it == owners.end()) break; // bail if reach the end of the list +#ifdef QDEBUG + qDebug() << "Considering: " << it->cell->Index() << " as a possible edge owner." << endl; +#endif + if (it->cell->Index() != this->Index()) { +#ifdef QDEBUG + qDebug() << "Adding: " << it->cell->Index() << " to the list of edge owners." << endl; +#endif + edge_owners.push_back(*it); + } + } - // Search through the sorted list of edge node owners looking for duplicate pairs. Each pair represents an actual edge owner. - list edge_owners; - list::iterator it; - for (it=owners.begin(); it!=owners.end(); it++) { - it = adjacent_find(it, owners.end(), neighbor_cell_eq); - if (it == owners.end()) break; // bail if reach the end of the list - #ifdef QDEBUG - qDebug() << "Considering: " << it->cell->Index() << " as a possible edge owner." << endl; - #endif - if (it->cell->Index() != this->Index()) { - #ifdef QDEBUG - qDebug() << "Adding: " << it->cell->Index() << " to the list of edge owners." << endl; - #endif - edge_owners.push_back(*it); - } - } + if (edge_owners.size() > 1){ + // Remove the boundary polygon - if its there + list::iterator it; + if ((it = find_if (edge_owners.begin(), edge_owners.end(), bind2nd(mem_fun_ref(&Neighbor::CellEquals), -1))) + != edge_owners.end()) { +#ifdef QDEBUG + qDebug() << "deleating: " << it->cell->Index() << " from the list of edge owners." << endl; +#endif + edge_owners.erase(it); + } + } + +#ifdef QDEBUG + qDebug() << "The edge owners list has: " << edge_owners.size() << " elements" << endl; +#endif - if (edge_owners.size() > 1){ - // Remove the boundary polygon - if its there - list::iterator it; - if ((it = find_if (edge_owners.begin(), edge_owners.end(), bind2nd(mem_fun_ref(&Neighbor::CellEquals), -1))) != edge_owners.end()) { - #ifdef QDEBUG - qDebug() << "deleating: " << it->cell->Index() << " from the list of edge owners." << endl; - #endif - edge_owners.erase(it); - } - } + // Since the list should always contain exactly one element, pass it on as an iterator + list::iterator c = (edge_owners.size() != 0) ? edge_owners.begin() : edge_owners.end(); + + // (can we have more than one neighboring cell here??) + if (c!=owners.end()) { + neighbor_cell = c->cell; + if (!c->cell->BoundaryPolP()) { - #ifdef QDEBUG - qDebug() << "The edge owners list has: " << edge_owners.size() << " elements" << endl; - #endif + // find correct position in the cells node list + // to insert the new node + list::iterator ins_pos = find + (neighbor_cell->nodes.begin(), + neighbor_cell->nodes.end(), + div_edges[i].first); + + neighbor_cell->nodes.insert(ins_pos, new_node_ind[i]); + neighbor_cell->ConstructConnections(); - // Since the list should always contain exactly one element, pass it on as an iterator - list::iterator c = (edge_owners.size() != 0) ? edge_owners.begin() : edge_owners.end(); + // give walls to daughter later + } + } else { + neighbor_cell = 0; + } + } + + // Split the Wall with the neighboring cell + + // if the neighbor cell has not yet been identified above, do it now + if (neighbor_cell == 0) { + + list owners; - // (can we have more than one neighboring cell here??) - if (c!=owners.end()) { - neighbor_cell = c->cell; - if (!c->cell->BoundaryPolP()) { + // push all cells owning the two nodes of the divides edges + // onto a list + copy((div_edges[i].first)->owners.begin(), + (div_edges[i].first)->owners.end(), + back_inserter(owners)); + copy((div_edges[i].second)->owners.begin(), + (div_edges[i].second)->owners.end(), + back_inserter(owners)); + + + // find first non-self duplicate in the owners: + // cells owning the same two nodes + // share an edge with me + owners.sort( mem_fun_ref( &Neighbor::Cmp ) ); - // find correct position in the cells node list - // to insert the new node - list::iterator ins_pos = find - (neighbor_cell->nodes.begin(), - neighbor_cell->nodes.end(), - div_edges[i].first); - - neighbor_cell->nodes.insert(ins_pos, new_node_ind[i]); - neighbor_cell->ConstructConnections(); - - // give walls to daughter later - } - } else { - neighbor_cell = 0; - } - } - - // Split the Wall with the neighboring cell - - // if the neighbor cell has not yet been identified above, do it now - if (neighbor_cell == 0) { - - list owners; - - // push all cells owning the two nodes of the divides edges - // onto a list - copy((div_edges[i].first)->owners.begin(), - (div_edges[i].first)->owners.end(), - back_inserter(owners)); - copy((div_edges[i].second)->owners.begin(), - (div_edges[i].second)->owners.end(), - back_inserter(owners)); - - - // find first non-self duplicate in the owners: - // cells owning the same two nodes - // share an edge with me - owners.sort( mem_fun_ref( &Neighbor::Cmp ) ); + list::iterator c; + for (c=owners.begin(); + c!=owners.end(); + c++) { + c=adjacent_find(c,owners.end(),neighbor_cell_eq); + if (c->cell->Index() != this->Index() || c==owners.end()) break; + } + + if (c!=owners.end()) + neighbor_cell = c->cell; + else + neighbor_cell = 0; + } + + + if (neighbor_cell /* && !neighbor_cell->BoundaryPolP() */) { + + //cerr << "Cell " << index << " says: neighboring cell is " << neighbor_cell->index << endl; + + /*************** 1. Find the correct wall element ********************/ + + list::iterator w, start_search; + w = start_search = walls.begin(); + do { + // Find wall between this cell and neighbor cell + w = find_if( start_search, walls.end(), bind2nd (mem_fun( &Wall::is_wall_of_cell_p ), neighbor_cell ) ); + start_search = w; start_search++; // continue searching at next element + } while ( w!=walls.end() && !(*w)->IntersectsWithDivisionPlaneP( from, to ) ); // go on until we find the right one. + + if (w == walls.end()) { +#ifdef QDEBUG + qDebug() << "Whoops, wall element not found...!" << endl; + qDebug() << "Cell ID: " << neighbor_cell->Index() << endl; + qDebug() << "My cell ID: " << Index() << endl; +#endif + } else { + + // 2. Split it up, if we should (sometimes, the new node coincides with an existing node so + // we should not split up the Wall) + + if (new_node_ind[i]!=(*w)->n1 && new_node_ind[i]!=(*w)->n2) { + + Wall *new_wall; - list::iterator c; - for (c=owners.begin(); - c!=owners.end(); - c++) { - c=adjacent_find(c,owners.end(),neighbor_cell_eq); - if (c->cell->Index() != this->Index() || c==owners.end()) break; - } - - if (c!=owners.end()) - neighbor_cell = c->cell; - else - neighbor_cell = 0; - } - - - if (neighbor_cell /* && !neighbor_cell->BoundaryPolP() */) { - - //cerr << "Cell " << index << " says: neighboring cell is " << neighbor_cell->index << endl; - - /*************** 1. Find the correct wall element ********************/ - - list::iterator w, start_search; - w = start_search = walls.begin(); - do { - // Find wall between this cell and neighbor cell - w = find_if( start_search, walls.end(), bind2nd (mem_fun( &Wall::is_wall_of_cell_p ), neighbor_cell ) ); - start_search = w; start_search++; // continue searching at next element - } while ( w!=walls.end() && !(*w)->IntersectsWithDivisionPlaneP( from, to ) ); // go on until we find the right one. - - if (w == walls.end()) { - #ifdef QDEBUG - qDebug() << "Whoops, wall element not found...!" << endl; - qDebug() << "Cell ID: " << neighbor_cell->Index() << endl; - qDebug() << "My cell ID: " << Index() << endl; - #endif - } else { - - // 2. Split it up, if we should (sometimes, the new node coincides with an existing node so - // we should not split up the Wall) - - if (new_node_ind[i]!=(*w)->n1 && new_node_ind[i]!=(*w)->n2) { - - Wall *new_wall; - - // keep the length of the original wall; we need it to equally divide the transporter concentrations - // over the two daughter walls - (*w)->SetLength(); // make sure we've got the current length - orig_length[i] = (*w)->Length(); - //cerr << "Original length is " << orig_length[i] << endl; - if ((*w)->c1 == this ) { - - // cerr << "Cell " << (*w)->c1->Index() << " splits up wall " << *(*w) << ", into: " << endl; - new_wall = new Wall( (*w)->n1, new_node_ind[i], this, neighbor_cell); - (*w)->n1 = new_node_ind[i]; - - // cerr << "wall " << *(*w) << ", and new wall " << *new_wall << endl; - - } else { - new_wall = new Wall( (*w)->n1, new_node_ind[i], neighbor_cell, this); - - (*w)->n1 = new_node_ind[i]; - } - - - // 3. Give wall elements to appropriate cells - if (new_wall->n1 != new_wall->n2) { - - if (par.copy_wall) - new_wall->CopyWallContents(**w); - else { - // If wall contents are not copied, decide randomly which wall will be the "parent" - // otherwise we will get biases (to the left), for example in the meristem growth model - if (RANDOM()<0.5) { - new_wall->SwapWallContents(*w); - } - } - AddWall(new_wall); - // cerr << "Building new wall: this=" << Index() << ", neighbor_cell = " << neighbor_cell->Index() << endl; - - neighbor_cell->AddWall( new_wall); - //cerr << "Existing wall: c1 = " << (*w)->c1->Index() << ", neighbor_cell = " << (*w)->c2->Index() << endl; - - // Remember the addresses of the new walls - div_wall[2*i+0] = *w; - div_wall[2*i+1] = new_wall; - - // we will correct the transporter concentrations later in this member function, after division - // First the new nodes should be inserted into the cells, before we can calculate wall lengths - // Remember that cell walls can be bent, so have a bigger length than the Euclidean distance n1->n2 - - } else { - delete new_wall; - } - } - } - } - } // closing loop over the two divided edges (for (int i=0;i<2;i++) ) - - // move half of the nodes to the daughter - { - //cerr << "Daughter: "; - list::iterator start, stop; - - start=new_node_locations.front(); - - //cerr << "*new_node_locations.front() = " << *new_node_locations.front() << endl; - if (new_node_flag[0]==1) { - start++; - if (start==nodes.end()) - start=nodes.begin(); - } - - stop=new_node_locations.back(); - if (new_node_flag[1]==2) { - if (stop==nodes.begin()) - stop=nodes.end(); - stop--; - } - list::iterator i=start; - while ( i!=stop) { - - // give the node to the daughter - // (find references to parent cell from this node, - // and remove them) - list::iterator neighb_with_this_cell= - find_if((*i)->owners.begin(), - (*i)->owners.end(), - bind2nd(mem_fun_ref( &Neighbor::CellEquals ),this->Index() ) ); - if (neighb_with_this_cell==(*i)->owners.end()) { - #ifdef QDEBUG - qDebug() << "not found" << endl; - #endif - abort(); - } - - (*i)->owners.erase(neighb_with_this_cell); - - daughter->nodes.push_back( *i ); - - - i++; - if (i==nodes.end()) - i=nodes.begin(); - }; + // keep the length of the original wall; we need it to equally divide the transporter concentrations + // over the two daughter walls + (*w)->SetLength(); // make sure we've got the current length + orig_length[i] = (*w)->Length(); + //cerr << "Original length is " << orig_length[i] << endl; + if ((*w)->c1 == this ) { + + // cerr << "Cell " << (*w)->c1->Index() << " splits up wall " << *(*w) << ", into: " << endl; + new_wall = new Wall( (*w)->n1, new_node_ind[i], this, neighbor_cell); + (*w)->n1 = new_node_ind[i]; + + // cerr << "wall " << *(*w) << ", and new wall " << *new_wall << endl; + + } else { + new_wall = new Wall( (*w)->n1, new_node_ind[i], neighbor_cell, this); + + (*w)->n1 = new_node_ind[i]; + } + + + // 3. Give wall elements to appropriate cells + if (new_wall->n1 != new_wall->n2) { + + if (par.copy_wall) + new_wall->CopyWallContents(**w); + else { + // If wall contents are not copied, decide randomly which wall will be the "parent" + // otherwise we will get biases (to the left), for example in the meristem growth model + if (RANDOM()<0.5) { + new_wall->SwapWallContents(*w); + } + } + AddWall(new_wall); + // cerr << "Building new wall: this=" << Index() << ", neighbor_cell = " << neighbor_cell->Index() << endl; + + neighbor_cell->AddWall( new_wall); + //cerr << "Existing wall: c1 = " << (*w)->c1->Index() << ", neighbor_cell = " << (*w)->c2->Index() << endl; + + // Remember the addresses of the new walls + div_wall[2*i+0] = *w; + div_wall[2*i+1] = new_wall; + + // we will correct the transporter concentrations later in this member function, after division + // First the new nodes should be inserted into the cells, before we can calculate wall lengths + // Remember that cell walls can be bent, so have a bigger length than the Euclidean distance n1->n2 + + } else { + delete new_wall; + } } - - // new node list of parent - list new_nodes_parent; - - // half of the nodes stay with the parent - { - list::iterator start, stop; - start=new_node_locations.back(); - if (new_node_flag[1]==1) { - start++; - if (start==nodes.end()) - start=nodes.begin(); - } - stop=new_node_locations.front(); - if (new_node_flag[0]==2) { - if (stop==nodes.begin()) - stop=nodes.end(); - stop--; - } - - list::iterator i=start; - while (i!=stop) { - new_nodes_parent.push_back( *i ); - - i++; - if (i==nodes.end()) - i = nodes.begin(); - }; - } + } + } + } // closing loop over the two divided edges (for (int i=0;i<2;i++) ) + + // move half of the nodes to the daughter + { + //cerr << "Daughter: "; + list::iterator start, stop; + + start=new_node_locations.front(); + + //cerr << "*new_node_locations.front() = " << *new_node_locations.front() << endl; + if (new_node_flag[0]==1) { + start++; + if (start==nodes.end()) + start=nodes.begin(); + } + + stop=new_node_locations.back(); + if (new_node_flag[1]==2) { + if (stop==nodes.begin()) + stop=nodes.end(); + stop--; + } + list::iterator i=start; + while ( i!=stop) { + + // give the node to the daughter + // (find references to parent cell from this node, + // and remove them) + list::iterator neighb_with_this_cell= + find_if((*i)->owners.begin(), + (*i)->owners.end(), + bind2nd(mem_fun_ref( &Neighbor::CellEquals ),this->Index() ) ); + if (neighb_with_this_cell==(*i)->owners.end()) { + +#ifdef QDEBUG + qDebug() << "not found" << endl; +#endif + abort(); + } + + (*i)->owners.erase(neighb_with_this_cell); + + daughter->nodes.push_back( *i ); + - // insert shared wall - // insert shared nodes on surface of parent cell - new_nodes_parent.push_back( new_node_ind[0] ); - daughter->nodes.push_back ( new_node_ind[1] ); - - // optionally add the new node to the nodeset (passed by pointer) - // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) - if (node_set) { - node_set->AddNode( new_node_ind[0] ); - } - + i++; + if (i==nodes.end()) + i=nodes.begin(); + }; + } + + // new node list of parent + list new_nodes_parent; + + // half of the nodes stay with the parent + { + list::iterator start, stop; + start=new_node_locations.back(); + if (new_node_flag[1]==1) { + start++; + if (start==nodes.end()) + start=nodes.begin(); + } + stop=new_node_locations.front(); + if (new_node_flag[0]==2) { + if (stop==nodes.begin()) + stop=nodes.end(); + stop--; + } + + list::iterator i=start; + while (i!=stop) { + new_nodes_parent.push_back( *i ); + + i++; + if (i==nodes.end()) + i = nodes.begin(); + }; + } + + // insert shared wall + // insert shared nodes on surface of parent cell + new_nodes_parent.push_back( new_node_ind[0] ); + daughter->nodes.push_back ( new_node_ind[1] ); + + // optionally add the new node to the nodeset (passed by pointer) + // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) + if (node_set) { + node_set->AddNode( new_node_ind[0] ); + } + #define MULTIPLE_NODES #ifdef MULTIPLE_NODES - // intermediate, extra nodes - // Calculate distance between the two new nodes - double dist=( new_node[1] - new_node[0] ).Norm(); - //bool fixed_wall = (new_node_ind[0])->fixed && (new_node_ind[1])->fixed; - bool fixed_wall = false; - - // Estimate number of extra nodes in wall - // factor 4 is to keep tension on the walls; - // this is a hidden parameter and should be made explicit - // later on. - int n=(int)((dist/Node::target_length)/4+0.5); - - Vector nodevec = ( new_node[1]- new_node[0]).Normalised(); - - double element_length = dist/(double)(n+1); - - // note that wall nodes need to run in inverse order in parent - list::iterator ins_pos = daughter->nodes.end(); - for (int i=1;i<=n;i++) { - Node *node= - m->AddNode( new Node( new_node[0] + i*element_length*nodevec ) ); - - node->fixed=fixed_wall; - - if (!fix_cellwall) - node->boundary = false; - else { - node->fixed = true; - } - - ins_pos=daughter->nodes.insert(ins_pos, node ); - new_nodes_parent.push_back( node ); - - // optionally add the new node to the nodeset (passed by pointer) - // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) - if (node_set) { - node_set->AddNode( node ); - } - - } + // intermediate, extra nodes + // Calculate distance between the two new nodes + double dist=( new_node[1] - new_node[0] ).Norm(); + //bool fixed_wall = (new_node_ind[0])->fixed && (new_node_ind[1])->fixed; + bool fixed_wall = false; + + // Estimate number of extra nodes in wall + // factor 4 is to keep tension on the walls; + // this is a hidden parameter and should be made explicit + // later on. + int n=(int)((dist/Node::target_length)/4+0.5); + + Vector nodevec = ( new_node[1]- new_node[0]).Normalised(); + + double element_length = dist/(double)(n+1); + + // note that wall nodes need to run in inverse order in parent + list::iterator ins_pos = daughter->nodes.end(); + for (int i=1;i<=n;i++) { + Node *node= + m->AddNode( new Node( new_node[0] + i*element_length*nodevec ) ); + + node->fixed=fixed_wall; + + if (!fix_cellwall) + node->boundary = false; + else { + node->fixed = true; + } + + ins_pos=daughter->nodes.insert(ins_pos, node ); + new_nodes_parent.push_back( node ); + + // optionally add the new node to the nodeset (passed by pointer) + // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) + if (node_set) { + node_set->AddNode( node ); + } + + } #endif - daughter->nodes.push_back( new_node_ind[0] ); - new_nodes_parent.push_back( new_node_ind[1] ); - - // optionally add the new node to the nodeset (passed by pointer) - // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) - if (node_set) { - node_set->AddNode( new_node_ind[1] ); - } - - // move the new nodes to the parent - nodes.clear(); - copy( new_nodes_parent.begin(), - new_nodes_parent.end(), - back_inserter(nodes) ); - - - // Repair cell lists of Nodes, and node connectivities - ConstructConnections(); - daughter->ConstructConnections(); - - if (boundary_touched_flag) { - m->boundary_polygon->ConstructConnections(); - } - - // collecting neighbors of divided cell - list broken_neighbors; - - // this cell's old neighbors - copy(neighbors.begin(), neighbors.end(), back_inserter(broken_neighbors) ); - - // this cell - broken_neighbors.push_back(this); - - // its daughter - broken_neighbors.push_back(daughter); - - - - // Recalculate area of parent and daughter - area = CalcArea(); - daughter->area = daughter->CalcArea(); - - SetIntegrals(); - daughter->SetIntegrals(); - - - - // Add a "Cell Wall" for diffusion algorithms - Wall *wall = new Wall( new_node_ind[0], new_node_ind[1], this, daughter ); - - AddWall( wall ); - - daughter->AddWall( wall ); - - //cerr << "Correct walls of cell " << Index() << " and daughter " << daughter->Index() << endl; - - // Move Walls to daughter cell - list copy_walls = walls; - for (list::iterator w = copy_walls.begin(); - w!=copy_walls.end(); - w++) { - - //cerr << "Doing wall, before: " << **w << endl; - - // checks the nodes of the wall and gives it away if appropriate - (*w)->CorrectWall ( ); - - //cerr << "and after: " << **w << endl; - - } - - - - // Correct tranporterconcentrations of divided walls - for (int i=0;i<4;i++) { - if (div_wall[i]) { - div_wall[i]->SetLength(); - div_wall[i]->CorrectTransporters(orig_length[i/2]); - } - } - - //cerr << "Cell " << index << " has been dividing, and gave birth to Cell " << daughter->index << endl; - - // now reconstruct neighbor list for all "broken" neighbors - - for (list::iterator i=broken_neighbors.begin(); - i!=broken_neighbors.end();i++) { - ((Cell *)(*i))->ConstructNeighborList(); - } - - - ConstructNeighborList(); - daughter->ConstructNeighborList(); - - m->plugin->OnDivide(&parent_info, daughter, this); - - daughter->div_counter=(++div_counter); - - + daughter->nodes.push_back( new_node_ind[0] ); + new_nodes_parent.push_back( new_node_ind[1] ); + + // optionally add the new node to the nodeset (passed by pointer) + // (in this way we can move the NodeSet as a whole; useful for a fixed cutting line) + if (node_set) { + node_set->AddNode( new_node_ind[1] ); + } + + // move the new nodes to the parent + nodes.clear(); + copy( new_nodes_parent.begin(), + new_nodes_parent.end(), + back_inserter(nodes) ); + + + // Repair cell lists of Nodes, and node connectivities + ConstructConnections(); + daughter->ConstructConnections(); + + if (boundary_touched_flag) { + m->boundary_polygon->ConstructConnections(); + } + + // collecting neighbors of divided cell + list broken_neighbors; + + // this cell's old neighbors + copy(neighbors.begin(), neighbors.end(), back_inserter(broken_neighbors) ); + + // this cell + broken_neighbors.push_back(this); + + // its daughter + broken_neighbors.push_back(daughter); + + // Recalculate area of parent and daughter + area = CalcArea(); + daughter->area = daughter->CalcArea(); + + SetIntegrals(); + daughter->SetIntegrals(); + + // Add a "Cell Wall" for diffusion algorithms + Wall *wall = new Wall( new_node_ind[0], new_node_ind[1], this, daughter ); + + AddWall( wall ); + + daughter->AddWall( wall ); + + //cerr << "Correct walls of cell " << Index() << " and daughter " << daughter->Index() << endl; + + // Move Walls to daughter cell + list copy_walls = walls; + for (list::iterator w = copy_walls.begin(); + w!=copy_walls.end(); + w++) { + + //cerr << "Doing wall, before: " << **w << endl; + + // checks the nodes of the wall and gives it away if appropriate + (*w)->CorrectWall ( ); + + //cerr << "and after: " << **w << endl; + + } + + // Correct tranporterconcentrations of divided walls + for (int i=0;i<4;i++) { + if (div_wall[i]) { + div_wall[i]->SetLength(); + div_wall[i]->CorrectTransporters(orig_length[i/2]); + } + } + + //cerr << "Cell " << index << " has been dividing, and gave birth to Cell " << daughter->index << endl; + + // now reconstruct neighbor list for all "broken" neighbors + + for (list::iterator i=broken_neighbors.begin(); + i!=broken_neighbors.end();i++) { + ((Cell *)(*i))->ConstructNeighborList(); + } + + ConstructNeighborList(); + daughter->ConstructNeighborList(); + + m->plugin->OnDivide(&parent_info, daughter, this); + + daughter->div_counter=(++div_counter); } // Move the whole cell void Cell::Move(const Vector T) { - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - *(*i)+=T; - } + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + *(*i)+=T; + } } -double Cell::Displace(double dx, double dy, double dh) { - - // Displace whole cell, add resulting energy to dh, - // and accept displacement if energetically favorable - // - // Method is called if a "fixed" node is displaced - - // Warning: length constraint not yet CORRECTLY implemented for this function - - // Attempt to move this cell in a random direction - // Vector movement(par.mc_cell_stepsize*(RANDOM()-0.5),par.mc_cell_stepsize*(RANDOM()-0.5),0); - - - dh=0; - - Vector movement(dx,dy,0); - - vector< pair > length_edges; - vector cellareas; - cellareas.reserve(neighbors.size()); - - // for the length constraint, collect all edges to this cell's nodes, - // which are not part of the cell - // the length of these edges will change - - double old_length=0.; - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - +double Cell::Displace(double dx, double dy, double dh) +{ + + // Displace whole cell, add resulting energy to dh, + // and accept displacement if energetically favorable + // + // Method is called if a "fixed" node is displaced + + // Warning: length constraint not yet CORRECTLY implemented for this function + + // Attempt to move this cell in a random direction + // Vector movement(par.mc_cell_stepsize*(RANDOM()-0.5),par.mc_cell_stepsize*(RANDOM()-0.5),0); + + + dh=0; + + Vector movement(dx,dy,0); + + vector< pair > length_edges; + vector cellareas; + cellareas.reserve(neighbors.size()); + + // for the length constraint, collect all edges to this cell's nodes, + // which are not part of the cell + // the length of these edges will change + + double old_length=0.; + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + + for (list::const_iterator n=(*i)->owners.begin(); + n!=(*i)->owners.end(); + n++) { + + if (n->getCell()!=this) { + length_edges.push_back( pair (*i, n->nb1) ); + length_edges.push_back( pair (*i, n->nb2) ); + old_length += + DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm())+ + DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); + } + } + } - for (list::const_iterator n=(*i)->owners.begin(); - n!=(*i)->owners.end(); - n++) { - - if (n->getCell()!=this) { - length_edges.push_back( pair (*i, n->nb1) ); - length_edges.push_back( pair (*i, n->nb2) ); - old_length += - DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm())+ - DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); - } - } - } - - // calculate area energy difference of neighboring cells - // (this cells' shape remains unchanged) - double old_area_energy=0., old_length_energy=0.; - for (list::const_iterator i=neighbors.begin(); - i!=neighbors.end(); - i++) { - old_area_energy += DSQR((*i)->Area()-(*i)->TargetArea()); - old_length_energy += DSQR((*i)->Length()-(*i)->TargetLength()); - } - - Move(movement); - - double new_area_energy=0., new_length_energy=0.; - for (list::const_iterator i=neighbors.begin(); - i!=neighbors.end(); - i++) { - cellareas.push_back((*i)->CalcArea()); - new_area_energy += DSQR(cellareas.back()-(*i)->TargetArea()); - new_length_energy += DSQR((*i)->CalcLength()-(*i)->TargetLength()); - } - - double new_length=0; - for ( vector< pair< Node *, Node * > >::const_iterator e = length_edges.begin(); - e != length_edges.end(); - e++) { - new_length += DSQR(Node::target_length- - (*(e->first)-*(e->second)).Norm()); - } - - - dh += (new_area_energy - old_area_energy) + (new_length_energy - old_length_energy) * lambda_celllength + - par.lambda_length * (new_length - old_length); - - if (dh<0 || RANDOM()::const_iterator nb_it = neighbors.begin(); - for (vector::const_iterator ar_it = cellareas.begin(); - ar_it!=cellareas.end(); - ( ar_it++, nb_it++) ) { - ((Cell *)(*nb_it))->area = *ar_it; - (*nb_it)->SetIntegrals(); - } - - //cerr << endl; - - } else { - - Move ( -1*movement); - - } - - return dh; + // calculate area energy difference of neighboring cells + // (this cells' shape remains unchanged) + double old_area_energy=0., old_length_energy=0.; + for (list::const_iterator i=neighbors.begin(); + i!=neighbors.end(); + i++) { + old_area_energy += DSQR((*i)->Area()-(*i)->TargetArea()); + old_length_energy += DSQR((*i)->Length()-(*i)->TargetLength()); + } + + Move(movement); + + double new_area_energy=0., new_length_energy=0.; + for (list::const_iterator i=neighbors.begin(); + i!=neighbors.end(); + i++) { + cellareas.push_back((*i)->CalcArea()); + new_area_energy += DSQR(cellareas.back()-(*i)->TargetArea()); + new_length_energy += DSQR((*i)->CalcLength()-(*i)->TargetLength()); + } + + double new_length=0; + for ( vector< pair< Node *, Node * > >::const_iterator e = length_edges.begin(); + e != length_edges.end(); + e++) { + new_length += DSQR(Node::target_length- + (*(e->first)-*(e->second)).Norm()); + } + + + dh += (new_area_energy - old_area_energy) + (new_length_energy - old_length_energy) * lambda_celllength + + par.lambda_length * (new_length - old_length); + + if (dh<0 || RANDOM()::const_iterator nb_it = neighbors.begin(); + for (vector::const_iterator ar_it = cellareas.begin(); + ar_it!=cellareas.end(); + ( ar_it++, nb_it++) ) { + ((Cell *)(*nb_it))->area = *ar_it; + (*nb_it)->SetIntegrals(); + } + + //cerr << endl; + + } else { + + Move ( -1*movement); + + } + + return dh; } -void Cell::Displace (void) { - Displace(par.mc_cell_stepsize*(RANDOM()-0.5),par.mc_cell_stepsize*(RANDOM()-0.5),0); +void Cell::Displace (void) +{ + Displace(par.mc_cell_stepsize*(RANDOM()-0.5),par.mc_cell_stepsize*(RANDOM()-0.5),0); } // Get energy level of whole cell (excluding length constraint?) -double Cell::Energy(void) const { - - double energy = 0.; - double length_contribution = 0.; - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - for (list::const_iterator n=(*i)->owners.begin(); - n!=(*i)->owners.end(); - n++) { - - if (n->getCell()==this) { - - length_contribution += - DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm())+ - DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); - - } - } - } - - // wall elasticity constraint - energy += par.lambda_length * length_contribution; - - // area constraint - energy += DSQR(CalcArea() - target_area); - - // cell length constraint - - - energy += lambda_celllength * DSQR(Length() - target_length); - - - return energy; +double Cell::Energy(void) const +{ + double energy = 0.; + double length_contribution = 0.; + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + for (list::const_iterator n=(*i)->owners.begin(); + n!=(*i)->owners.end(); + n++) { + + if (n->getCell()==this) { + + length_contribution += + DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm())+ + DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); + + } + } + } + + // wall elasticity constraint + energy += par.lambda_length * length_contribution; + + // area constraint + energy += DSQR(CalcArea() - target_area); + + // cell length constraint + energy += lambda_celllength * DSQR(Length() - target_length); + + return energy; } -bool Cell::SelfIntersect(void) { - - // The (obvious) O(N*N) algorithm - - // Compare each edge against each other edge - - // An O(N log(N)) algorithm by Shamos & Hoey (1976) supposedly exists; - // it was mentioned on comp.graphics.algorithms - - // But I haven't been able to lay my hand on the paper. - // Let's try whether we need it.... - - // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ +bool Cell::SelfIntersect(void) +{ + // The (obvious) O(N*N) algorithm + + // Compare each edge against each other edge + + // An O(N log(N)) algorithm by Shamos & Hoey (1976) supposedly exists; + // it was mentioned on comp.graphics.algorithms + + // But I haven't been able to lay my hand on the paper. + // Let's try whether we need it.... + + // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + list::const_iterator j=i; + ++j; + for (; + j!=nodes.end(); + j++) + { - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - list::const_iterator j=i; - ++j; - for (; - j!=nodes.end(); - j++) - { - - Vector v1 = *(*i); - list::const_iterator nb=i; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - Vector v2 = *(*nb); - Vector v3 = *(*j); - nb=j; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - Vector v4=*( *nb ); - - double denominator = - (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - - double ua = - ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = - ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; - - - if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; - return true; - } - } - } - - return false; + Vector v1 = *(*i); + list::const_iterator nb=i; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + Vector v2 = *(*nb); + Vector v3 = *(*j); + nb=j; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + Vector v4=*( *nb ); + + double denominator = + (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); + + double ua = + ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; + double ub = + ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; + + + if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { + //cerr << "ua = " << ua << ", ub = " << ub << endl; + return true; + } + } + } + + return false; } -bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) { - - // Check whether the polygon will self-intersect if moving_node_ind - // were displaced to new_pos - - // Compare the two new edges against each other edge - - // O(2*N) - - // method used for segment intersection: - // http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - - Vector neighbor_of_moving_node[2]; - - //cerr << "list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind);\n"; - list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind); - - list::const_iterator nb = moving_node_ind_pos; - //cerr << "Done\n"; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - - neighbor_of_moving_node[0]=*(*nb); - - nb=moving_node_ind_pos; - if (nb == nodes.begin()) { - nb = nodes.end(); - } - nb--; - - neighbor_of_moving_node[1]=*( *nb ); - - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - - for (int j=0;j<2;j++) { // loop over the two neighbors of moving node - list::const_iterator nb=i; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - if (*i == moving_node_ind || *nb == moving_node_ind) { - // do not compare to self - continue; - } - - Vector v3 = *(*i); - Vector v4 = *(*nb); - - double denominator = - (v4.y - v3.y)*(neighbor_of_moving_node[j].x - new_pos.x) - (v4.x - v3.x)*(neighbor_of_moving_node[j].y - new_pos.y); - - double ua = - ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x))/denominator; - double ub = - ((neighbor_of_moving_node[j].x - new_pos.x)*(new_pos.y-v3.y) - (neighbor_of_moving_node[j].y- new_pos.y)*(new_pos.x - v3.x))/denominator; - - if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; - return true; - } - } - } - - return false; +bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) +{ + + // Check whether the polygon will self-intersect if moving_node_ind + // were displaced to new_pos + + // Compare the two new edges against each other edge + + // O(2*N) + + // method used for segment intersection: + // http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ + + Vector neighbor_of_moving_node[2]; + + //cerr << "list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind);\n"; + list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind); + + list::const_iterator nb = moving_node_ind_pos; + //cerr << "Done\n"; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + + neighbor_of_moving_node[0]=*(*nb); + + nb=moving_node_ind_pos; + if (nb == nodes.begin()) { + nb = nodes.end(); + } + nb--; + + neighbor_of_moving_node[1]=*( *nb ); + + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + + for (int j=0;j<2;j++) { // loop over the two neighbors of moving node + list::const_iterator nb=i; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + if (*i == moving_node_ind || *nb == moving_node_ind) { + // do not compare to self + continue; + } + + Vector v3 = *(*i); + Vector v4 = *(*nb); + + double denominator = + (v4.y - v3.y)*(neighbor_of_moving_node[j].x - new_pos.x) - (v4.x - v3.x)*(neighbor_of_moving_node[j].y - new_pos.y); + + double ua = + ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x))/denominator; + double ub = + ((neighbor_of_moving_node[j].x - new_pos.x)*(new_pos.y-v3.y) - (neighbor_of_moving_node[j].y- new_pos.y)*(new_pos.x - v3.x))/denominator; + + if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { + //cerr << "ua = " << ua << ", ub = " << ub << endl; + return true; + } + } + } + return false; } /*! \brief Test if this cell intersects with the given line. - + */ -bool Cell::IntersectsWithLineP(const Vector v1, const Vector v2) { - - - // Compare the line against each edge - - // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - - - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) +bool Cell::IntersectsWithLineP(const Vector v1, const Vector v2) +{ + // Compare the line against each edge + // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ + + for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { - - Vector v3 = *(*i); - list::const_iterator nb=i; - nb++; - if (nb == nodes.end()) { - nb = nodes.begin(); - } - Vector v4 = *(*nb); - - double denominator = - (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - - double ua = - ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = - ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; - - if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { - return true; - } + Vector v3 = *(*i); + list::const_iterator nb=i; + nb++; + if (nb == nodes.end()) { + nb = nodes.begin(); + } + Vector v4 = *(*nb); + + double denominator = + (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); + + double ua = + ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; + double ub = + ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; + + if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { + return true; + } } - - return false; - - + return false; } /*! \brief Constructs Walls, but only one per cell boundary. - - Standard method constructs a Wall for each cell wall element, - making transport algorithms computationally more intensive than needed. - - We can remove this? Well, let's leave it in the code in case we need it for something else. E.g. for importing leaf architectures in different formats than our own... :-) - - */ -void Cell::ConstructWalls(void) { - + + Standard method constructs a Wall for each cell wall element, + making transport algorithms computationally more intensive than needed. + + We can remove this? Well, let's leave it in the code in case we need it for something else. E.g. for importing leaf architectures in different formats than our own... :-) + +*/ +void Cell::ConstructWalls(void) +{ + return; + if (dead) return; + + walls.clear(); + neighbors.clear(); + + // Get "corner points; i.e. nodes where more than 2 cells are connected + list corner_points; + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end();i++) { + + // look for nodes belonging to >2 cells + if ((*i)->owners.size()>2) { + + // push onto list + corner_points.push_back(*i); + } + } + + // Construct Walls between corner points + + // previous one in list + list::const_iterator nb = (--corner_points.end()); + + // loop over list, + for (list::const_iterator i=corner_points.begin(); + i!=corner_points.end(); ( i++, nb++) ) { + + if (nb==corner_points.end()) nb=corner_points.begin(); + // add owning cells to a list + list owning_cells; + Node &n(*(*i)); + + for (list::const_iterator j=n.owners.begin(); + j!=n.owners.end(); + j++) { + owning_cells.push_back(j->cell); + } + + Node &n2(*(*nb)); + for (list::const_iterator j=n2.owners.begin(); + j!=n2.owners.end(); + j++) { + owning_cells.push_back(j->cell); + } + + // sort cell owners + owning_cells.sort( mem_fun( &Cell::Cmp )); + + // find duplicates + vector duplicates; + list::const_iterator prevj = (--owning_cells.end()); + for (list::const_iterator j=owning_cells.begin(); + j!=owning_cells.end(); + ( j++, prevj++) ) { + + if (prevj==owning_cells.end()) prevj=owning_cells.begin(); + if (*j==*prevj) duplicates.push_back(*j); + + } + + + if (duplicates.size()==3) { // ignore cell boundary (this occurs only after the first division, I think) + vector::iterator dup_it = find_if(duplicates.begin(),duplicates.end(),mem_fun(&Cell::BoundaryPolP) ); + if (dup_it!=duplicates.end()) + duplicates.erase(dup_it); + else { return; - if (dead) return; - - walls.clear(); - neighbors.clear(); - - // Get "corner points; i.e. nodes where more than 2 cells are connected - list corner_points; - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end();i++) { - - // look for nodes belonging to >2 cells - if ((*i)->owners.size()>2) { - - // push onto list - corner_points.push_back(*i); - } - - } - - // Construct Walls between corner points - - // previous one in list - list::const_iterator nb = (--corner_points.end()); - - // loop over list, - for (list::const_iterator i=corner_points.begin(); - i!=corner_points.end(); ( i++, nb++) ) { - - if (nb==corner_points.end()) nb=corner_points.begin(); - // add owning cells to a list - list owning_cells; - Node &n(*(*i)); - - for (list::const_iterator j=n.owners.begin(); - j!=n.owners.end(); - j++) { - owning_cells.push_back(j->cell); - } - - Node &n2(*(*nb)); - for (list::const_iterator j=n2.owners.begin(); - j!=n2.owners.end(); - j++) { - owning_cells.push_back(j->cell); - } - - // sort cell owners - owning_cells.sort( mem_fun( &Cell::Cmp )); + } + } + + + // One Wall for each neighbor, so we should be able to correctly construct neighbor lists here. + if (duplicates[0]==this) { + AddWall( new Wall(*nb,*i,duplicates[0],duplicates[1]) ); + if (!duplicates[1]->BoundaryPolP()) { - // find duplicates - vector duplicates; - list::const_iterator prevj = (--owning_cells.end()); - for (list::const_iterator j=owning_cells.begin(); - j!=owning_cells.end(); - ( j++, prevj++) ) { - - if (prevj==owning_cells.end()) prevj=owning_cells.begin(); - if (*j==*prevj) duplicates.push_back(*j); - - } - - - if (duplicates.size()==3) { // ignore cell boundary (this occurs only after the first division, I think) - vector::iterator dup_it = find_if(duplicates.begin(),duplicates.end(),mem_fun(&Cell::BoundaryPolP) ); - if (dup_it!=duplicates.end()) - duplicates.erase(dup_it); - else { - return; - } - - } - - - // One Wall for each neighbor, so we should be able to correctly construct neighbor lists here. - if (duplicates[0]==this) { - AddWall( new Wall(*nb,*i,duplicates[0],duplicates[1]) ); - if (!duplicates[1]->BoundaryPolP()) { - - neighbors.push_back(duplicates[1]); - } - } else { - AddWall ( new Wall(*nb,*i,duplicates[1],duplicates[0]) ); - if (!duplicates[0]->BoundaryPolP()) { - neighbors.push_back(duplicates[0]); - - } - } - } - + neighbors.push_back(duplicates[1]); + } + } else { + AddWall ( new Wall(*nb,*i,duplicates[1],duplicates[0]) ); + if (!duplicates[0]->BoundaryPolP()) { + neighbors.push_back(duplicates[0]); + + } + } + } } -void BoundaryPolygon::Draw(QGraphicsScene *c, QString tooltip) { - - // Draw the BoundaryPolygon on a QCanvas object - - - CellItem* p = new CellItem(this, c); - - QPolygonF pa(nodes.size()); - int cc=0; - - for (list::const_iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - Node *i=*n; - - pa[cc++] = QPoint((int)((Offset().x+i->x)*Factor()), - (int)((Offset().y+i->y)*Factor()) ); - } - - - p->setPolygon(pa); - p->setPen(par.outlinewidth>=0?QPen( QColor(par.cell_outline_color),par.outlinewidth):QPen(Qt::NoPen)); - p->setBrush( Qt::NoBrush ); - p->setZValue(1); - - if (!tooltip.isEmpty()) - p->setToolTip(tooltip); - - p->show(); - +void BoundaryPolygon::Draw(QGraphicsScene *c, QString tooltip) +{ + + // Draw the BoundaryPolygon on a QCanvas object + + CellItem* p = new CellItem(this, c); + + QPolygonF pa(nodes.size()); + int cc=0; + + for (list::const_iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + Node *i=*n; + + pa[cc++] = QPoint((int)((Offset().x+i->x)*Factor()), + (int)((Offset().y+i->y)*Factor()) ); + } + + p->setPolygon(pa); + p->setPen(par.outlinewidth>=0?QPen( QColor(par.cell_outline_color),par.outlinewidth):QPen(Qt::NoPen)); + p->setBrush( Qt::NoBrush ); + p->setZValue(1); + + if (!tooltip.isEmpty()) + p->setToolTip(tooltip); + + p->show(); } -void Cell::Flux(double *flux, double *D) { - - - // loop over cell edges - - for (int c=0;c::iterator i=walls.begin(); - i!=walls.end(); - i++) { - - - // leaf cannot take up chemicals from environment ("no flux boundary") - if ((*i)->c2->BoundaryPolP()) continue; - - - // flux depends on edge length and concentration difference - for (int c=0;clength * ( D[c] ) * ( ((Cell *)(*i)->c2)->chem[c] - chem[c] ); - - #ifdef QDEBUG - if ((*i)->c1!=this) { - qDebug() << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl; - } - #endif - - flux[c] += phi; - } - } - +void Cell::Flux(double *flux, double *D) +{ + // loop over cell edges + + for (int c=0;c::iterator i=walls.begin(); + i!=walls.end(); + i++) { + + + // leaf cannot take up chemicals from environment ("no flux boundary") + if ((*i)->c2->BoundaryPolP()) continue; + + + // flux depends on edge length and concentration difference + for (int c=0;clength * ( D[c] ) * ( ((Cell *)(*i)->c2)->chem[c] - chem[c] ); + +#ifdef QDEBUG + if ((*i)->c1!=this) { + qDebug() << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl; + } +#endif + + flux[c] += phi; + } + } } @@ -1552,46 +1503,46 @@ void Cell::Flux(double *flux, double *D) #include "canvas.h" -void Cell::Draw(QGraphicsScene *c, QString tooltip) { - - // Draw the cell on a QCanvas object - - if (DeadP()) { - #ifdef QDEBUG - qDebug() << "Cell " << index << " not drawn, because dead." << endl; - #endif - return; - } - - CellItem* p = new CellItem(this, c); - - QPolygonF pa(nodes.size()); - int cc=0; - - for (list::const_iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - Node *i=*n; - - pa[cc++] = QPoint((int)((offset[0]+i->x)*factor), - (int)((offset[1]+i->y)*factor) ); - } - - - QColor cell_color; - - m->plugin->SetCellColor(this,&cell_color); - - p->setPolygon(pa); - p->setPen(par.outlinewidth>=0?QPen( QColor(par.cell_outline_color),par.outlinewidth):QPen(Qt::NoPen)); - p->setBrush( cell_color ); - p->setZValue(1); - - if (!tooltip.isEmpty()) - p->setToolTip(tooltip); - - p->show(); - +void Cell::Draw(QGraphicsScene *c, QString tooltip) +{ + + // Draw the cell on a QCanvas object + + if (DeadP()) { +#ifdef QDEBUG + qDebug() << "Cell " << index << " not drawn, because dead." << endl; +#endif + return; + } + + CellItem* p = new CellItem(this, c); + + QPolygonF pa(nodes.size()); + int cc=0; + + for (list::const_iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + Node *i=*n; + + pa[cc++] = QPoint((int)((offset[0]+i->x)*factor), + (int)((offset[1]+i->y)*factor) ); + } + + + QColor cell_color; + + m->plugin->SetCellColor(this,&cell_color); + + p->setPolygon(pa); + p->setPen(par.outlinewidth>=0?QPen( QColor(par.cell_outline_color),par.outlinewidth):QPen(Qt::NoPen)); + p->setBrush( cell_color ); + p->setZValue(1); + + if (!tooltip.isEmpty()) + p->setToolTip(tooltip); + + p->show(); } @@ -1599,234 +1550,227 @@ void Cell::DrawCenter(QGraphicsScene *c) // Maginfication derived similarly to that in nodeitem.cpp // Why not use Cell::Magnification()? const double mag = par.node_mag; - - // construct an ellipse + + // construct an ellipse QGraphicsEllipseItem *disk = new QGraphicsEllipseItem ( -1*mag, -1*mag, 2*mag, 2*mag, 0, c ); - disk->setBrush( QColor("forest green") ); - disk->setZValue(5); - disk->show(); - Vector centroid=Centroid(); - disk -> setPos((offset[0]+centroid.x)*factor,(offset[1]+centroid.y)*factor); + disk->setBrush( QColor("forest green") ); + disk->setZValue(5); + disk->show(); + Vector centroid=Centroid(); + disk -> setPos((offset[0]+centroid.x)*factor,(offset[1]+centroid.y)*factor); } void Cell::DrawNodes(QGraphicsScene *c) const { - - for (list::const_iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - Node *i=*n; - + + for (list::const_iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + Node *i=*n; + - NodeItem *item = new NodeItem ( &(*i), c ); - item->setColor(); - item->setZValue(5); - item->show(); - item ->setPos(((offset[0]+i->x)*factor), - ((offset[1]+i->y)*factor) ); - } - + NodeItem *item = new NodeItem ( &(*i), c ); + item->setColor(); + item->setZValue(5); + item->show(); + item ->setPos(((offset[0]+i->x)*factor), + ((offset[1]+i->y)*factor) ); + } } void Cell::DrawIndex(QGraphicsScene *c) const { - - DrawText( c, QString("%1").arg(index)); + + DrawText( c, QString("%1").arg(index)); } // Draw any text in the cell's center void Cell::DrawText(QGraphicsScene *c, const QString &text) const { - - Vector centroid = Centroid(); - QGraphicsSimpleTextItem *ctext = new QGraphicsSimpleTextItem ( text, 0, c ); - ctext->setPen( QPen(QColor(par.textcolor)) ); - ctext->setZValue(20); - ctext->setFont( QFont( "Helvetica", par.cellnumsize, QFont::Bold) ); - ctext->show(); - ctext ->setPos(((offset[0]+centroid.x)*factor), - ((offset[1]+centroid.y)*factor) ); - + + Vector centroid = Centroid(); + QGraphicsSimpleTextItem *ctext = new QGraphicsSimpleTextItem ( text, 0, c ); + ctext->setPen( QPen(QColor(par.textcolor)) ); + ctext->setZValue(20); + ctext->setFont( QFont( "Helvetica", par.cellnumsize, QFont::Bold) ); + ctext->show(); + ctext ->setPos(((offset[0]+centroid.x)*factor), + ((offset[1]+centroid.y)*factor) ); } void Cell::DrawAxis(QGraphicsScene *c) const { - - Vector long_axis; - double width; - Length(&long_axis, &width); - - //cerr << "Length is " << length << endl; - long_axis.Normalise(); - Vector short_axis=long_axis.Perp2D(); - + + Vector long_axis; + double width; + Length(&long_axis, &width); + + //cerr << "Length is " << length << endl; + long_axis.Normalise(); + Vector short_axis=long_axis.Perp2D(); + - Vector centroid = Centroid(); - Vector from = centroid - 0.5 * width * short_axis; - Vector to = centroid + 0.5 * width *short_axis; + Vector centroid = Centroid(); + Vector from = centroid - 0.5 * width * short_axis; + Vector to = centroid + 0.5 * width *short_axis; + - - QGraphicsLineItem *line = new QGraphicsLineItem(0, c); - line->setPen( QPen(QColor(par.arrowcolor),2) ); - line->setZValue(2); - - line->setLine( ( (offset[0]+from.x)*factor ), - ( (offset[1]+from.y)*factor ), - ( (offset[0]+to.x)*factor ), - ( (offset[1]+to.y)*factor ) ); - line->setZValue(10); - line->show(); - + QGraphicsLineItem *line = new QGraphicsLineItem(0, c); + line->setPen( QPen(QColor(par.arrowcolor),2) ); + line->setZValue(2); + + line->setLine( ( (offset[0]+from.x)*factor ), + ( (offset[1]+from.y)*factor ), + ( (offset[0]+to.x)*factor ), + ( (offset[1]+to.y)*factor ) ); + line->setZValue(10); + line->show(); } void Cell::DrawStrain(QGraphicsScene *c) const { c = NULL; // assignment merely to obviate compilation warning - MyWarning::warning("Sorry, Cell::DrawStrain temporarily not implemented."); + MyWarning::warning("Sorry, Cell::DrawStrain temporarily not implemented."); } -void Cell::DrawFluxes(QGraphicsScene *c, double arrowsize) { - - // get the mean flux through this cell - Vector vec_flux = ReduceCellAndWalls( PINdir ); - - vec_flux.Normalise(); - - vec_flux *= arrowsize; - - QGraphicsArrowItem *arrow = new QGraphicsArrowItem(0,c); - - Vector centroid = Centroid(); - Vector from = centroid - vec_flux/2.; - Vector to = centroid + vec_flux/2.; - - - arrow->setPen( QPen(QColor(par.arrowcolor),par.outlinewidth)); - arrow->setZValue(2); - - arrow->setLine( ( (offset[0]+from.x)*factor ), - ( (offset[1]+from.y)*factor ), - ( (offset[0]+to.x)*factor ), - ( (offset[1]+to.y)*factor ) ); - arrow->setZValue(10); - arrow->show(); - +void Cell::DrawFluxes(QGraphicsScene *c, double arrowsize) +{ + + // get the mean flux through this cell + Vector vec_flux = ReduceCellAndWalls( PINdir ); + + vec_flux.Normalise(); + + vec_flux *= arrowsize; + + QGraphicsArrowItem *arrow = new QGraphicsArrowItem(0,c); + + Vector centroid = Centroid(); + Vector from = centroid - vec_flux/2.; + Vector to = centroid + vec_flux/2.; + + + arrow->setPen( QPen(QColor(par.arrowcolor),par.outlinewidth)); + arrow->setZValue(2); + + arrow->setLine( ( (offset[0]+from.x)*factor ), + ( (offset[1]+from.y)*factor ), + ( (offset[0]+to.x)*factor ), + ( (offset[1]+to.y)*factor ) ); + arrow->setZValue(10); + arrow->show(); } void Cell::DrawWalls(QGraphicsScene *c) const { - - for_each(walls.begin(), walls.end(), bind2nd ( mem_fun ( &Wall::Draw ) , c ) ); - - // to see the cells connected the each wall (for debugging), uncomment the following - //for_each(walls.begin(), walls.end(), bind2nd ( mem_fun ( &Wall::ShowStructure ), c ) ); + + for_each(walls.begin(), walls.end(), bind2nd ( mem_fun ( &Wall::Draw ) , c ) ); + + // to see the cells connected the each wall (for debugging), uncomment the following + //for_each(walls.begin(), walls.end(), bind2nd ( mem_fun ( &Wall::ShowStructure ), c ) ); } void Cell::DrawValence(QGraphicsScene *c) const { - - DrawText(c, QString("%1").arg(walls.size()) ); - + + DrawText(c, QString("%1").arg(walls.size()) ); } -#endif +#endif // QTGRAPHICS ! /*! \brief Recalculate the lengths of the cell's Walls. - - Call this function after the Monte Carlo updates, and before doing the reaction-diffusion iterations. - - */ -void Cell::SetWallLengths(void) { - - for (list::iterator de=walls.begin(); - de!=walls.end(); - de++) { - - // Step 1: find the path of nodes leading along the Wall. - // A Wall often represents a curved cell wall: we want the total - // length _along_ the wall here... - - - // Locate first and second nodes of the edge in list of nodes - list::const_iterator first_node_edge = find(nodes.begin(), nodes.end(), (*de)->n1); - list::const_iterator second_node_edge_plus_1 = ++find(nodes.begin(), nodes.end(), (*de)->n2); - - double sum_length = 0.; - - // Now, walk to the second node of the edge in the list of nodes - for (list::const_iterator n=++first_node_edge; - n!=second_node_edge_plus_1; - ++n ) { - - if (n==nodes.end()) n=nodes.begin(); /* wrap around */ - - - list::const_iterator prev_n = n; - if (prev_n==nodes.begin()) prev_n=nodes.end(); - --prev_n; - - - // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h - sum_length += (*(*prev_n) - *(*n)).Norm(); - - //cerr << "Node " << *prev_n << " to " << *n << ", cumulative length = " << sum_length << endl; - } - - // We got the total length of the Wall now, store it: - (*de)->length = sum_length; - - //cerr << endl; - // goto next de - } + + Call this function after the Monte Carlo updates, and before doing the reaction-diffusion iterations. + +*/ +void Cell::SetWallLengths(void) +{ + + for (list::iterator de=walls.begin(); + de!=walls.end(); + de++) { + + // Step 1: find the path of nodes leading along the Wall. + // A Wall often represents a curved cell wall: we want the total + // length _along_ the wall here... + + + // Locate first and second nodes of the edge in list of nodes + list::const_iterator first_node_edge = find(nodes.begin(), nodes.end(), (*de)->n1); + list::const_iterator second_node_edge_plus_1 = ++find(nodes.begin(), nodes.end(), (*de)->n2); + + double sum_length = 0.; + + // Now, walk to the second node of the edge in the list of nodes + for (list::const_iterator n=++first_node_edge; + n!=second_node_edge_plus_1; + ++n ) { + + if (n==nodes.end()) n=nodes.begin(); /* wrap around */ + + + list::const_iterator prev_n = n; + if (prev_n==nodes.begin()) prev_n=nodes.end(); + --prev_n; + + + // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h + sum_length += (*(*prev_n) - *(*n)).Norm(); + + //cerr << "Node " << *prev_n << " to " << *n << ", cumulative length = " << sum_length << endl; + } + + // We got the total length of the Wall now, store it: + (*de)->length = sum_length; + + //cerr << endl; + // goto next de + } } //! Add Wall w to the list of Walls -void Cell::AddWall( Wall *w ) { - - // if necessary, we could try later inserting it at the correct position - #ifdef QDEBUG - if (w->c1 == w->c2 ){ - qDebug() << "Wall between identical cells: " << w->c1->Index()<< endl; - } - #endif +void Cell::AddWall( Wall *w ) +{ + + // if necessary, we could try later inserting it at the correct position +#ifdef QDEBUG + if (w->c1 == w->c2 ){ + qDebug() << "Wall between identical cells: " << w->c1->Index()<< endl; + } +#endif - // Add Wall to Cell's list - walls.push_back( w ); - - // Add wall to Mesh's list if it isn't there yet - - if (find ( - m->walls.begin(), m->walls.end(), - w ) - == m->walls.end() ) { - m->walls.push_back(w); - } - + // Add Wall to Cell's list + walls.push_back( w ); + + // Add wall to Mesh's list if it isn't there yet + + if (find ( + m->walls.begin(), m->walls.end(), + w ) + == m->walls.end() ) { + m->walls.push_back(w); + } } //! Remove Wall w from the list of Walls -list::iterator Cell::RemoveWall( Wall *w ) { - - // remove wall from Mesh's list - m->walls.erase( - find( - m->walls.begin(), m->walls.end(), - w ) - ); - - // remove wall from Cell's list - return - walls.erase ( - find( - walls.begin(), walls.end(), - w ) - ); - +list::iterator Cell::RemoveWall( Wall *w ) +{ + + // remove wall from Mesh's list + m->walls.erase( + find( + m->walls.begin(), m->walls.end(), + w ) + ); + + // remove wall from Cell's list + return walls.erase (find( walls.begin(), walls.end(), w )); } +void Cell::EmitValues(double t) +{ -void Cell::EmitValues(double t) { - - // cerr << "Attempting to emit " << t << ", " << chem[0] << ", " << chem[1] << endl; - emit ChemMonValue(t, chem); - + // cerr << "Attempting to emit " << t << ", " << chem[0] << ", " << chem[1] << endl; + emit ChemMonValue(t, chem); } + +/* finis */ diff --git a/src/cell.h b/src/cell.h --- a/src/cell.h +++ b/src/cell.h @@ -45,161 +45,153 @@ class Cell : public CellBase { - - Q_OBJECT - friend class Mesh; - friend class FigureEditor; + + Q_OBJECT + friend class Mesh; + friend class FigureEditor; + + public: + Cell(double x, double y, double z = 0.); + Cell(void); + Cell(const Cell &src); + Cell operator=(const Cell &src); + bool Cmp(Cell*) const; + bool Eq(Cell*) const; + + inline bool IndexEquals(int i) { return i == index; } + + static void SetMagnification(const double &magn) { + factor=magn; + } + static Vector Offset(void) { + Vector offs; + offs.x=offset[0]; + offs.y=offset[1]; + return offs; + } -public: - Cell(double x, double y, double z = 0.); - Cell(void); - Cell(const Cell &src); - Cell operator=(const Cell &src); - bool Cmp(Cell*) const; - bool Eq(Cell*) const; + static void Translate(const double &tx,const double &ty) { + offset[0]+=tx; + offset[1]+=ty; + } + + inline static double Factor(void) { + return factor; + } + static void setOffset(double ox, double oy) { + offset[0]=ox; + offset[1]=oy; + } + static double Magnification(void) { + return factor; + } + + static double Scale(const double scale) { + factor*=scale; + return factor; + } + + void DivideOverAxis(Vector axis); // divide cell over axis + + // divide over the line (if line and cell intersect) + bool DivideOverGivenLine(const Vector v1, const Vector v2, bool wall_fixed = false, NodeSet *node_set = 0); + + void Divide(void) { // Divide cell over short axis + + Vector long_axis; + Length(&long_axis); + DivideOverAxis(long_axis.Perp2D()); + } - inline bool IndexEquals(int i) { return i == index; } - - static void SetMagnification(const double &magn) { - factor=magn; - } - static Vector Offset(void) { - Vector offs; - offs.x=offset[0]; - offs.y=offset[1]; - return offs; - } - - static void Translate(const double &tx,const double &ty) { - offset[0]+=tx; - offset[1]+=ty; - } - - inline static double Factor(void) { - return factor; - } - static void setOffset(double ox, double oy) { - offset[0]=ox; - offset[1]=oy; - } - static double Magnification(void) { - return factor; - } - - static double Scale(const double scale) { - factor*=scale; - return factor; - } - - void DivideOverAxis(Vector axis); // divide cell over axis - bool DivideOverGivenLine(const Vector v1, const Vector v2, bool wall_fixed = false, NodeSet *node_set = 0); // divide over the line (if line and cell intersect) - - void Divide(void) { // Divide cell over short axis - - Vector long_axis; - Length(&long_axis); - DivideOverAxis(long_axis.Perp2D()); - - } - - //void CheckForGFDrivenDivision(void); - inline int NNodes(void) const { return nodes.size(); } - - void Move(Vector T); - void Move(double dx, double dy, double dz=0) { - Move( Vector (dx, dy, dz) ); - } - - double Displace(double dx, double dy, double dh); - void Displace(void); - double Energy(void) const; - bool SelfIntersect(void); - bool MoveSelfIntersectsP(Node *nid, Vector new_pos); - bool IntersectsWithLineP(const Vector v1, const Vector v2); + //void CheckForGFDrivenDivision(void); + inline int NNodes(void) const { return nodes.size(); } + + void Move(Vector T); + void Move(double dx, double dy, double dz=0) { + Move( Vector (dx, dy, dz) ); + } + + double Displace(double dx, double dy, double dh); + void Displace(void); + double Energy(void) const; + bool SelfIntersect(void); + bool MoveSelfIntersectsP(Node *nid, Vector new_pos); + bool IntersectsWithLineP(const Vector v1, const Vector v2); + + void XMLAdd(xmlNodePtr cells_node) const; + + void ConstructWalls(void); + void Flux(double *flux, double *D); + + void OnClick(QMouseEvent *e); + inline Mesh& getMesh(void) const { return *m; } + double MeanArea(void); + + void Apoptose(void); // Cell kills itself + list::iterator RemoveWall( Wall *w ); + void AddWall( Wall *w ); + + void Draw(QGraphicsScene *c, QString tooltip = QString::Null()); - void XMLAdd(xmlNodePtr cells_node) const; - - void ConstructWalls(void); - void Flux(double *flux, double *D); - - /*! \brief Method called if a cell is clicked. - - Define this in the end-user code (e.g. meinhardt.cpp). - - */ - void OnClick(QMouseEvent *e); - inline Mesh& getMesh(void) const { return *m; } - double MeanArea(void); - - void Apoptose(void); // Cell kills itself - list::iterator RemoveWall( Wall *w ); - void AddWall( Wall *w ); + // Draw a text in the cell's center + void DrawText(QGraphicsScene *c, const QString &text) const; + void DrawIndex(QGraphicsScene *c) const; + void DrawCenter(QGraphicsScene *c) const; + void DrawNodes(QGraphicsScene *c) const; + + void DrawAxis(QGraphicsScene *c) const; + void DrawStrain(QGraphicsScene *c) const; + void DrawFluxes(QGraphicsScene *c, double arrowsize = 1.); + void DrawWalls(QGraphicsScene *c) const; + void DrawValence(QGraphicsScene *c) const; + void EmitValues(double t); - void Draw(QGraphicsScene *c, QString tooltip = QString::Null()); - - // Draw a text in the cell's center - void DrawText(QGraphicsScene *c, const QString &text) const; - void DrawIndex(QGraphicsScene *c) const; - void DrawCenter(QGraphicsScene *c) const; - void DrawNodes(QGraphicsScene *c) const; - - void DrawAxis(QGraphicsScene *c) const; - void DrawStrain(QGraphicsScene *c) const; - void DrawFluxes(QGraphicsScene *c, double arrowsize = 1.); - void DrawWalls(QGraphicsScene *c) const; - void DrawValence(QGraphicsScene *c) const; - void EmitValues(double t); - -signals: - void ChemMonValue(double t, double *x); - - -protected: - void XMLAddCore(xmlNodePtr xmlcell) const; - int XMLRead(xmlNode *cur); - void DivideWalls(ItList new_node_locations, const Vector from, const Vector to, bool wall_fixed = false, NodeSet *node_set = 0); + signals: + void ChemMonValue(double t, double *x); + + protected: + void XMLAddCore(xmlNodePtr xmlcell) const; + int XMLRead(xmlNode *cur); + void DivideWalls(ItList new_node_locations, const Vector from, const Vector to, bool wall_fixed = false, NodeSet *node_set = 0); -private: + private: - static QPen *cell_outline_pen; - static double offset[3]; - static double factor; - Mesh *m; - void ConstructConnections(void); - void SetWallLengths(void); - + static QPen *cell_outline_pen; + static double offset[3]; + static double factor; + Mesh *m; + void ConstructConnections(void); + void SetWallLengths(void); }; // Boundarypolygon is a special cell; will not increase ncells // and will not be part of Mesh::cells class BoundaryPolygon : public Cell { - -public: - BoundaryPolygon(void) : Cell() { - NCells()--; - index=-1; - } - - BoundaryPolygon(double x,double y,double z=0) : Cell (x,y,z) { - NCells()--; - index=-1; - } - - BoundaryPolygon &operator=(Cell &src) { - Cell::operator=(src); - index=-1; - return *this; - } - virtual void Draw(QGraphicsScene *c, QString tooltip = QString::Null()); - - virtual void XMLAdd(xmlNodePtr parent_node) const; - - virtual bool BoundaryPolP(void) const { return true; } + + public: + BoundaryPolygon(void) : Cell() { + NCells()--; + index=-1; + } + BoundaryPolygon(double x,double y,double z=0) : Cell (x,y,z) { + NCells()--; + index=-1; + } + BoundaryPolygon &operator=(Cell &src) { + Cell::operator=(src); + index=-1; + return *this; + } + virtual void Draw(QGraphicsScene *c, QString tooltip = QString::Null()); + + virtual void XMLAdd(xmlNodePtr parent_node) const; + + virtual bool BoundaryPolP(void) const { return true; } }; - +#endif -#endif +/* finis */ diff --git a/src/cellbase.cpp b/src/cellbase.cpp --- a/src/cellbase.cpp +++ b/src/cellbase.cpp @@ -61,598 +61,590 @@ CellsStaticDatamembers *CellBase::static #endif CellBase::CellBase(QObject *parent) : -QObject(parent), -Vector() + QObject(parent), + Vector() { - chem=new double[NChem()]; - for (int i=0;i=NChem()) { - stringstream error; - error << "SetChemical: value c = " << c << " is out of range\n"; - throw error.str().c_str(); - } - chem[c]=conc; +void CellBase::SetChemical(int c, double conc) +{ + if (c>=NChem()) { + stringstream error; + error << "SetChemical: value c = " << c << " is out of range\n"; + throw error.str().c_str(); + } + chem[c]=conc; } -void CellBase::SetTransporters(int ch, double conc) { - if (ch>=NChem()) { - stringstream error; - error << "SetChemical: value ch = " << ch << " is out of range\n"; - throw error.str().c_str(); - } - for (list::iterator w=walls.begin(); - w!=walls.end(); - w++) { - (*w)->setTransporter(this, ch, conc); - } +void CellBase::SetTransporters(int ch, double conc) +{ + if (ch>=NChem()) { + stringstream error; + error << "SetChemical: value ch = " << ch << " is out of range\n"; + throw error.str().c_str(); + } + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + (*w)->setTransporter(this, ch, conc); + } } -ostream &CellBase::print(ostream &os) const { - - - os << "[ index = " << index << " {" << x << ", " << y << ", " << z << "}: {"; - - for (int i=0;i::const_iterator i = nodes.begin(); i!=nodes.end(); i++) { - os << (*i)->Index() << "( " << *i << ") "; - } - os << " } "; - - for (list::const_iterator i = walls.begin(); i!=walls.end(); i++) { - (*i)->print(os); - os << ", "; - } - os << endl; - - os << " [ area = " << area << " ]"; - os << " [ walls = "; - - for (list::const_iterator i= walls.begin(); - i!=walls.end(); - i++) { - os << (*i)->n1->Index() << " -> " << (*i)->n2->Index() << ", " << (*i)->c1->Index() << " | " << (*i)->c2->Index() << ", "; - } - os << " ] "; - os << "div_counter = " << div_counter << endl; - os << "cell_type = " << cell_type << endl; - os << endl; - return os; - +ostream &CellBase::print(ostream &os) const +{ + + + os << "[ index = " << index << " {" << x << ", " << y << ", " << z << "}: {"; + + for (int i=0;i::const_iterator i = nodes.begin(); i!=nodes.end(); i++) { + os << (*i)->Index() << "( " << *i << ") "; + } + os << " } "; + + for (list::const_iterator i = walls.begin(); i!=walls.end(); i++) { + (*i)->print(os); + os << ", "; + } + os << endl; + + os << " [ area = " << area << " ]"; + os << " [ walls = "; + + for (list::const_iterator i= walls.begin(); + i!=walls.end(); + i++) { + os << (*i)->n1->Index() << " -> " << (*i)->n2->Index() << ", " << (*i)->c1->Index() << " | " << (*i)->c2->Index() << ", "; + } + os << " ] "; + os << "div_counter = " << div_counter << endl; + os << "cell_type = " << cell_type << endl; + os << endl; + return os; } -ostream &operator<<(ostream &os, const CellBase &c) { - c.print(os); - return os; +ostream &operator<<(ostream &os, const CellBase &c) +{ + c.print(os); + return os; } -double CellBase::CalcArea(void) const { - - double loc_area=0.; - - for (list::const_iterator i=nodes.begin(); - i!=(nodes.end()); - i++) { - - list::const_iterator i_plus_1=i; i_plus_1++; - if (i_plus_1==nodes.end()) - i_plus_1=nodes.begin(); - - loc_area+= (*i)->x * (*i_plus_1)->y; - loc_area-= (*i_plus_1)->x * (*i)->y; - } +double CellBase::CalcArea(void) const +{ + + double loc_area=0.; + + for (list::const_iterator i=nodes.begin(); + i!=(nodes.end()); + i++) { - // http://technology.niagarac.on.ca/courses/ctec1335/docs/arrays2.pdf - //return loc_area/2.0; - return fabs(loc_area)/2.0; + list::const_iterator i_plus_1=i; i_plus_1++; + if (i_plus_1==nodes.end()) + i_plus_1=nodes.begin(); + + loc_area+= (*i)->x * (*i_plus_1)->y; + loc_area-= (*i_plus_1)->x * (*i)->y; + } + + // http://technology.niagarac.on.ca/courses/ctec1335/docs/arrays2.pdf + return fabs(loc_area)/2.0; } -Vector CellBase::Centroid(void) const { - - double area=0.; - double integral_x_dxdy=0.,integral_y_dxdy=0.; - - for (list::const_iterator i=nodes.begin(); - i!=(nodes.end()); - i++) { - - list::const_iterator i_plus_1=i; i_plus_1++; - if (i_plus_1==nodes.end()) - i_plus_1=nodes.begin(); - - area+= (*i)->x * (*i_plus_1)->y; - area-= (*i_plus_1)->x * (*i)->y; - - integral_x_dxdy+= - ((*i_plus_1)->x+(*i)->x)* - ((*i)->x*(*i_plus_1)->y- - (*i_plus_1)->x*(*i)->y); - integral_y_dxdy+= - ((*i_plus_1)->y+(*i)->y)* - ((*i)->x*(*i_plus_1)->y- - (*i_plus_1)->x*(*i)->y); - } - - //area/=2.0; - area = fabs(area)/2.0; - - integral_x_dxdy/=6.; - integral_y_dxdy/=6.; - - Vector centroid(integral_x_dxdy,integral_y_dxdy,0); - centroid/=area; - return centroid; +Vector CellBase::Centroid(void) const +{ + + double area=0.; + double integral_x_dxdy=0.,integral_y_dxdy=0.; + + for (list::const_iterator i=nodes.begin(); + i!=(nodes.end()); + i++) { + + list::const_iterator i_plus_1=i; i_plus_1++; + if (i_plus_1==nodes.end()) + i_plus_1=nodes.begin(); + + area+= (*i)->x * (*i_plus_1)->y; + area-= (*i_plus_1)->x * (*i)->y; + + integral_x_dxdy+= + ((*i_plus_1)->x+(*i)->x)* + ((*i)->x*(*i_plus_1)->y- + (*i_plus_1)->x*(*i)->y); + integral_y_dxdy+= + ((*i_plus_1)->y+(*i)->y)* + ((*i)->x*(*i_plus_1)->y- + (*i_plus_1)->x*(*i)->y); + } + + area = fabs(area)/2.0; + + integral_x_dxdy/=6.; + integral_y_dxdy/=6.; + + Vector centroid(integral_x_dxdy,integral_y_dxdy,0); + centroid/=area; + return centroid; } -void CellBase::SetIntegrals(void) const { - - // Set the initial values for the integrals over x^2, - // xy, yy, x, and y - - // these values will be updated after each move of the CellBase wall - - intgrl_xx=0.; intgrl_xy=0.; intgrl_yy=0.; - intgrl_x=0.; intgrl_y=0.; - area=0.; - list::const_iterator nb; - list::const_iterator i=nodes.begin(); - - for (; - i!=(nodes.end()); - i++) { - - nb = i; nb++; if (nb==nodes.end()) nb=nodes.begin(); - - area+=(*i)->x*(*nb)->y; - area-=(*nb)->x*(*i)->y; - intgrl_xx+= - ((*i)->x*(*i)->x+ - (*nb)->x*(*i)->x+ - (*nb)->x*(*nb)->x ) * - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - intgrl_xy+= - ((*nb)->x*(*i)->y- - (*i)->x*(*nb)->y)* - ((*i)->x*(2*(*i)->y+(*nb)->y)+ - (*nb)->x*((*i)->y+2*(*nb)->y)); - intgrl_yy+= - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y)* - ((*i)->y*(*i)->y+ - (*nb)->y*(*i)->y+ - (*nb)->y*(*nb)->y ); - intgrl_x+= - ((*nb)->x+(*i)->x)* - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - intgrl_y+= - ((*nb)->y+(*i)->y)* - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - } - +void CellBase::SetIntegrals(void) const +{ + + // Set the initial values for the integrals over x^2, + // xy, yy, x, and y + + // these values will be updated after each move of the CellBase wall + + intgrl_xx=0.; intgrl_xy=0.; intgrl_yy=0.; + intgrl_x=0.; intgrl_y=0.; + area=0.; + list::const_iterator nb; + list::const_iterator i=nodes.begin(); + + for (; + i!=(nodes.end()); + i++) { + + nb = i; nb++; if (nb==nodes.end()) nb=nodes.begin(); - area = fabs(area)/2.0; - + area+=(*i)->x*(*nb)->y; + area-=(*nb)->x*(*i)->y; + intgrl_xx+= + ((*i)->x*(*i)->x+ + (*nb)->x*(*i)->x+ + (*nb)->x*(*nb)->x ) * + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + intgrl_xy+= + ((*nb)->x*(*i)->y- + (*i)->x*(*nb)->y)* + ((*i)->x*(2*(*i)->y+(*nb)->y)+ + (*nb)->x*((*i)->y+2*(*nb)->y)); + intgrl_yy+= + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y)* + ((*i)->y*(*i)->y+ + (*nb)->y*(*i)->y+ + (*nb)->y*(*nb)->y ); + intgrl_x+= + ((*nb)->x+(*i)->x)* + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + intgrl_y+= + ((*nb)->y+(*i)->y)* + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + } + area = fabs(area)/2.0; } -double CellBase::Length(Vector *long_axis, double *width) const { - - // Calculate length and axes of CellBase - - // Calculate inertia tensor - // see file inertiatensor.nb for explanation of this method - if (!lambda_celllength) { - - // Without length constraint we do not keep track of the cells' - // moments of inertia. So we must calculate them here. - SetIntegrals(); - } - - double intrx=intgrl_x/6.; - double intry=intgrl_y/6.; - double ixx=(intgrl_xx/12.)-(intrx*intrx)/area; - double ixy=(intgrl_xy/24.)+(intrx*intry)/area; - double iyy=(intgrl_yy/12.)-(intry*intry)/area; - - double rhs1=(ixx+iyy)/2., rhs2=sqrt( (ixx-iyy)*(ixx-iyy)+4*ixy*ixy )/2.; - - double lambda_b=rhs1+rhs2; - - // see: http://scienceworld.wolfram.com/physics/MomentofInertiaEllipse.html - // cerr << "n = " << n << "\n"; - - if (long_axis) { - *long_axis = Vector(-ixy, lambda_b - ixx, 0); - // cerr << "ixx = " << ixx << ", ixy = " << ixy << ", iyy = " << iyy << ", area = " << area << endl; - } - - if (width) { - *width = 4*sqrt((rhs1-rhs2)/area); - } - - return 4*sqrt(lambda_b/area); - - - +double CellBase::Length(Vector *long_axis, double *width) const +{ + + // Calculate length and axes of CellBase + + // Calculate inertia tensor + // see file inertiatensor.nb for explanation of this method + if (!lambda_celllength) { + + // Without length constraint we do not keep track of the cells' + // moments of inertia. So we must calculate them here. + SetIntegrals(); + } + + double intrx=intgrl_x/6.; + double intry=intgrl_y/6.; + double ixx=(intgrl_xx/12.)-(intrx*intrx)/area; + double ixy=(intgrl_xy/24.)+(intrx*intry)/area; + double iyy=(intgrl_yy/12.)-(intry*intry)/area; + + double rhs1=(ixx+iyy)/2., rhs2=sqrt( (ixx-iyy)*(ixx-iyy)+4*ixy*ixy )/2.; + + double lambda_b=rhs1+rhs2; + + // see: http://scienceworld.wolfram.com/physics/MomentofInertiaEllipse.html + // cerr << "n = " << n << "\n"; + + if (long_axis) { + *long_axis = Vector(-ixy, lambda_b - ixx, 0); + // cerr << "ixx = " << ixx << ", ixy = " << ixy << ", iyy = " << iyy << ", area = " << area << endl; + } + + if (width) { + *width = 4*sqrt((rhs1-rhs2)/area); + } + + return 4*sqrt(lambda_b/area); } -double CellBase::CalcLength(Vector *long_axis, double *width) const { - - // Calculate length and axes of CellBase, without touching cells raw moments - - // Calculate inertia tensor - // see file inertiatensor.nb for explanation of this method - - double my_intgrl_xx=0., my_intgrl_xy=0., my_intgrl_yy=0.; - double my_intgrl_x=0., my_intgrl_y=0., my_area=0.; - my_area=0.; - list::const_iterator nb; - list::const_iterator i=nodes.begin(); - - for (; - i!=(nodes.end()); - i++) { - - nb = i; nb++; if (nb==nodes.end()) nb=nodes.begin(); - - my_area+=(*i)->x*(*nb)->y; - my_area-=(*nb)->x*(*i)->y; - my_intgrl_xx+= - ((*i)->x*(*i)->x+ - (*nb)->x*(*i)->x+ - (*nb)->x*(*nb)->x ) * - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - my_intgrl_xy+= - ((*nb)->x*(*i)->y- - (*i)->x*(*nb)->y)* - ((*i)->x*(2*(*i)->y+(*nb)->y)+ - (*nb)->x*((*i)->y+2*(*nb)->y)); - my_intgrl_yy+= - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y)* - ((*i)->y*(*i)->y+ - (*nb)->y*(*i)->y+ - (*nb)->y*(*nb)->y ); - my_intgrl_x+= - ((*nb)->x+(*i)->x)* - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - my_intgrl_y+= - ((*nb)->y+(*i)->y)* - ((*i)->x*(*nb)->y- - (*nb)->x*(*i)->y); - } - - - //my_area/=2.0; - my_area = fabs(my_area)/2.0; - - - double intrx=my_intgrl_x/6.; - double intry=my_intgrl_y/6.; - double ixx=(my_intgrl_xx/12.)-(intrx*intrx)/my_area; - double ixy=(my_intgrl_xy/24.)+(intrx*intry)/my_area; - double iyy=(my_intgrl_yy/12.)-(intry*intry)/my_area; - - double rhs1=(ixx+iyy)/2., rhs2=sqrt( (ixx-iyy)*(ixx-iyy)+4*ixy*ixy )/2.; - - double lambda_b=rhs1+rhs2; - - // see: http://scienceworld.wolfram.com/physics/MomentofInertiaEllipse.html - // cerr << "n = " << n << "\n"; - - if (long_axis) { - *long_axis = Vector(-ixy, lambda_b - ixx, 0); - // cerr << "ixx = " << ixx << ", ixy = " << ixy << ", iyy = " << iyy << ", my_area = " << my_area << endl; - } - - if (width) { - *width = 4*sqrt((rhs1-rhs2)/my_area); - } - - return 4*sqrt(lambda_b/my_area); - - - +double CellBase::CalcLength(Vector *long_axis, double *width) const +{ + + // Calculate length and axes of CellBase, without touching cells raw moments + + // Calculate inertia tensor + // see file inertiatensor.nb for explanation of this method + + double my_intgrl_xx=0., my_intgrl_xy=0., my_intgrl_yy=0.; + double my_intgrl_x=0., my_intgrl_y=0., my_area=0.; + my_area=0.; + list::const_iterator nb; + list::const_iterator i=nodes.begin(); + + for (; + i!=(nodes.end()); + i++) { + + nb = i; nb++; if (nb==nodes.end()) nb=nodes.begin(); + + my_area+=(*i)->x*(*nb)->y; + my_area-=(*nb)->x*(*i)->y; + my_intgrl_xx+= + ((*i)->x*(*i)->x+ + (*nb)->x*(*i)->x+ + (*nb)->x*(*nb)->x ) * + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + my_intgrl_xy+= + ((*nb)->x*(*i)->y- + (*i)->x*(*nb)->y)* + ((*i)->x*(2*(*i)->y+(*nb)->y)+ + (*nb)->x*((*i)->y+2*(*nb)->y)); + my_intgrl_yy+= + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y)* + ((*i)->y*(*i)->y+ + (*nb)->y*(*i)->y+ + (*nb)->y*(*nb)->y ); + my_intgrl_x+= + ((*nb)->x+(*i)->x)* + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + my_intgrl_y+= + ((*nb)->y+(*i)->y)* + ((*i)->x*(*nb)->y- + (*nb)->x*(*i)->y); + } + + + //my_area/=2.0; + my_area = fabs(my_area)/2.0; + + + double intrx=my_intgrl_x/6.; + double intry=my_intgrl_y/6.; + double ixx=(my_intgrl_xx/12.)-(intrx*intrx)/my_area; + double ixy=(my_intgrl_xy/24.)+(intrx*intry)/my_area; + double iyy=(my_intgrl_yy/12.)-(intry*intry)/my_area; + + double rhs1=(ixx+iyy)/2., rhs2=sqrt( (ixx-iyy)*(ixx-iyy)+4*ixy*ixy )/2.; + + double lambda_b=rhs1+rhs2; + + // see: http://scienceworld.wolfram.com/physics/MomentofInertiaEllipse.html + // cerr << "n = " << n << "\n"; + + if (long_axis) { + *long_axis = Vector(-ixy, lambda_b - ixx, 0); + // cerr << "ixx = " << ixx << ", ixy = " << ixy << ", iyy = " << iyy << ", my_area = " << my_area << endl; + } + + if (width) { + *width = 4*sqrt((rhs1-rhs2)/my_area); + } + + return 4*sqrt(lambda_b/my_area); } +void CellBase::ConstructNeighborList(void) +{ -void CellBase::ConstructNeighborList(void) { - - neighbors.clear(); - for (//list::const_reverse_iterator wit=walls.rbegin(); - list::const_iterator wit=walls.begin(); - // somehow the reverse_iterator returns by walls needs to be casted to const to let this work. - // it seems to me it is a bug in the STL implementation... + neighbors.clear(); + for (//list::const_reverse_iterator wit=walls.rbegin(); + list::const_iterator wit=walls.begin(); + // somehow the reverse_iterator returns by walls needs to be casted to const to let this work. + // it seems to me it is a bug in the STL implementation... + + wit!=walls.end(); + wit++) { + + if ((*wit)->C1() != this) { + neighbors.push_back((*wit)->C1()); + } else { + neighbors.push_back((*wit)->C2()); + } + + } - wit!=walls.end(); - wit++) { - - if ((*wit)->C1() != this) { - neighbors.push_back((*wit)->C1()); - } else { - neighbors.push_back((*wit)->C2()); - } - - } - - - // remove all boundary_polygons from the list - list ::iterator e=neighbors.begin(); - at_boundary=false; - - do { - // Code crashes here after cutting off part of the leaf. I can't find the problem. - // Leaving the "Illegal" walls in the simulation helps. (c1=-1 && c2=-1) - // Work-around: define leaf primordium. Save to XML. Restart. Read XML file. - // Sorry about this; I hope to solve this annoying issue later. RM :-). - // All cells in neighbors seem to be okay (I might be messing some part of the memory elsewhere - // during the cutting operation?). - e = find_if(neighbors.begin(),neighbors.end(),mem_fun(&CellBase::BoundaryPolP)); - if (e!=neighbors.end()) { - e=neighbors.erase(e); - at_boundary=true; - } else { - break; - } + + // remove all boundary_polygons from the list + list ::iterator e=neighbors.begin(); + at_boundary=false; + + do { + // Code crashes here after cutting off part of the leaf. I can't find the problem. + // Leaving the "Illegal" walls in the simulation helps. (c1=-1 && c2=-1) + // Work-around: define leaf primordium. Save to XML. Restart. Read XML file. + // Sorry about this; I hope to solve this annoying issue later. RM :-). + // All cells in neighbors seem to be okay (I might be messing some part of the memory elsewhere + // during the cutting operation?). + e = find_if(neighbors.begin(),neighbors.end(),mem_fun(&CellBase::BoundaryPolP)); + if (e!=neighbors.end()) { + e=neighbors.erase(e); + at_boundary=true; + } else { + break; + } } while(1); - } - - // Save the cell to a stream so we can reconstruct its state later - void CellBase::Dump(ostream &os) const { - - - os << index << " " << nodes.size() << endl; - - Vector::Dump(os); - os << endl; - - for (list::const_iterator i=nodes.begin();i!=nodes.end();i++) { - os << *i << " "; - } - os << endl; - - - os << index << " " << neighbors.size() << endl; - for (list::const_iterator i=neighbors.begin();i!=neighbors.end();i++) { - os << *i << " "; - } - os << endl; - - os << walls.size() << endl; - /*for (list::const_iterator i=walls.begin();i!=walls.end(); i++) { - (*i)->Dump(os); - }*/ - - os << endl; - - os << NChem() << " "; - for (int i=0;i::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - (*i)->Unfix(); - } - - } - - void CellBase::FixNodes(void) { - - for (list::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - (*i)->Fix(); - } - - } - - // returns true if cell is at border - bool CellBase::AtBoundaryP(void) const { - - return at_boundary; - } - + +// Save the cell to a stream so we can reconstruct its state later +void CellBase::Dump(ostream &os) const +{ + + + os << index << " " << nodes.size() << endl; + + Vector::Dump(os); + os << endl; + + for (list::const_iterator i=nodes.begin();i!=nodes.end();i++) { + os << *i << " "; + } + os << endl; + os << index << " " << neighbors.size() << endl; + for (list::const_iterator i=neighbors.begin();i!=neighbors.end();i++) { + os << *i << " "; + } + os << endl << walls.size() << endl << endl; + os << NChem() << " "; + for (int i=0;i::const_iterator i = nodes.begin(); i!=nodes.end(); i++) { - info_string += QString("%1 ").arg((*i)->Index()); - } - info_string += " } "; - return info_string; +void CellBase::UnfixNodes(void) +{ + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + (*i)->Unfix(); + } + } + +void CellBase::FixNodes(void) +{ + + for (list::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + (*i)->Fix(); + } + +} + +// returns true if cell is at border +bool CellBase::AtBoundaryP(void) const +{ + return at_boundary; +} + + +QString CellBase::printednodelist(void) +{ + QString info_string = "Nodelist = { "; + for (list::const_iterator i = nodes.begin(); i!=nodes.end(); i++) { + info_string += QString("%1 ").arg((*i)->Index()); + } + info_string += " } "; + return info_string; +} + +/* finis*/ diff --git a/src/cellbase.h b/src/cellbase.h --- a/src/cellbase.h +++ b/src/cellbase.h @@ -47,11 +47,10 @@ class CellBase; class NodeSet; struct ParentInfo { - - Vector polarization; - double PINmembrane; - double PINendosome; - + + Vector polarization; + double PINmembrane; + double PINendosome; }; // We need a little trick here, to make sure the plugin and the main application will see the same static datamembers @@ -59,428 +58,408 @@ struct ParentInfo { // My solution is as follow. I collect all original statics in a class. The main application instantiates it and // has a static pointer to it. After loading the plugin I set a static pointer to the same class class CellsStaticDatamembers { - -public: - CellsStaticDatamembers(void) { - ncells = 0; - nchem = 0; - base_area = 0.; - #ifdef QDEBUG - qDebug() << "Constructor of CellsStaticDatamembers" << endl; - #endif - } - ~CellsStaticDatamembers() { - #ifdef QDEBUG - qDebug() << "Oops! Desctructor of CellsStaticDatamembers called" << endl; - #endif - } - int ncells; - int nchem; - double base_area; - + public: + CellsStaticDatamembers(void) { + ncells = 0; + nchem = 0; + base_area = 0.; +#ifdef QDEBUG + qDebug() << "Constructor of CellsStaticDatamembers" << endl; +#endif + } + ~CellsStaticDatamembers() { +#ifdef QDEBUG + qDebug() << "Oops! Desctructor of CellsStaticDatamembers called" << endl; +#endif + } + int ncells; + int nchem; + double base_area; }; class CellBase : public QObject, public Vector { - Q_OBJECT + Q_OBJECT + + friend class Mesh; + friend class CellInfo; + friend class Node; + friend class WallBase; + friend class SimPluginInterface; + + public: + CellBase(QObject *parent=0); + CellBase(double x,double y,double z=0); // constructor + + virtual ~CellBase() { + delete[] chem; + delete[] new_chem; + if (division_axis) delete division_axis; + //cerr << "CellBase " << index << " is dying. " << endl; + } + + CellBase(const CellBase &src); // copy constructor + virtual bool BoundaryPolP(void) const { return false; } - friend class Mesh; - friend class CellInfo; - friend class Node; - friend class WallBase; - friend class SimPluginInterface; - - public: - CellBase(QObject *parent=0); - CellBase(double x,double y,double z=0); // constructor - - virtual ~CellBase() { - delete[] chem; - delete[] new_chem; - if (division_axis) delete division_axis; - //cerr << "CellBase " << index << " is dying. " << endl; + CellBase operator=(const CellBase &src); // assignment operator + CellBase operator=(const Vector &src); + + void SetChemical(int chem, double conc); + inline void SetNewChem(int chem, double conc) + { + new_chem[chem] = conc; + } + + void SetSource(int chem, double conc) + { + source=true; + source_chem = chem; + source_conc = conc; + } + + // set chem 1 to conc in all membranes of this cell + void SetTransporters(int chem, double conc); + void UnfixNodes(void); + void FixNodes(void); + void UnsetSource(void) { + source = false; } - - CellBase(const CellBase &src); // copy constructor - virtual bool BoundaryPolP(void) const { return false; } - - - CellBase operator=(const CellBase &src); // assignment operator - CellBase operator=(const Vector &src); - - void SetChemical(int chem, double conc); - inline void SetNewChem(int chem, double conc) { - new_chem[chem] = conc; - } - void SetSource(int chem, double conc) { - source=true; - source_chem = chem; - source_conc = conc; - } - // set chem 1 to conc in all membranes of this cell - void SetTransporters(int chem, double conc); - void UnfixNodes(void); - void FixNodes(void); - void UnsetSource(void) { - source = false; - } - - inline bool Source(void) { return source; } - enum boundary_type {None, Noflux, SourceSink, SAM}; - static const char * boundary_type_names[4]; + + inline bool Source(void) { return source; } + enum boundary_type {None, Noflux, SourceSink, SAM}; + static const char * boundary_type_names[4]; + + inline const char *BoundaryStr(void) { return boundary_type_names[boundary]; } - inline const char *BoundaryStr(void) { return boundary_type_names[boundary]; } - - ostream &print(ostream &os) const; + ostream &print(ostream &os) const; + + inline double Chemical(int c) const { // returns the value of chemical c +#ifdef _undefined_ + qDebug() << endl << "Entering cellbase::chemical(" << c << "), and nchem is: " << NChem() << "." << endl; +#endif - inline double Chemical(int c) const { // returns the value of chemical c - #ifdef _undefined_ - qDebug() << endl << "Entering cellbase::chemical(" << c << "), and nchem is: " << NChem() << "." << endl; - #endif - - int nchem = NChem(); + int nchem = NChem(); - #ifdef _undefined_ - if ((c<0) || (c>=nchem)) - MyWarning::warning("CellBase::Chemical says: index c is: %d, but nchem is: %d. Merely return zero", c, nchem); - #endif - - return ((c<0) || (c>=nchem)) ? 0 : chem[c]; - } - - - //void print_nblist(void) const; +#ifdef _undefined_ + if ((c<0) || (c>=nchem)) + MyWarning::warning("CellBase::Chemical says: index c is: %d, but nchem is: %d. Merely return zero", c, nchem); +#endif - boundary_type SetBoundary(boundary_type bound) { - if (bound!=None) { - } - return boundary=bound; - } - - boundary_type ResetBoundary(void) { - return boundary=None; - } - boundary_type Boundary(void) const { - return boundary; - } - static int &NChem(void) { - return static_data_members->nchem; - } - - double CalcArea(void) const; - double RecalcArea(void) { - return area = CalcArea(); + return ((c<0) || (c>=nchem)) ? 0 : chem[c]; + } + + + //void print_nblist(void) const; + + boundary_type SetBoundary(boundary_type bound) + { + if (bound!=None) { } - - Vector Centroid(void) const; - - void SetIntegrals(void) const; - - double Length(Vector *long_axis = 0, double *width = 0) const; - double CalcLength(Vector *long_axis = 0, double *width = 0) const; - + return boundary=bound; + } + + boundary_type ResetBoundary(void) { return boundary=None; } - inline int Index(void) const { - return index; - } - + boundary_type Boundary(void) const { return boundary; } + + static int &NChem(void) { return static_data_members->nchem; } + + double CalcArea(void) const; + + double RecalcArea(void) { return area = CalcArea(); } - void SetTargetArea(double tar_ar) { - target_area=tar_ar; - } - inline void SetTargetLength(double tar_l) { - target_length=tar_l; - } - inline void SetLambdaLength(double lambda_length) { - lambda_celllength = lambda_length; - } - inline double TargetArea(void) { - return target_area; - } - - inline void SetStiffness(double stiff) { - stiffness = stiff; - } + Vector Centroid(void) const; + + void SetIntegrals(void) const; + + double Length(Vector *long_axis = 0, double *width = 0) const; + double CalcLength(Vector *long_axis = 0, double *width = 0) const; + + + inline int Index(void) const { return index; } + + + void SetTargetArea(double tar_ar) { target_area=tar_ar; } - inline double Stiffness(void) { - return stiffness; - } - inline double EnlargeTargetArea(double da) { - return target_area+=da; - } - - inline double Area(void) const { - return area; - } - - inline void Divide(void) { - flag_for_divide = true; - } - - inline void DivideOverAxis(const Vector &v) { - division_axis = new Vector(v); - flag_for_divide = true; - } - + inline void SetTargetLength(double tar_l) { target_length=tar_l; } + + inline void SetLambdaLength(double lambda_length) { lambda_celllength = lambda_length; } + + inline double TargetArea(void) { return target_area; } - inline double Circumference(void) const { - double sum=0.; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->Length(); - } - - return sum; - } + inline void SetStiffness(double stiff) { stiffness = stiff; } + + inline double Stiffness(void) { return stiffness; } + + inline double EnlargeTargetArea(double da) { return target_area+=da; } + + inline double Area(void) const { return area; } - QList getWalls(void) { - QList wall_list; - for (list::iterator i=walls.begin(); - i!=walls.end(); - i++) { - wall_list << *i; - } - return wall_list; - } - - void Dump(ostream &os) const; - - QString printednodelist(void); - + inline void Divide(void) { flag_for_divide = true; } - - inline bool DeadP(void) { return dead; } - inline void MarkDead(void) { dead = true; } - - static double &BaseArea(void) { - return static_data_members->base_area; - } - - void CheckForDivision(void); + inline void DivideOverAxis(const Vector &v) + { + division_axis = new Vector(v); + flag_for_divide = true; + } - - // write flux from neighboring cells into "flux" - void Flux(double *flux, double *D); - inline bool FixedP(void) { return fixed; } - inline bool Fix(void) { FixNodes(); return (fixed=true); } - inline bool Unfix(void) { UnfixNodes(); return (fixed=false);} - inline void setCellVec(Vector cv) { cellvec = cv; } - - bool AtBoundaryP(void) const; - - static inline int &NCells(void) { - return static_data_members->ncells; + inline double Circumference(void) const { + double sum=0.; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->Length(); } - - - inline void Mark(void) { - marked=true; - } - inline void Unmark(void) { - marked=false; - } - inline bool Marked(void) const { - return marked; - } + return sum; + } - //! Returns the sum of chemical "chem" of this CellBase's neighbors - double SumChemicalsOfNeighbors(int chem) { - double sum=0.; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->Length() * ( (*w)->c1!=this ? (*w)->c1->Chemical(chem) : (*w)->c2->Chemical(chem) ); - } - return sum; - } - - //! Generalization of the previous member function - template P ReduceNeighbors(Op f) { - P sum=0; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->c1 != this ? f( *((*w)->c1) ) : f ( *((*w)->c2) ); - } - return sum; - } - - //! The same, but now for the walls - template P ReduceWalls(Op f, P sum) { - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += f( **w ); - } - return sum; + QList getWalls(void) { + QList wall_list; + for (list::iterator i=walls.begin(); + i!=walls.end(); + i++) { + wall_list << *i; } - - - - - //! The same, but now for the walls AND neighbors - template P ReduceCellAndWalls(Op f) { - P sum = 0; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += ((*w)->c1 == this) ? - f( ((*w)->c1), ((*w)->c2), *w ) : - f( ((*w)->c2), ((*w)->c1), *w ); - } - return sum; + return wall_list; + } + + void Dump(ostream &os) const; + + QString printednodelist(void); + + inline bool DeadP(void) { return dead; } + inline void MarkDead(void) { dead = true; } + + static double &BaseArea(void) + { + return static_data_members->base_area; + } + + void CheckForDivision(void); + + // write flux from neighboring cells into "flux" + void Flux(double *flux, double *D); + inline bool FixedP(void) { return fixed; } + inline bool Fix(void) { FixNodes(); return (fixed=true); } + inline bool Unfix(void) { UnfixNodes(); return (fixed=false);} + inline void setCellVec(Vector cv) { cellvec = cv; } + + bool AtBoundaryP(void) const; + + static inline int &NCells(void) + { + return static_data_members->ncells; + } + + inline void Mark(void) + { + marked=true; + } + + inline void Unmark(void) + { + marked=false; + } + + inline bool Marked(void) const { + return marked; + } + + //! Returns the sum of chemical "chem" of this CellBase's neighbors + double SumChemicalsOfNeighbors(int chem) + { + double sum=0.; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->Length() * ( (*w)->c1!=this ? (*w)->c1->Chemical(chem) : (*w)->c2->Chemical(chem) ); } - - - //! Sum transporters at this CellBase's side of the walls - double SumTransporters(int ch) { - double sum=0.; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->getTransporter(this, ch); - - } - - return sum; + return sum; + } + + //! Generalization of the previous member function + template P ReduceNeighbors(Op f) { + P sum=0; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->c1 != this ? f( *((*w)->c1) ) : f ( *((*w)->c2) ); + } + return sum; + } + + //! The same, but now for the walls + template P ReduceWalls(Op f, P sum) { + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += f( **w ); } + return sum; + } - inline int NumberOfDivisions(void) { return div_counter; } - - //! Sum transporters at this CellBase's side of the walls - double SumLengthTransporters(int ch) { - double sum=0.; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->getTransporter(this, ch) * (*w)->Length(); - - } - - return sum; + //! The same, but now for the walls AND neighbors + template P ReduceCellAndWalls(Op f) + { + P sum = 0; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += ((*w)->c1 == this) ? + f( ((*w)->c1), ((*w)->c2), *w ) : + f( ((*w)->c2), ((*w)->c1), *w ); + } + return sum; + } + + + //! Sum transporters at this CellBase's side of the walls + double SumTransporters(int ch) + { + double sum=0.; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->getTransporter(this, ch); + } - - - - double SumLengthTransportersChemical(int trch, int ch) { - double sum=0.; - for (list::const_iterator w=walls.begin(); - w!=walls.end(); - w++) { - sum += (*w)->getTransporter(this, trch) * ( (*w)->c1!=this ? (*w)->c1->Chemical(ch) : (*w)->c2->Chemical(ch) ); - - } - - return sum; + return sum; + } + + inline int NumberOfDivisions(void) { return div_counter; } + + //! Sum transporters at this CellBase's side of the walls + double SumLengthTransporters(int ch) + { + double sum=0.; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->getTransporter(this, ch) * (*w)->Length(); + } - inline int CellType(void) const { return cell_type; } - inline void SetCellType(int ct) { cell_type = ct; } + return sum; + } + + - - static void SetNChem(int new_nchem) { - if (NCells()) { - MyWarning::error("CellBase::SetNChem says: not permitted, call SetNChem after deleting all cells."); - } else { - NChem() = new_nchem; - } - } - - inline double TargetLength() const { return target_length; } + double SumLengthTransportersChemical(int trch, int ch) + { + double sum=0.; + for (list::const_iterator w=walls.begin(); + w!=walls.end(); + w++) { + sum += (*w)->getTransporter(this, trch) * ( (*w)->c1!=this ? (*w)->c1->Chemical(ch) : (*w)->c2->Chemical(ch) ); + + } + return sum; + } + inline int CellType(void) const { return cell_type; } + inline void SetCellType(int ct) { cell_type = ct; } - static inline CellsStaticDatamembers *GetStaticDataMemberPointer(void) { return static_data_members; } - -protected: - // (define a list of Node* iterators) - typedef list < list::iterator > ItList; - - int index; - inline void SetChemToNewchem(void) { - for (int c=0;c nodes; - void ConstructNeighborList(void); - long wall_list_index (Wall *elem) const; + // (define a list of Node* iterators) + typedef list < list::iterator > ItList; - // DATA MEMBERS - - // list of nodes, in clockwise order - - // a (non-ordered) list of neighboring cells (actually I think the - // introduction of ConstructWalls() has made these - // lists ordered (clockwise), but I am not yet 100% sure...). - list neighbors; + int index; - list walls; - - double *chem; - double *new_chem; - - boundary_type boundary; - mutable double area; - double target_area; - double target_length; - double lambda_celllength; + inline void SetChemToNewchem(void) + { + for (int c=0;c nodes; + void ConstructNeighborList(void); + long wall_list_index (Wall *elem) const; + + // DATA MEMBERS + + // list of nodes, in clockwise order + + // a (non-ordered) list of neighboring cells (actually I think the + // introduction of ConstructWalls() has made these + // lists ordered (clockwise), but I am not yet 100% sure...). + list neighbors; + + list walls; - bool fixed; - bool pin_fixed; - bool at_boundary; - bool dead; - bool flag_for_divide; - - Vector *division_axis; - - int cell_type; - - - // for length constraint - mutable double intgrl_xx, intgrl_xy, intgrl_yy, intgrl_x, intgrl_y; - - bool source; - Vector cellvec; - - // STATIC DATAMEMBERS MOVED TO CLASS - static CellsStaticDatamembers *static_data_members; - double source_conc; - int source_chem; - - // PRIVATE MEMBER FUNCTIONS - inline static void ClearNCells(void) { - NCells()=0; - } - - bool marked; - int div_counter; + double *chem; + double *new_chem; + + boundary_type boundary; + mutable double area; + double target_area; + double target_length; + double lambda_celllength; + + double stiffness; // stiffness like in Hogeweg (2000) + + bool fixed; + bool pin_fixed; + bool at_boundary; + bool dead; + bool flag_for_divide; + + Vector *division_axis; + int cell_type; + + // for length constraint + mutable double intgrl_xx, intgrl_xy, intgrl_yy, intgrl_x, intgrl_y; + + bool source; + Vector cellvec; + + // STATIC DATAMEMBERS MOVED TO CLASS + static CellsStaticDatamembers *static_data_members; + double source_conc; + int source_chem; + + // PRIVATE MEMBER FUNCTIONS + inline static void ClearNCells(void) + { + NCells()=0; + } + + bool marked; + int div_counter; }; ostream &operator<<(ostream &os, const CellBase &v); -inline Vector PINdir(CellBase *here, CellBase *nb, Wall *w) { - nb = NULL; // assignment merely to obviate compilation warning - return w->getTransporter( here, 1) * w->getInfluxVector(here); +inline Vector PINdir(CellBase *here, CellBase *nb, Wall *w) +{ + nb = NULL; // assignment merely to obviate compilation warning + return w->getTransporter( here, 1) * w->getInfluxVector(here); } - #endif - - - - +/* finis*/ diff --git a/src/cellitem.cpp b/src/cellitem.cpp --- a/src/cellitem.cpp +++ b/src/cellitem.cpp @@ -29,17 +29,19 @@ CellItem::CellItem( Cell *c, QGraphicsSc : QGraphicsPolygonItem( 0, canvas ), SimItemBase( c, canvas){ } -void CellItem::userMove(double dx, double dy) { +void CellItem::userMove(double dx, double dy) +{ QGraphicsPolygonItem::moveBy( dx, dy ); // also move the cell itself class_cast(obj)->x += (dx/Cell::Magnification()); class_cast(obj)->y += (dy/Cell::Magnification()); - + class_cast(obj)->Move( (dx/Cell::Magnification()), (dy/Cell::Magnification()) ); } - QPainterPath CellItem::shape() const { return QGraphicsPolygonItem::shape(); } QRectF CellItem::boundingRect() const { return QGraphicsPolygonItem::boundingRect(); } + +/* finis */ diff --git a/src/cellitem.h b/src/cellitem.h --- a/src/cellitem.h +++ b/src/cellitem.h @@ -34,7 +34,7 @@ class CellItem : public QGraphicsPolygonItem, public SimItemBase { -public: + public: CellItem( Cell *n, QGraphicsScene *canvas ); virtual ~CellItem() {} Cell &getCell(void) const { return *class_cast(obj); } @@ -43,7 +43,8 @@ public: QRectF boundingRect() const; private: - }; #endif + +/* finis */ diff --git a/src/curvecolors.h b/src/curvecolors.h --- a/src/curvecolors.h +++ b/src/curvecolors.h @@ -175,3 +175,5 @@ class CurveColors { QStringList colors; }; #endif + +/* finis */ diff --git a/src/data_plot.cpp b/src/data_plot.cpp --- a/src/data_plot.cpp +++ b/src/data_plot.cpp @@ -51,7 +51,7 @@ DataPlot::DataPlot(QWidget *parent, cons // Number of curves is number of names given ncurves = curvenames.size(); - + // allocate data and curves d_t = new double[PLOT_SIZE]; d_x = new double *[ncurves]; @@ -59,15 +59,13 @@ DataPlot::DataPlot(QWidget *parent, cons for (int i=1;isetFrameStyle(QFrame::Box | QFrame::Plain ); + canvas()->setLineWidth(1); - canvas()->setFrameStyle(QFrame::Box | QFrame::Plain ); - canvas()->setLineWidth(1); - - for ( int i = 0; i < QwtPlot::axisCnt; i++ ) + for ( int i = 0; i < QwtPlot::axisCnt; i++ ) { - QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i); - if ( scaleWidget ) - scaleWidget->setMargin(0); + QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i); + if ( scaleWidget ) + scaleWidget->setMargin(0); - QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i); - if ( scaleDraw ) - scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); + QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i); + if ( scaleDraw ) + scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); } } - // Generate new values void DataPlot::AddValue(double t,double *x) { // std::cerr << "AddValue receives: " << t << ", " << y << ", " << z << std::endl; - + // Plot slowly fills up, then shifts to the left if ( data_pos >= PLOT_SIZE ) { - + for ( int j = 0; j < PLOT_SIZE - 1; j++ ) d_t[j] = d_t[j+1]; @@ -154,7 +150,6 @@ void DataPlot::AddValue(double t,double d_x[i][j] = d_x[i][j+1]; } data_pos = PLOT_SIZE - 1; - } d_t[data_pos] = t; @@ -163,31 +158,26 @@ void DataPlot::AddValue(double t,double curves[i].setRawData(d_t, d_x[i], data_pos); d_x[i][data_pos] = x[i]; } - + setAxisScale(QwtPlot::xBottom, d_t[0], t); - data_pos++; + // update the display replot(); - - } PlotDialog::PlotDialog(QWidget *parent, const QString title, const QStringList curvenames): QDialog(parent) { - plot = new DataPlot(this,title,curvenames); - plot->resize(400,300); - show(); - } -PlotDialog::~PlotDialog(void) { - +PlotDialog::~PlotDialog(void) +{ delete plot; } +/* finis */ diff --git a/src/data_plot.h b/src/data_plot.h --- a/src/data_plot.h +++ b/src/data_plot.h @@ -36,40 +36,39 @@ const int PLOT_SIZE = 1000; class DataPlot : public QwtPlot { - Q_OBJECT + Q_OBJECT -public: + public: DataPlot(QWidget *parent, const QString title, const QStringList curvenames); virtual ~DataPlot(void); -public slots: - void AddValue(double t, double *x); + public slots: + void AddValue(double t, double *x); -private: - void alignScales(); + private: + void alignScales(); - double *d_t; - double **d_x; + double *d_t; + double **d_x; - int d_interval; // timer in ms - int d_timerId; - - QwtPlotCurve *curves; - int data_pos; - int ncurves; - - CurveColors curvecolors; + int d_interval; // timer in ms + int d_timerId; + + QwtPlotCurve *curves; + int data_pos; + int ncurves; + + CurveColors curvecolors; protected: - // to write contents of DataPlot to a file - QFile *datfile; - QTextStream datstream; - + // to write contents of DataPlot to a file + QFile *datfile; + QTextStream datstream; }; class PlotDialog : public QDialog { -Q_OBJECT - public: + Q_OBJECT + public: PlotDialog(QWidget *parent, const QString title, const QStringList curvenames); ~PlotDialog(void); public slots: @@ -82,3 +81,5 @@ Q_OBJECT }; #endif + +/* finis */ diff --git a/src/far_mem_5.h b/src/far_mem_5.h --- a/src/far_mem_5.h +++ b/src/far_mem_5.h @@ -21,134 +21,147 @@ * */ - #ifndef _FAR_MEM_5_h_ #define _FAR_MEM_5_h_ template - struct my_1_function - { -typedef _Arg1 argument_type1; -typedef _Result result_type; ///< result_type is the return type -}; + struct my_1_function + { + typedef _Arg1 argument_type1; + typedef _Result result_type; ///< result_type is the return type + }; template -class far_1_arg_mem_fun_t : public my_1_function { -public: -explicit far_1_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1)) { - m_ptyp = &ir_typ; - m_pmf = i_pmf; - }; -Result operator()(Param1 i_prm1) { return (m_ptyp->*(m_pmf))(i_prm1); }; + class far_1_arg_mem_fun_t : public my_1_function { + public: + explicit far_1_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1)) { + m_ptyp = &ir_typ; + m_pmf = i_pmf; + }; + Result operator()(Param1 i_prm1) { return (m_ptyp->*(m_pmf))(i_prm1); }; -protected: -Type *m_ptyp; -Result (Type::*m_pmf)(Param1); + protected: + Type *m_ptyp; + Result (Type::*m_pmf)(Param1); }; -template far_1_arg_mem_fun_t far_1_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1) ) { - return far_1_arg_mem_fun_t(ir_typ,i_pmf); - } +template far_1_arg_mem_fun_t far_1_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1) ) +{ + return far_1_arg_mem_fun_t(ir_typ,i_pmf); +} + template - struct my_2_function - { -typedef _Arg1 argument_type1; -typedef _Arg2 argument_type2; -typedef _Result result_type; ///< result_type is the return type -}; + struct my_2_function + { + typedef _Arg1 argument_type1; + typedef _Arg2 argument_type2; + typedef _Result result_type; ///< result_type is the return type + }; + template -class far_2_arg_mem_fun_t : public my_2_function { -public: -explicit far_2_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2)) { - m_ptyp = &ir_typ; - m_pmf = i_pmf; - }; -Result operator()(Param1 i_prm1, Param2 i_prm2) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2); }; + class far_2_arg_mem_fun_t : public my_2_function { + public: + explicit far_2_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2)) { + m_ptyp = &ir_typ; + m_pmf = i_pmf; + }; + Result operator()(Param1 i_prm1, Param2 i_prm2) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2); }; -protected: -Type *m_ptyp; -Result (Type::*m_pmf)(Param1, Param2); + protected: + Type *m_ptyp; + Result (Type::*m_pmf)(Param1, Param2); }; -template far_2_arg_mem_fun_t far_2_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2) ) { - return far_2_arg_mem_fun_t(ir_typ,i_pmf); - } +template far_2_arg_mem_fun_t far_2_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2) ) { + return far_2_arg_mem_fun_t(ir_typ,i_pmf); +} + template - struct my_3_function - { -typedef _Arg1 argument_type1; -typedef _Arg2 argument_type2; -typedef _Arg3 argument_type3; -typedef _Result result_type; ///< result_type is the return type -}; + struct my_3_function + { + typedef _Arg1 argument_type1; + typedef _Arg2 argument_type2; + typedef _Arg3 argument_type3; + typedef _Result result_type; ///< result_type is the return type + }; + template -class far_3_arg_mem_fun_t : public my_3_function { -public: -explicit far_3_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3)) { - m_ptyp = &ir_typ; - m_pmf = i_pmf; - }; -Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3); }; + class far_3_arg_mem_fun_t : public my_3_function { + public: + explicit far_3_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3)) { + m_ptyp = &ir_typ; + m_pmf = i_pmf; + }; + Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3); }; -protected: -Type *m_ptyp; -Result (Type::*m_pmf)(Param1, Param2, Param3); + protected: + Type *m_ptyp; + Result (Type::*m_pmf)(Param1, Param2, Param3); }; -template far_3_arg_mem_fun_t far_3_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3) ) { - return far_3_arg_mem_fun_t(ir_typ,i_pmf); - } +template far_3_arg_mem_fun_t far_3_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3) ) { + return far_3_arg_mem_fun_t(ir_typ,i_pmf); +} + template - struct my_4_function - { -typedef _Arg1 argument_type1; -typedef _Arg2 argument_type2; -typedef _Arg3 argument_type3; -typedef _Arg4 argument_type4; -typedef _Result result_type; ///< result_type is the return type -}; + struct my_4_function + { + typedef _Arg1 argument_type1; + typedef _Arg2 argument_type2; + typedef _Arg3 argument_type3; + typedef _Arg4 argument_type4; + typedef _Result result_type; ///< result_type is the return type + }; + template -class far_4_arg_mem_fun_t : public my_4_function { -public: -explicit far_4_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4)) { - m_ptyp = &ir_typ; - m_pmf = i_pmf; - }; -Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3, Param4 i_prm4) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3, i_prm4); }; + class far_4_arg_mem_fun_t : public my_4_function { + public: + explicit far_4_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4)) { + m_ptyp = &ir_typ; + m_pmf = i_pmf; + }; + Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3, Param4 i_prm4) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3, i_prm4); }; -protected: -Type *m_ptyp; -Result (Type::*m_pmf)(Param1, Param2, Param3, Param4); + protected: + Type *m_ptyp; + Result (Type::*m_pmf)(Param1, Param2, Param3, Param4); }; template far_4_arg_mem_fun_t far_4_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4) ) { - return far_4_arg_mem_fun_t(ir_typ,i_pmf); - } + return far_4_arg_mem_fun_t(ir_typ,i_pmf); +} + template - struct my_5_function - { -typedef _Arg1 argument_type1; -typedef _Arg2 argument_type2; -typedef _Arg3 argument_type3; -typedef _Arg4 argument_type4; -typedef _Arg5 argument_type5; -typedef _Result result_type; ///< result_type is the return type -}; + struct my_5_function + { + typedef _Arg1 argument_type1; + typedef _Arg2 argument_type2; + typedef _Arg3 argument_type3; + typedef _Arg4 argument_type4; + typedef _Arg5 argument_type5; + typedef _Result result_type; ///< result_type is the return type + }; + template -class far_5_arg_mem_fun_t : public my_5_function { -public: -explicit far_5_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4, Param5)) { - m_ptyp = &ir_typ; - m_pmf = i_pmf; - }; -Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3, Param4 i_prm4, Param5 i_prm5) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3, i_prm4, i_prm5); }; + class far_5_arg_mem_fun_t : public my_5_function { + public: + explicit far_5_arg_mem_fun_t(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4, Param5)) { + m_ptyp = &ir_typ; + m_pmf = i_pmf; + }; + Result operator()(Param1 i_prm1, Param2 i_prm2, Param3 i_prm3, Param4 i_prm4, Param5 i_prm5) { return (m_ptyp->*(m_pmf))(i_prm1, i_prm2, i_prm3, i_prm4, i_prm5); }; -protected: -Type *m_ptyp; -Result (Type::*m_pmf)(Param1, Param2, Param3, Param4, Param5); + protected: + Type *m_ptyp; + Result (Type::*m_pmf)(Param1, Param2, Param3, Param4, Param5); }; template far_5_arg_mem_fun_t far_5_arg_mem_fun(Type &ir_typ, Result (Type::*i_pmf)(Param1, Param2, Param3, Param4, Param5) ) { - return far_5_arg_mem_fun_t(ir_typ,i_pmf); - } + return far_5_arg_mem_fun_t(ir_typ,i_pmf); +} #endif + +/* finis */ diff --git a/src/flux_function.h b/src/flux_function.h --- a/src/flux_function.h +++ b/src/flux_function.h @@ -36,6 +36,8 @@ #include "far_mem_5.h" #define SumFluxFromWalls( _vleafcellp_, _flux_function_ ) \ -(( _vleafcellp_->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &_flux_function_ ) ) )) + (( _vleafcellp_->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &_flux_function_ )))) #endif + +/* finis */ diff --git a/src/forwardeuler.cpp b/src/forwardeuler.cpp --- a/src/forwardeuler.cpp +++ b/src/forwardeuler.cpp @@ -38,7 +38,7 @@ const double ForwardEuler::Pshrnk = -0.2 const double ForwardEuler::Errcon = 1.89e-4; const double ForwardEuler::Maxstp = 10000000; const double ForwardEuler::Tiny = 1.0e-30; - + /* User storage for intermediate results. Preset kmax and dxsav in the calling program. If kmax = @@ -49,12 +49,12 @@ const double ForwardEuler::Tiny = 1.0e-3 void ForwardEuler::odeint(double *ystart, int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad) /* Runge-Kutta driver with adaptive stepsize control. Integrate starting values ystart[1..nvar] - from x1 to x2 with accuracy eps, storing intermediate results in global variables. h1 should - be set as a guessed first stepsize, hmin as the minimum allowed stepsize (can be zero). On - output nok and nbad are the number of good and bad (but retried and fixed) steps taken, and - ystart is replaced byv alues at the end of the integration interval. derivs is the user-supplied - routine for calculating the right-hand side derivative, while rkqs is the name of the stepper - routine to be used. */ + from x1 to x2 with accuracy eps, storing intermediate results in global variables. h1 should + be set as a guessed first stepsize, hmin as the minimum allowed stepsize (can be zero). On + output nok and nbad are the number of good and bad (but retried and fixed) steps taken, and + ystart is replaced byv alues at the end of the integration interval. derivs is the user-supplied + routine for calculating the right-hand side derivative, while rkqs is the name of the stepper + routine to be used. */ { static bool warning_issued = false; @@ -68,12 +68,12 @@ void ForwardEuler::odeint(double *ystart } // N.B. Not for serious use and not fully usage compatible with RungeKutta // simply for testing API of integrator. - + double *y,*dydx; y=new double[nvar]; dydx=new double[nvar]; double x=x1; - + for (int i=0;i 0) xsav=x-dxsav*2.0; //Assures storage of first step. @@ -81,9 +81,9 @@ void ForwardEuler::odeint(double *ystart dydx=new double[nvar]; for (int nstp=0;nstp 0 && kount < kmax-1) { xp[kount]=x; //Store intermediate results. for (int i=0;i= 0.0) { //Are we done? goto done; } - - } done: @@ -110,11 +107,12 @@ void ForwardEuler::odeint(double *ystart if (kmax) { xp[kount]=x; //Save final step. for (int i=0;iaddStretch(); - boxLayout()->addWidget(virtleaf);//, Qt::AlignHCenter); - boxLayout()->addStretch(); - } - - void SetText(QString text) { - virtleaf->setText(QString("

The Virtual Leaf

\n
Model: %1
").arg(text)); - } - -private: - QLabel *virtleaf; + setHorizontalStretchable(true); + boxLayout()->addStretch(); + boxLayout()->addWidget(virtleaf);//, Qt::AlignHCenter); + boxLayout()->addStretch(); + } + + void SetText(QString text) { + virtleaf->setText(QString("

The Virtual Leaf

\n
Model: %1
").arg(text)); + } + + private: + QLabel *virtleaf; }; -#endif \ No newline at end of file +#endif + +/* finis */ diff --git a/src/mainbase.cpp b/src/mainbase.cpp --- a/src/mainbase.cpp +++ b/src/mainbase.cpp @@ -31,219 +31,217 @@ static const std::string _module_id("$Id$"); xmlNode *MainBase::XMLSettingsTree(void) const { - - xmlNode *xmlsettings = xmlNewNode(NULL, BAD_CAST "settings"); - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_centers"); - ostringstream text; - text << bool_name(showcentersp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_nodes"); - ostringstream text; - text << bool_name(showmeshp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_node_numbers"); - ostringstream text; - text << bool_name(shownodenumbersp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_numbers"); - ostringstream text; - text << bool_name(showcellnumbersp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_border_cells"); - ostringstream text; - text << bool_name(showbordercellp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_axes"); - ostringstream text; - text << bool_name(showcellsaxesp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_strain"); - ostringstream text; - text << bool_name(showcellstrainp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_fluxes"); - ostringstream text; - text << bool_name(showfluxesp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_walls"); - ostringstream text; - text << bool_name(showwallsp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_apoplasts"); - ostringstream text; - text << bool_name(showapoplastsp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "save_movie_frames"); - ostringstream text; - text << bool_name(movieframesp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_only_leaf_boundary"); - ostringstream text; - text << bool_name(showboundaryonlyp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "cell_growth"); - ostringstream text; - text << bool_name(dynamicscellsp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - { - xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); - xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "hide_cells"); - ostringstream text; - text << bool_name(hidecellsp); - xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); - } - - return xmlsettings; + + xmlNode *xmlsettings = xmlNewNode(NULL, BAD_CAST "settings"); + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_centers"); + ostringstream text; + text << bool_name(showcentersp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_nodes"); + ostringstream text; + text << bool_name(showmeshp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_node_numbers"); + ostringstream text; + text << bool_name(shownodenumbersp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_numbers"); + ostringstream text; + text << bool_name(showcellnumbersp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_border_cells"); + ostringstream text; + text << bool_name(showbordercellp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_axes"); + ostringstream text; + text << bool_name(showcellsaxesp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_strain"); + ostringstream text; + text << bool_name(showcellstrainp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_fluxes"); + ostringstream text; + text << bool_name(showfluxesp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_walls"); + ostringstream text; + text << bool_name(showwallsp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_apoplasts"); + ostringstream text; + text << bool_name(showapoplastsp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "save_movie_frames"); + ostringstream text; + text << bool_name(movieframesp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_only_leaf_boundary"); + ostringstream text; + text << bool_name(showboundaryonlyp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "cell_growth"); + ostringstream text; + text << bool_name(dynamicscellsp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL); + xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "hide_cells"); + ostringstream text; + text << bool_name(hidecellsp); + xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + return xmlsettings; } -void MainBase::XMLReadSettings(xmlNode *settings) { - - // Many files have no settings section, so don't complain about it. - // Defaults will be used instead. - if (settings == 0) { - return; - } - - xmlNode *cur = settings->xmlChildrenNode; - - while (cur!=NULL) { - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"setting"))){ - - xmlChar *name = xmlGetProp(cur, BAD_CAST "name"); - xmlChar *val = xmlGetProp(cur, BAD_CAST "val"); - if (!xmlStrcmp(name, (const xmlChar *)"show_cell_centers")) { - showcentersp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_nodes")) { - showmeshp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_node_numbers")) { - shownodenumbersp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_cell_numbers")) { - showcellnumbersp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_border_cells")) { - showbordercellp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_cell_axes")) { - showcellsaxesp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_cell_strain")) { - showcellstrainp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_fluxes")) { - showfluxesp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_walls")) { - showwallsp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_apoplasts")) { - showapoplastsp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"save_movie_frames")) { - movieframesp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"show_only_leaf_boundary")) { - showboundaryonlyp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name, (const xmlChar *)"cell_growth")) { - dynamicscellsp = strtobool( (const char *)val ); - } - if (!xmlStrcmp(name,(const xmlChar *)"hide_cells")) { - hidecellsp = strtobool( (const char *)val ); - } - - xmlFree(name); - xmlFree(val); - - - } - cur=cur->next; - } - +void MainBase::XMLReadSettings(xmlNode *settings) +{ + + // Many files have no settings section, so don't complain about it. + // Defaults will be used instead. + if (settings == 0) { + return; + } + + xmlNode *cur = settings->xmlChildrenNode; + + while (cur!=NULL) { + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"setting"))){ + + xmlChar *name = xmlGetProp(cur, BAD_CAST "name"); + xmlChar *val = xmlGetProp(cur, BAD_CAST "val"); + if (!xmlStrcmp(name, (const xmlChar *)"show_cell_centers")) { + showcentersp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_nodes")) { + showmeshp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_node_numbers")) { + shownodenumbersp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_cell_numbers")) { + showcellnumbersp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_border_cells")) { + showbordercellp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_cell_axes")) { + showcellsaxesp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_cell_strain")) { + showcellstrainp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_fluxes")) { + showfluxesp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_walls")) { + showwallsp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_apoplasts")) { + showapoplastsp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"save_movie_frames")) { + movieframesp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"show_only_leaf_boundary")) { + showboundaryonlyp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name, (const xmlChar *)"cell_growth")) { + dynamicscellsp = strtobool( (const char *)val ); + } + if (!xmlStrcmp(name,(const xmlChar *)"hide_cells")) { + hidecellsp = strtobool( (const char *)val ); + } + + xmlFree(name); + xmlFree(val); + } + cur=cur->next; + } } -void MainBase::Save(const char *fname, const char *format, int sizex, int sizey) { - - Vector ll,ur; - mesh.BoundingBox(ll, ur); - - if (QString(fname).isEmpty()) { - MyWarning::warning("No output filename given. Saving nothing.\n"); - return; - } - - - ll*=Cell::Magnification(); ur*=Cell::Magnification(); - - // give the leaf some space - Vector border = ((ur-ll)/5.); - - if (!QString(format).contains("pdf", Qt::CaseInsensitive)) { - - QImage *image = new QImage(QSize(sizex, sizey), QImage::Format_RGB32); - image->fill(QColor(Qt::white).rgb()); - QPainter *painter=new QPainter(image); - canvas.render(painter); - if (!image->save(QString(fname))) { - MyWarning::warning("Image not saved successfully. Is the disk full or the extension not recognized?"); - }; - delete painter; - delete image; - } else { - QPrinter pdf(QPrinter::HighResolution); - pdf.setOutputFileName(fname); - pdf.setOutputFormat(QPrinter::PdfFormat); - QPainter painter(&pdf); - canvas.render(&painter, QRectF(), QRectF(-5000,-5000, 10000, 10000)); - - cerr << "Rendering to printer\n"; - } +void MainBase::Save(const char *fname, const char *format, int sizex, int sizey) +{ + + Vector ll,ur; + mesh.BoundingBox(ll, ur); + + if (QString(fname).isEmpty()) { + MyWarning::warning("No output filename given. Saving nothing.\n"); + return; + } + + ll*=Cell::Magnification(); ur*=Cell::Magnification(); + + // give the leaf some space + Vector border = ((ur-ll)/5.); + + if (!QString(format).contains("pdf", Qt::CaseInsensitive)) { + + QImage *image = new QImage(QSize(sizex, sizey), QImage::Format_RGB32); + image->fill(QColor(Qt::white).rgb()); + QPainter *painter=new QPainter(image); + canvas.render(painter); + if (!image->save(QString(fname))) { + MyWarning::warning("Image not saved successfully. Is the disk full or the extension not recognized?"); + }; + delete painter; + delete image; + } else { + QPrinter pdf(QPrinter::HighResolution); + pdf.setOutputFileName(fname); + pdf.setOutputFormat(QPrinter::PdfFormat); + QPainter painter(&pdf); + canvas.render(&painter, QRectF(), QRectF(-5000,-5000, 10000, 10000)); + + cerr << "Rendering to printer\n"; + } } -void MainBase::CutSAM() { - - mesh.CutAwaySAM(); - +void MainBase::CutSAM() +{ + mesh.CutAwaySAM(); } + +/* finis */ diff --git a/src/mainbase.h b/src/mainbase.h --- a/src/mainbase.h +++ b/src/mainbase.h @@ -42,8 +42,8 @@ using namespace std; class MainBase { public: - MainBase(QGraphicsScene &c, Mesh &m) : mesh(m), canvas(c) { - + MainBase(QGraphicsScene &c, Mesh &m) : mesh(m), canvas(c) { + // Standard options for batch version showcentersp = false; showmeshp = false; @@ -60,71 +60,71 @@ class MainBase { showtooltipsp = false; hidecellsp = false; } - virtual ~MainBase() {}; - - virtual double TimeStep(); - virtual void Init(char *leaffile=0); - - virtual bool ShowCentersP(void) {return showcentersp;} - virtual bool ShowMeshP(void) {return showmeshp; } - virtual bool ShowBorderCellsP(void) {return showbordercellp; } - virtual bool PausedP(void) {return false; } - virtual bool ShowNodeNumbersP(void) {return shownodenumbersp; } - virtual bool ShowCellNumbersP(void) {return showcellnumbersp;} - virtual bool ShowCellAxesP(void) {return showcellsaxesp;} - virtual bool ShowCellStrainP(void) {return showcellstrainp;} - virtual bool MovieFramesP(void) {return movieframesp;} - virtual bool ShowBoundaryOnlyP(void) {return showboundaryonlyp;} - virtual bool ShowToolTipsP(void) {return showtooltipsp;} - virtual bool ShowWallsP(void) {return showwallsp;} - virtual bool ShowApoplastsP(void) { return showapoplastsp;} - virtual bool ShowFluxesP(void) { return showfluxesp; } - virtual bool DynamicCellsP(void) { return dynamicscellsp; } - virtual void FitCanvasToWindow() {}; - virtual void FitLeafToCanvas() {}; - virtual bool HideCellsP(void) { return hidecellsp; } - virtual void clear(void) { - QList list = canvas.items(); - QList::Iterator it = list.begin(); - for (; it != list.end(); ++it) { - if ( *it ) - delete *it; - } - }; - virtual void XMLReadSettings(xmlNode *settings); - virtual double getFluxArrowsize(void) { return 10.;} - - void Save(const char *fname, const char *format, int sizex=640, int sizey=480); - void CutSAM(void); - - void Plot(int resize_stride=10); + virtual ~MainBase() {}; + + virtual double TimeStep(); + virtual void Init(char *leaffile=0); - virtual void UserMessage(QString message, int timeout = 0) { - timeout = 0; // merely to obviate 'warning unused parameter' message - cerr << message.toAscii().constData() << endl; + virtual bool ShowCentersP(void) {return showcentersp;} + virtual bool ShowMeshP(void) {return showmeshp; } + virtual bool ShowBorderCellsP(void) {return showbordercellp; } + virtual bool PausedP(void) {return false; } + virtual bool ShowNodeNumbersP(void) {return shownodenumbersp; } + virtual bool ShowCellNumbersP(void) {return showcellnumbersp;} + virtual bool ShowCellAxesP(void) {return showcellsaxesp;} + virtual bool ShowCellStrainP(void) {return showcellstrainp;} + virtual bool MovieFramesP(void) {return movieframesp;} + virtual bool ShowBoundaryOnlyP(void) {return showboundaryonlyp;} + virtual bool ShowToolTipsP(void) {return showtooltipsp;} + virtual bool ShowWallsP(void) {return showwallsp;} + virtual bool ShowApoplastsP(void) { return showapoplastsp;} + virtual bool ShowFluxesP(void) { return showfluxesp; } + virtual bool DynamicCellsP(void) { return dynamicscellsp; } + virtual void FitCanvasToWindow() {}; + virtual void FitLeafToCanvas() {}; + virtual bool HideCellsP(void) { return hidecellsp; } + virtual void clear(void) { + QList list = canvas.items(); + QList::Iterator it = list.begin(); + for (; it != list.end(); ++it) { + if ( *it ) + delete *it; } - Mesh &mesh; - - protected: - QGraphicsScene &canvas; - virtual xmlNode *XMLSettingsTree(void) const; + }; + virtual void XMLReadSettings(xmlNode *settings); + virtual double getFluxArrowsize(void) { return 10.;} + + void Save(const char *fname, const char *format, int sizex=640, int sizey=480); + void CutSAM(void); + + void Plot(int resize_stride=10); + + virtual void UserMessage(QString message, int timeout = 0) { + timeout = 0; // merely to obviate 'warning unused parameter' message + cerr << message.toAscii().constData() << endl; + } + Mesh &mesh; protected: - bool showcentersp; - bool showmeshp; - bool showbordercellp; - bool shownodenumbersp; - bool showcellnumbersp; - bool showcellsaxesp; - bool showcellstrainp; - bool movieframesp; - bool showboundaryonlyp; - bool showwallsp; - bool showapoplastsp; - bool showfluxesp; - bool dynamicscellsp; - bool showtooltipsp; - bool hidecellsp; + QGraphicsScene &canvas; + virtual xmlNode *XMLSettingsTree(void) const; + + protected: + bool showcentersp; + bool showmeshp; + bool showbordercellp; + bool shownodenumbersp; + bool showcellnumbersp; + bool showcellsaxesp; + bool showcellstrainp; + bool movieframesp; + bool showboundaryonlyp; + bool showwallsp; + bool showapoplastsp; + bool showfluxesp; + bool dynamicscellsp; + bool showtooltipsp; + bool hidecellsp; }; //#include @@ -132,3 +132,5 @@ class MainBase { #define INIT void MainBase::Init(char *leaffile) #endif + +/* finis */ diff --git a/src/matrix.cpp b/src/matrix.cpp --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -29,35 +29,32 @@ static const std::string _module_id("$Id$"); Matrix::Matrix(const Vector &c1, const Vector &c2, const Vector &c3) { - + Alloc(); mat[0][0]=c1.x; mat[0][1]=c2.x; mat[0][2]=c3.x; mat[1][0]=c1.y; mat[1][1]=c2.y; mat[1][2]=c3.y; mat[2][0]=c1.z; mat[2][1]=c2.z; mat[2][2]=c3.z; - - } -void Matrix::Alloc(void) { - +void Matrix::Alloc(void) +{ // constructor mat = new double*[3]; mat[0] = new double[9]; for (int i=1;i<3;i++) mat[i]=mat[i-1]+3; - } -Matrix::~Matrix() { - +Matrix::~Matrix() +{ // destructor delete[] mat[0]; delete[] mat; } -Matrix::Matrix(void) { - +Matrix::Matrix(void) +{ // constructor Alloc(); @@ -65,39 +62,37 @@ Matrix::Matrix(void) { for (int i=0;i<9;i++) { mat[0][i]=0.; } - } -Matrix::Matrix(const Matrix &source) { - +Matrix::Matrix(const Matrix &source) +{ // copy constructor Alloc(); - + for (int i=0;i<9;i++) { mat[0][i]=source.mat[0][i]; } - } -void Matrix::operator=(const Matrix &source) { - +void Matrix::operator=(const Matrix &source) +{ // assignment - + // don't assign to self if (this==&source) return; - + // copy for (int i=0;i<9;i++) mat[0][i]=source.mat[0][i]; - } -void Matrix::print(ostream *os) { - - *os << "{ { " << mat[0][0] << "," << mat[0][1] << "," << mat[0][2] << "},{" << mat[1][0] << "," << mat[1][1] << "," << mat[1][2] << "},{" << mat[2][0] << "," << mat[2][1] << "," << mat[2][2] << "} }"; - +void Matrix::print(ostream *os) +{ + *os << "{ { " << mat[0][0] << "," << mat[0][1] << "," << mat[0][2] + << "},{" << mat[1][0] << "," << mat[1][1] << "," << mat[1][2] + << "},{" << mat[2][0] << "," << mat[2][1] << "," << mat[2][2] << "} }"; } ostream &operator<<(ostream &os, Matrix &v) { @@ -106,33 +101,30 @@ ostream &operator<<(ostream &os, Matrix } -Vector Matrix::operator*(const Vector &v) const { - +Vector Matrix::operator*(const Vector &v) const +{ // matrix * vector Vector result; - + result.x = mat[0][0]*v.x+mat[0][1]*v.y+mat[0][2]*v.z; result.y = mat[1][0]*v.x+mat[1][1]*v.y+mat[1][2]*v.z; result.z = mat[2][0]*v.x+mat[2][1]*v.y+mat[2][2]*v.z; - + return result; - - } -bool Matrix::operator==(Matrix &m) const { - +bool Matrix::operator==(Matrix &m) const +{ for (int i=0;i<9;i++) { if ((mat[0][i]-m.mat[0][i])>TINY) return false; } return true; - } -double Matrix::Det(void) const { - +double Matrix::Det(void) const +{ return - mat[0][2]*mat[0][4]*mat[0][6] + mat[0][1]*mat[0][5]*mat[0][6] @@ -140,11 +132,11 @@ double Matrix::Det(void) const { - mat[0][0]*mat[0][5]*mat[0][7] - mat[0][1]*mat[0][3]*mat[0][8] + mat[0][0]*mat[0][4]*mat[0][8]; - } -Matrix Matrix::Inverse(void) const { - +Matrix Matrix::Inverse(void) const +{ + // return the Inverse of this matrix double rd=1./Det(); // Reciproce Det; Matrix inverse; @@ -157,18 +149,18 @@ Matrix Matrix::Inverse(void) const { inverse.mat[0][6]=rd*(-mat[0][4]*mat[0][6]+mat[0][3]*mat[0][7]); inverse.mat[0][7]=rd*( mat[0][1]*mat[0][6]-mat[0][0]*mat[0][7]); inverse.mat[0][8]=rd*(-mat[0][1]*mat[0][3]+mat[0][0]*mat[0][4]); - return inverse; } -void Matrix::Rot2D(double theta) { - +void Matrix::Rot2D(double theta) +{ // make this matrix a rotation matrix over theta // see http://mathworld.wolfram.com/RotationMatrix.html - + mat[0][0] = cos(theta); mat[0][1]=sin(theta); mat[1][0] = -sin(theta); mat[1][1]=cos(theta); mat[0][2] = mat[1][2] = mat[2][0] = mat[2][1] = mat[2][2] = 0.; +} -} +/* finis */ diff --git a/src/matrix.h b/src/matrix.h --- a/src/matrix.h +++ b/src/matrix.h @@ -30,7 +30,7 @@ class Vector; class Matrix { -public: + public: Matrix(const Vector &v1,const Vector &v2, const Vector &v3); // constructor Matrix(void); ~Matrix(); // destructor @@ -38,7 +38,7 @@ public: void print(ostream *os); Matrix(const Matrix &source); // copy constructor void operator=(const Matrix &source); // assignment operator - + Vector operator*(const Vector &v) const; // matrix * vector bool operator==(Matrix &v) const; // comparison double Det(void) const; // gives the "determinant" (| m |) of m @@ -47,7 +47,7 @@ public: // data members double **mat; -private: + private: void Alloc(void); }; @@ -55,3 +55,5 @@ private: ostream &operator<<(ostream &os, Matrix &v); #endif + +/* finis */ diff --git a/src/maxmin.h b/src/maxmin.h --- a/src/maxmin.h +++ b/src/maxmin.h @@ -33,3 +33,4 @@ inline double SIGN(double a, double b) { #endif +/* finis */ diff --git a/src/mesh.cpp b/src/mesh.cpp --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -58,103 +58,100 @@ void Mesh::AddNodeToCellAtIndex(Cell *c, void Mesh::AddNodeToCell(Cell *c, Node *n, Node *nb1, Node *nb2) { - + c->nodes.push_back( n ); n->owners.push_back( Neighbor(c, nb1, nb2 ) ); - } void Mesh::PerturbChem(int chemnum, double range) { - + for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { (*i)->chem[chemnum] += range*(RANDOM()-0.5); if ((*i)->chem[chemnum]<0.) (*i)->chem[chemnum]=0.; } - } void Mesh::CellFiles(const Vector ll, const Vector ur) { - + Cell *cell = RectangularCell(ll,ur,0.001); - + for (int c=0;cSetChemical(c,par.initval[c]); } - + cell->SetTargetArea(cell->CalcArea()); - + Vector axis(1,0,0); - + // divide rectangle a number of times for (int i=0;i<6;i++) { IncreaseCellCapacityIfNecessary(); - + vector current_cells = cells; for (vector::iterator j=current_cells.begin(); j!=current_cells.end();j++) { (*j)->DivideOverAxis(axis); } axis=axis.Perp2D(); - + } - + IncreaseCellCapacityIfNecessary(); - + axis=axis.Perp2D(); - + vector current_cells = cells; for (vector::iterator j=current_cells.begin(); - j!=current_cells.end();j++) { - (*j)->DivideOverAxis(axis); - } - - - double sum_l=0; int n_l=0; + j!=current_cells.end();j++) { + (*j)->DivideOverAxis(axis); + } + + + double sum_l=0; int n_l=0; for (list::const_iterator i=cell->nodes.begin(); i!=cell->nodes.end(); i++) { list::const_iterator nb=i; nb++; if (nb==cell->nodes.end()) nb=cell->nodes.begin(); - + double l = (**nb-**i).Norm(); - + sum_l += l; n_l++; - + } - - + + Node::target_length = sum_l/(double)n_l; // a bit more tension Node::target_length/=4.; - + SetBaseArea(); - } Cell *Mesh::RectangularCell(const Vector ll, const Vector ur, double rotation) { Cell *cell=AddCell(new Cell()); cell->m=this; - + Matrix rotmat; rotmat.Rot2D(rotation); // rotation over 0,0 - + Node *n1=AddNode(new Node(rotmat * ll)); Node *n2=AddNode(new Node(rotmat * Vector(ll.x, ur.y,0))); Node *n3=AddNode(new Node(rotmat * ur)); Node *n4=AddNode(new Node(rotmat * Vector(ur.x, ll.y,0))); - + n1->boundary=true; n2->boundary=true; n3->boundary=true; n4->boundary=true; //n1.fixed=n2.fixed=n3.fixed=n4.fixed=true; - + AddNodeToCell(cell, n4, n1, n3); @@ -162,7 +159,7 @@ Cell *Mesh::RectangularCell(const Vector AddNodeToCell(cell, n3, n4, n2); - + AddNodeToCell(cell, n2, n3, n1); @@ -170,8 +167,8 @@ Cell *Mesh::RectangularCell(const Vector AddNodeToCell(cell, n1, n2, n4); - - + + AddNodeToCell(boundary_polygon, n4, n1, n3); @@ -189,44 +186,44 @@ Cell *Mesh::RectangularCell(const Vector boundary_polygon->m = this; boundary_polygon->area = 0; - + cell->area = cell->CalcArea(); // target length is the length of the elements - + Node::target_length = ur.y-ll.y; // a bit more tension Node::target_length/=2; - + cell->SetIntegrals(); cell->ConstructNeighborList(); - + return cell; } Cell &Mesh::EllipticCell(double xc, double yc, double ra, double rb, int nnodes, double rotation) { - + int first_node=Node::nnodes; // nodes.reserve(nodes.size()+nnodes); - + //cells.push_back(Cell(xc,yc)); Cell *c=AddCell(new Cell(xc,yc)); c->m=this; - + for (int i=0;iboundary = true; - + } - + for (int i=0;im = this; boundary_polygon->area = 0; - + c->area = c->CalcArea(); // target length is the length of the elements - + Node::target_length = (2 * ((ra +rb)/2.) * sin (Pi/nnodes)); // a bit more tension Node::target_length/=2; //boundary_polygon = c; /* list::iterator nb; - for (list::iterator i=c->nodes.begin(); - i!=c->nodes.end(); - i++) { - - nb = i; nb++; - if (nb==c->nodes.end()) { + for (list::iterator i=c->nodes.begin(); + i!=c->nodes.end(); + i++) { + + nb = i; nb++; + if (nb==c->nodes.end()) { nb=c->nodes.begin(); - } - int next = *nb; - - nb = i; - if (nb==c->nodes.begin()) { + } + int next = *nb; + + nb = i; + if (nb==c->nodes.begin()) { nb=c->nodes.end(); - } - nb--; - int previous = *nb; - - - getNode(*i).cells.push_back( Neighbor(boundary_polygon->index, next, previous) ); - }*/ - + } + nb--; + int previous = *nb; + + + getNode(*i).cells.push_back( Neighbor(boundary_polygon->index, next, previous) ); + }*/ + c->SetIntegrals(); //c->ConstructNeighborList(); - + //c->ConstructWalls(); // initial cell has one wall with the outside world //c->walls.push_back( new Wall ( nodes.front(), nodes.front(), c, boundary_polygon )); - + c->at_boundary=true; - + return *c; - - } Cell &Mesh::LeafPrimordium(int nnodes, double pet_length) { - + // first leaf cell int first_node=Node::nnodes; - + Cell *circle=AddCell(new Cell(0,0)); circle->m=this; const double ra=10, rb=10; const double xc=0,yc=0; const double rotation=0; for (int i=0;i 1.25*Pi && angle < 1.75*Pi ) { - n.sam = true; - }*/ - + n.sam = true; + }*/ + AddNodeToCell(circle, n, nodes[first_node+ (nnodes+i-1)%nnodes], nodes[first_node+ (i + 1)%nnodes]); - + } - + boundary_polygon->m = this; boundary_polygon->area = 0; - + circle->area = circle->CalcArea(); // target length is the length of the elements - + Node::target_length = (2 * ((ra +rb)/2.) * sin (Pi/nnodes)); // a bit more tension Node::target_length/=2; circle->SetIntegrals(); - + //return c; circle->SetTargetArea(2*circle->Area()); - + // Petiole: starts at both sides of the circular cell // get position of the (n/4)'th and (3*(n/4))'th node. - + list::reverse_iterator it_n1=circle->nodes.rbegin(); for (int i=0;i::reverse_iterator it_n2=--circle->nodes.rend(); /* for (int i=0;iIndex() + (( (*it_n1)->Index() - (*it_n2)->Index() )-1+nnodes)%nnodes]); - - + + list::reverse_iterator i=it_n1; i++; for (; i!=it_n2; @@ -371,17 +366,17 @@ Cell &Mesh::LeafPrimordium(int nnodes, d *i, nodes[(*it_n2)->Index() + (((*i)->Index()-(*it_n2)->Index()) + 1)%nnodes], nodes[(*it_n2)->Index() + (((*i)->Index()-(*it_n2)->Index())-1+nnodes)%nnodes]); - + } - + AddNodeToCell(petiole, *it_n2, *it_n2 + 1, n3); - + (*it_n2)->boundary=true; - + //petiole.nodes.push_back(n3.Index()); //petiole.nodes.push_back(n4.Index()); AddNodeToCell(petiole, @@ -393,34 +388,34 @@ Cell &Mesh::LeafPrimordium(int nnodes, d n3, n1); - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << circle << endl; qDebug() << petiole << endl; - #endif - +#endif + AddNodeToCell(boundary_polygon, *it_n1, n4, *it_n2 + ((*it_n1-*it_n2)+1)%nnodes); // is this gonna work? - + (*it_n1)->boundary=true; - + for (int i=0;iowners.size()==1) { AddNodeToCell(boundary_polygon, nodes[first_node +i], nodes[first_node+ (nnodes+i-1)%nnodes], nodes[first_node+ (i + 1)%nnodes]); - + nodes[first_node+i]->boundary=true; } } - + AddNodeToCell(boundary_polygon, *it_n2, nodes[(nnodes+(*it_n2)->Index() - 1)%nnodes], n3); - + AddNodeToCell(boundary_polygon, n3, n2, @@ -446,20 +441,17 @@ Cell &Mesh::LeafPrimordium(int nnodes, d boundary_polygon->ConstructNeighborList(); circle->setCellVec(Vector(0,1,0)); - + return *circle; } /*Cell &Mesh::Box() { - - - -}*/ + }*/ // return bounding box of mesh void Mesh::BoundingBox(Vector &LowerLeft, Vector &UpperRight) { - + LowerLeft = **nodes.begin(); UpperRight = **nodes.begin(); for (vector::iterator c=nodes.begin(); @@ -478,12 +470,11 @@ void Mesh::BoundingBox(Vector &LowerLeft if ((*c)->z > UpperRight.z) UpperRight.z = (*c)->z; } - } double Mesh::Area(void) { - + double area=0; vector::iterator i=cells.begin(); while (i != cells.end()) { @@ -493,11 +484,11 @@ double Mesh::Area(void) { } void Mesh::SetBaseArea(void) { - + // Set base area to mean area. // This method is typically called during initiation, after // defining the first cell - Cell::BaseArea() = Area()/cells.size(); + Cell::BaseArea() = Area()/cells.size(); } // for optimization, we moved Displace to Mesh @@ -519,142 +510,142 @@ public: }; void Mesh::Clear(void) { - - // clear nodes - for (vector::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - delete *i; - } - - nodes.clear(); + + // clear nodes + for (vector::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + delete *i; + } + + nodes.clear(); + Node::nnodes=0; + + node_insertion_queue.clear(); + // Clear NodeSets + for (vector::iterator i=node_sets.begin(); + i!=node_sets.end(); + i++) { + delete *i; + } + + node_sets.clear(); + time = 0; + + // clear cells + + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + delete *i; + } + + cells.clear(); + Cell::NCells() = 0; + + delete boundary_polygon; + + // Clear walls + for (list::iterator i=walls.begin(); + i!=walls.end(); + i++) { + delete *i; + } + + walls.clear(); + WallBase::nwalls = 0; + //tmp_walls->clear(); + + shuffled_cells.clear(); + shuffled_nodes.clear(); + //Cell::ncells=0; + /* Cell::ClearNCells(); Node::nnodes=0; - - node_insertion_queue.clear(); - // Clear NodeSets - for (vector::iterator i=node_sets.begin(); - i!=node_sets.end(); - i++) { - delete *i; - } - - node_sets.clear(); - time = 0; - - // clear cells - - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - delete *i; - } - + cells.clear(); - Cell::NCells() = 0; - - delete boundary_polygon; - - // Clear walls - for (list::iterator i=walls.begin(); - i!=walls.end(); - i++) { - delete *i; - } - - walls.clear(); - WallBase::nwalls = 0; - //tmp_walls->clear(); - + nodes.clear(); shuffled_cells.clear(); shuffled_nodes.clear(); - //Cell::ncells=0; - /* Cell::ClearNCells(); - Node::nnodes=0; - - cells.clear(); - nodes.clear(); - shuffled_cells.clear(); - shuffled_nodes.clear(); - node_insertion_queue.empty(); - - cerr << "Meshed cleared: cells: " << cells.size() << ", nodes: " << nodes.size() << endl; - */ - - #ifdef QDEBUG - qDebug() << "cells.size() = " << cells.size() << endl; - qDebug << "walls.size() = " << walls.size() << endl; - qDebug << "nodes.size() = " << nodes.size() << endl; - #endif + node_insertion_queue.empty(); + + cerr << "Meshed cleared: cells: " << cells.size() << ", nodes: " << nodes.size() << endl; + */ + +#ifdef QDEBUG + qDebug() << "cells.size() = " << cells.size() << endl; + qDebug << "walls.size() = " << walls.size() << endl; + qDebug << "nodes.size() = " << nodes.size() << endl; +#endif } double Mesh::DisplaceNodes(void) { MyUrand r(shuffled_nodes.size()); random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r); - + double sum_dh=0; - + list delta_intgrl_list; - + for_each( node_sets.begin(), node_sets.end(), mem_fun( &NodeSet::ResetDone ) ); - + for (vector::const_iterator i=shuffled_nodes.begin(); i!=shuffled_nodes.end(); i++) { - + //int n=shuffled_nodes[*i]; Node &node(**i); - + // Do not allow displacement if fixed //if (node.fixed) continue; - + if (node.DeadP()) continue; - + // Attempt to move this cell in a random direction double rx=par.mc_stepsize*(RANDOM()-0.5); // was 100. double ry=par.mc_stepsize*(RANDOM()-0.5); - + // Uniform with a circle of radius par.mc_stepsize /* double r = RANDOM() * par.mc_stepsize; double th = RANDOM()*2*Pi; - + double rx = r * cos(th); double ry = r * sin(th); */ Vector new_p(node.x+rx,node.y+ry,0); Vector old_p(node.x,node.y,0); - + /* if (node.boundary && boundary_polygon->MoveSelfIntersectsP(n, new_p )) { // reject if move of boundary results in self intersection continue; }*/ - + if (node.node_set) { - // move each node set only once - if (!node.node_set->DoneP()) - node.node_set->AttemptMove(rx,ry); - + // move each node set only once + if (!node.node_set->DoneP()) + node.node_set->AttemptMove(rx,ry); + } else { - + // for all cells to which this node belongs: // calculate energy difference - + double area_dh=0.; double length_dh=0.; double bending_dh=0.; double cell_length_dh=0.; double alignment_dh=0.; - + double old_l1=0.,old_l2=0.,new_l1=0.,new_l2=0.; - + double sum_stiff=0.; double dh=0.; - + for (list::const_iterator cit=node.owners.begin(); cit!=node.owners.end(); cit++) { - + //Cell &c=m->getCell(cit->cell); //Cell &c=cit->cell->BoundaryPolP()?*boundary_polygon:*(cit->cell); Cell &c=*((Cell *)(cit->cell)); @@ -667,16 +658,16 @@ double Mesh::DisplaceNodes(void) { //cerr << "Rejecting due to self-intersection\n"; goto next_node; } - + // summing stiffnesses of cells. Move has to overcome this minimum required energy. sum_stiff += c.stiffness; // area - (area after displacement): see notes for derivation //Vector i_min_1 = m->getNode(cit->nb1); - + Vector i_min_1 = *(cit->nb1); - //Vector i_plus_1 = m->getNode(cit->nb2); + //Vector i_plus_1 = m->getNode(cit->nb2); Vector i_plus_1 = *(cit->nb2); - + // We must double the weights for the perimeter (otherwise they start bulging...) double w1, w2; @@ -688,7 +679,7 @@ double Mesh::DisplaceNodes(void) { #endif else w1 = 1; - + if (node.boundary && cit->nb2->boundary) #ifdef FLEMING w2 = par.rel_perimeter_stiffness; @@ -697,167 +688,167 @@ double Mesh::DisplaceNodes(void) { #endif else w2 = 1; - + //if (cit->cell>=0) { if (!cit->cell->BoundaryPolP()) { double delta_A = 0.5 * ( ( new_p.x - old_p.x ) * (i_min_1.y - i_plus_1.y) + ( new_p.y - old_p.y ) * ( i_plus_1.x - i_min_1.x ) ); - + area_dh += delta_A * (2 * c.target_area - 2 * c.area + delta_A); - + // cell length constraint // expensive and not always needed // so we check the value of lambda_celllength - + if (/* par.lambda_celllength */ cit->cell->lambda_celllength) { - + double delta_ix = (i_min_1.x + new_p.x) * (new_p.x * i_min_1.y- i_min_1.x * new_p.y) + (new_p.x + i_plus_1.x) * (i_plus_1.x * new_p.y- new_p.x * i_plus_1.y) - - + (i_min_1.x + old_p.x) * (old_p.x * i_min_1.y- i_min_1.x * old_p.y) - (old_p.x + i_plus_1.x) * (i_plus_1.x * old_p.y - old_p.x * i_plus_1.y); - - + + double delta_iy = (i_min_1.y + new_p.y) * (new_p.x * i_min_1.y- i_min_1.x * new_p.y) + (new_p.y + i_plus_1.y) * (i_plus_1.x * new_p.y- new_p.x * i_plus_1.y) - - + (i_min_1.y + old_p.y) * (old_p.x * i_min_1.y- i_min_1.x * old_p.y) - (old_p.y + i_plus_1.y) * (i_plus_1.x * old_p.y - old_p.x * i_plus_1.y); - - + + double delta_ixx = (new_p.x*new_p.x+ i_min_1.x*new_p.x+ i_min_1.x*i_min_1.x ) * (new_p.x*i_min_1.y - i_min_1.x*new_p.y) + - + (i_plus_1.x*i_plus_1.x+ new_p.x*i_plus_1.x+ new_p.x*new_p.x ) * (i_plus_1.x*new_p.y - new_p.x*i_plus_1.y) - - + (old_p.x*old_p.x+ i_min_1.x*old_p.x+ i_min_1.x*i_min_1.x ) * (old_p.x*i_min_1.y - i_min_1.x*old_p.y) - - + (i_plus_1.x*i_plus_1.x+ old_p.x*i_plus_1.x+ old_p.x*old_p.x ) * (i_plus_1.x*old_p.y - old_p.x*i_plus_1.y); - - + + double delta_ixy = (i_min_1.x*new_p.y- new_p.x*i_min_1.y)* (new_p.x*(2*new_p.y+i_min_1.y)+ i_min_1.x*(new_p.y+2*i_min_1.y)) + - + (new_p.x*i_plus_1.y- i_plus_1.x*new_p.y)* (i_plus_1.x*(2*i_plus_1.y+new_p.y)+ new_p.x*(i_plus_1.y+2*new_p.y)) - - + (i_min_1.x*old_p.y- old_p.x*i_min_1.y)* (old_p.x*(2*old_p.y+i_min_1.y)+ i_min_1.x*(old_p.y+2*i_min_1.y)) - - + (old_p.x*i_plus_1.y- i_plus_1.x*old_p.y)* (i_plus_1.x*(2*i_plus_1.y+old_p.y)+ old_p.x*(i_plus_1.y+2*old_p.y)); - - + + double delta_iyy = (new_p.x*i_min_1.y- i_min_1.x*new_p.y)* (new_p.y*new_p.y+ i_min_1.y*new_p.y+ i_min_1.y*i_min_1.y ) + - + (i_plus_1.x*new_p.y- new_p.x*i_plus_1.y)* (i_plus_1.y*i_plus_1.y+ new_p.y*i_plus_1.y+ new_p.y*new_p.y ) - - + (old_p.x*i_min_1.y- i_min_1.x*old_p.y)* (old_p.y*old_p.y+ i_min_1.y*old_p.y+ i_min_1.y*i_min_1.y ) - - + (i_plus_1.x*old_p.y- old_p.x*i_plus_1.y)* (i_plus_1.y*i_plus_1.y+ old_p.y*i_plus_1.y+ old_p.y*old_p.y ); - + delta_intgrl_list.push_back(DeltaIntgrl(delta_A,delta_ix,delta_iy,delta_ixx,delta_ixy,delta_iyy)); - + Vector old_axis; double old_celllength = c.Length(&old_axis); old_axis=old_axis.Normalised().Perp2D(); - + // calculate length after proposed update double intrx=(c.intgrl_x-delta_ix)/6.; double intry=(c.intgrl_y-delta_iy)/6.; double ixx=((c.intgrl_xx-delta_ixx)/12.)-(intrx*intrx)/(c.area-delta_A); double ixy=((c.intgrl_xy-delta_ixy)/24.)+(intrx*intry)/(c.area-delta_A); double iyy=((c.intgrl_yy-delta_iyy)/12.)-(intry*intry)/(c.area-delta_A); - + double rhs1=(ixx+iyy)/2., rhs2=sqrt( (ixx-iyy)*(ixx-iyy)+4*ixy*ixy )/2.; - + double lambda_b=rhs1+rhs2; - - + + double new_celllength=4*sqrt(lambda_b/(c.area-delta_A)); //cerr << "new_celllength = " << new_celllength << endl; //cerr << "target_length = " << c.target_length << endl; - + cell_length_dh += c.lambda_celllength * ( DSQR(c.target_length - new_celllength) - DSQR(c.target_length-old_celllength) ); - + Vector norm_long_axis(lambda_b - ixx, ixy, 0); norm_long_axis.Normalise(); - + double alignment_before = InnerProduct(old_axis, c.cellvec); double alignment_after = InnerProduct(norm_long_axis, c.cellvec); - + /* cerr << "Delta alignment = " << alignment_before - alignment_after << endl; cerr << "Old alignment is " << alignment_before << ", new alignment is " << alignment_after << endl; cerr << "Old axis is " << old_axis << ", new axis is " << norm_long_axis << endl; */ alignment_dh += alignment_before - alignment_after; - + /* cerr << "alignment_dh = " << alignment_dh << endl; cerr << "cellvec = " << c.cellvec << endl;*/ - + } else { // if we have no length constraint, still need to update area delta_intgrl_list.push_back(DeltaIntgrl(delta_A,0,0,0,0,0)); - + } - + old_l1=(old_p-i_min_1).Norm(); old_l2=(old_p-i_plus_1).Norm(); new_l1=(new_p-i_min_1).Norm(); new_l2=(new_p-i_plus_1).Norm(); - - - - + + + + static int count=0; // Insertion of nodes (cell wall yielding) if (!node.fixed) { @@ -877,26 +868,26 @@ double Mesh::DisplaceNodes(void) { - DSQR(old_l1)) + w2*(DSQR(new_l2) - DSQR(old_l2)); */ - - + + /* if (c.cellvec.ManhattanNorm()!=0) { - + // wall element length constraint double old_aniso1, old_aniso2; double new_aniso1, new_aniso2; - + // anisotropic expansion? old_aniso1 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((old_p-i_min_1), c.cellvec))/old_l1); old_aniso2 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((old_p-i_plus_1), c.cellvec))/old_l2); new_aniso1 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((new_p-i_min_1), c.cellvec))/new_l1); new_aniso2 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((new_p-i_plus_1), c.cellvec))/new_l2); - - + + length_dh += w1 * ( new_aniso1 * DSQR(new_l1 - Node::target_length) - old_aniso1 * DSQR(old_l1 - Node::target_length) ) + w2 * ( new_aniso2 * DSQR(new_l2 - Node::target_length) - old_aniso2 * DSQR(old_l2 - Node::target_length) ); - + } else { */ length_dh += 2*Node::target_length * ( w1*(old_l1 - new_l1) + @@ -905,14 +896,14 @@ double Mesh::DisplaceNodes(void) { - DSQR(old_l1)) + w2*(DSQR(new_l2) - DSQR(old_l2)); - - + + //} - - - + + + } - + // bending energy also holds for outer boundary // first implementation. Can probably be done more efficiently // calculate circumcenter radius (gives local curvature) @@ -925,47 +916,47 @@ double Mesh::DisplaceNodes(void) { &xc,&yc,&r1); CircumCircle(i_min_1.x, i_min_1.y, new_p.x, new_p.y, i_plus_1.x, i_plus_1.y, &xc,&yc, &r2); - - if (r1<0 || r2<0) { - MyWarning::warning("r1 = %f, r2 = %f",r1,r2); - } - bending_dh += DSQR(1/r2 - 1/r1); - //bending_dh += ( DSQR(1/r2) - DSQR(1/r1) ); - + + if (r1<0 || r2<0) { + MyWarning::warning("r1 = %f, r2 = %f",r1,r2); + } + bending_dh += DSQR(1/r2 - 1/r1); + //bending_dh += ( DSQR(1/r2) - DSQR(1/r1) ); + //cerr << "bending_dh = " << par.bend_lambda*bending_dh << endl; - + } /*cerr << "Bending = " << ( DSQR(1/r2) - DSQR(1/r1)) << endl; cerr << node.index << ": " << bending_dh << " (" << r1 << ", " << r2 << ") " << cit->nb1 << ", " << cit->nb2 << ")" << endl; }*/ /*else bending_dh += ( DSQR(1/r2) - DSQR(1/r1) );*/ - - + + /*if (cit->cell==-1) { cerr << node.index << ": " << bending_dh << " (" << r1 << ", " << r2 << ") " << cit->nb1 << ", " << cit->nb2 << ")" << endl; }*/ - + //bending_dh += r1 - r2; - + } - + //const double bend_lambda = 100000; //const double bend_lambda = 0; - + /* double dh = //(area_dev_sum_after - area_dev_sum_before) + area_dh + par.lambda_celllength * cell_length_dh + par.lambda_length * length_dh + par.bend_lambda * bending_dh + par.alignment_lambda * alignment_dh;*/ - + dh = //(area_dev_sum_after - area_dev_sum_before) + area_dh + cell_length_dh + par.lambda_length * length_dh + par.bend_lambda * bending_dh + par.alignment_lambda * alignment_dh; - + //cerr << "cell_length_dh = " << par.lambda_celllength * cell_length_dh << endl; //(length_constraint_after - length_constraint_before); - + if (node.fixed) { - + // search the fixed cell to which this node belongs // and displace these cells as a whole // WARNING: undefined things will happen for connected fixed cells... @@ -973,14 +964,14 @@ double Mesh::DisplaceNodes(void) { c!=node.owners.end(); c++) { if (!c->cell->BoundaryPolP() && c->cell->FixedP()) { - sum_dh+=c->cell->Displace(rx,ry,0); + sum_dh+=c->cell->Displace(rx,ry,0); } } } else { - - + + if (dh<-sum_stiff || RANDOM()::const_iterator di_it = delta_intgrl_list.begin(); for (list::iterator cit=node.owners.begin(); @@ -1000,45 +991,44 @@ double Mesh::DisplaceNodes(void) { di_it++; } } - + double old_nodex, old_nodey; - + old_nodex=node.x; old_nodey=node.y; - + node.x = new_p.x; node.y = new_p.y; - + for (list::iterator cit=node.owners.begin(); cit!=node.owners.end(); ( cit++) ) { - + /* if (cit->cell >= 0 && cells[cit->cell].SelfIntersect()) { node.x = old_nodex; node.y = old_nodey; goto next_node; - }*/ + }*/ } sum_dh += dh; } } } - next_node: - delta_intgrl_list.clear();//dA_list.clear(); - - } - - return sum_dh; - + next_node: + delta_intgrl_list.clear();//dA_list.clear(); + + } + + return sum_dh; } - + void Mesh::InsertNode(Edge &e) { // Construct a new node in the middle of the edge Node *new_node = AddNode( new Node ( ( *e.first + *e.second )/2 ) ); - + // if new node is inserted into the boundary // it will be part of the boundary, fixed, and source, too @@ -1046,10 +1036,10 @@ void Mesh::InsertNode(Edge &e) { new_node->boundary = (e.first->BoundaryP() && e.first->BoundaryP()) && ((findNextBoundaryNode(e.first))->Index() == e.second->Index()); new_node->fixed = e.first->fixed && e.second->fixed; new_node->sam = new_node->boundary && (e.first->sam || e.second->sam); - + // insert it into the boundary polygon; /* if (new_node->boundary) { - + // find the position of the first node in the boundary list::iterator ins_pos = find (boundary_polygon->nodes.begin(), @@ -1058,9 +1048,9 @@ void Mesh::InsertNode(Edge &e) { // ... second node comes before or after it ... if (*(++ins_pos!=boundary_polygon->nodes.end()? ins_pos:boundary_polygon->nodes.begin())!=e.second) { - + boundary_polygon->nodes.insert(((ins_pos--)!=boundary_polygon->nodes.begin()?ins_pos:(--boundary_polygon->nodes.end())), new_node); - + // .. set the neighbors of the new node ... // in this case e.second and e.first are inverted new_node->owners.push_back( Neighbor(boundary_polygon, e.second, e.first ) ); @@ -1069,17 +1059,17 @@ void Mesh::InsertNode(Edge &e) { // insert before second node, so leave ins_pos as it is, // that is incremented boundary_polygon->nodes.insert(ins_pos, new_node); - + // .. set the neighbors of the new node ... new_node->owners.push_back( Neighbor(boundary_polygon, e.first, e.second ) ); // cerr << "pushing back " << Neighbor(boundary_polygon->index, e.second, e.first ) << endl; } - + }*/ - - + + list owners; - + // push all cells owning the two nodes of the divided edges // onto a list copy(e.first->owners.begin(), @@ -1091,63 +1081,63 @@ void Mesh::InsertNode(Edge &e) { //copy(owners.begin(), owners.end(), ostream_iterator(cerr, " ")); //cerr << endl; - + // sort the nodes owners.sort( mem_fun_ref( &Neighbor::Cmp ) ); - + // extern ofstream debug_stream; - + // debug_stream << "Nodes " << e.first << " and " << e.second << endl; // copy(owners.begin(), owners.end(), ostream_iterator(debug_stream, " ")); // debug_stream << endl; - + // the duplicates in this list indicate cells owning this edge list::iterator c=owners.begin(); while (c!=owners.end()) { c=adjacent_find(c,owners.end(), neighbor_cell_eq); - - + + if (c!=owners.end()) { // else break; - + // debug_stream << "Cell " << c->cell << " owns Edge " << e << endl; - + //if (c->cell>=0) { //if (!c->cell->BoundaryPolP()) { - // find the position of the edge's first node in cell c... - list::iterator ins_pos = find - (c->cell->nodes.begin(), - c->cell->nodes.end(), - e.first); - // ... second node comes before or after it ... - - // XXXX probably this test is always false XXXX: No, works okay. - if (*(++ins_pos!=c->cell->nodes.end()? - ins_pos:c->cell->nodes.begin())!=e.second) { - c->cell->nodes.insert(((ins_pos--)!=c->cell->nodes.begin()?ins_pos:(--c->cell->nodes.end())), new_node); - //cells[c->cell].nodes.insert(--ins_pos, new_node->index); - // .. set the neighbors of the new node ... - // in this case e.second and e.first are inverted - // cerr << "Inverted\n"; - new_node->owners.push_back( Neighbor(c->cell, e.second, e.first ) ); - } else { - // insert before second node, so leave ins_pos as it is, - // that is incremented - c->cell->nodes.insert(ins_pos, new_node); - // .. set the neighbors of the new node ... - // cerr << "Not inverted\n"; - new_node->owners.push_back( Neighbor(c->cell, e.first, e.second ) ); - } - - // redo the neighbors: - //} - + // find the position of the edge's first node in cell c... + list::iterator ins_pos = find + (c->cell->nodes.begin(), + c->cell->nodes.end(), + e.first); + // ... second node comes before or after it ... + + // XXXX probably this test is always false XXXX: No, works okay. + if (*(++ins_pos!=c->cell->nodes.end()? + ins_pos:c->cell->nodes.begin())!=e.second) { + c->cell->nodes.insert(((ins_pos--)!=c->cell->nodes.begin()?ins_pos:(--c->cell->nodes.end())), new_node); + //cells[c->cell].nodes.insert(--ins_pos, new_node->index); + // .. set the neighbors of the new node ... + // in this case e.second and e.first are inverted + // cerr << "Inverted\n"; + new_node->owners.push_back( Neighbor(c->cell, e.second, e.first ) ); + } else { + // insert before second node, so leave ins_pos as it is, + // that is incremented + c->cell->nodes.insert(ins_pos, new_node); + // .. set the neighbors of the new node ... + // cerr << "Not inverted\n"; + new_node->owners.push_back( Neighbor(c->cell, e.first, e.second ) ); + } + + // redo the neighbors: + //} + // - find cell c among owners of Node e.first list::iterator cpos= find_if( e.first->owners.begin(), e.first->owners.end(), bind2nd( mem_fun_ref(&Neighbor::CellEquals), c->cell->Index()) ); - + // - correct the record if (cpos->nb1 == e.second) { cpos->nb1 = new_node; @@ -1155,13 +1145,13 @@ void Mesh::InsertNode(Edge &e) { if (cpos->nb2 == e.second) { cpos->nb2 = new_node; } - + // - same for Node e.second cpos= find_if( e.second->owners.begin(), e.second->owners.end(), bind2nd( mem_fun_ref(&Neighbor::CellEquals), c->cell->Index()) ); - + // - correct the record if (cpos->nb1 == e.first) { cpos->nb1 = new_node; @@ -1169,8 +1159,8 @@ void Mesh::InsertNode(Edge &e) { if (cpos->nb2 == e.first) { cpos->nb2 = new_node; } - - + + } else break; c++; } @@ -1188,17 +1178,16 @@ void Mesh::InsertNode(Edge &e) { c++; } // debug_stream.flush(); - } /* - Calculate circumcircle of triangle (x1,y1), (x2,y2), (x3,y3) - The circumcircle centre is returned in (xc,yc) and the radius in r - NOTE: A point on the edge is inside the circumcircle + Calculate circumcircle of triangle (x1,y1), (x2,y2), (x3,y3) + The circumcircle centre is returned in (xc,yc) and the radius in r + NOTE: A point on the edge is inside the circumcircle */ void Mesh::CircumCircle(double x1,double y1,double x2,double y2,double x3,double y3, - double *xc,double *yc,double *r) + double *xc,double *yc,double *r) { double m1,m2,mx1,mx2,my1,my2; double dx,dy,rsqr; @@ -1238,41 +1227,39 @@ void Mesh::CircumCircle(double x1,double return; // Suggested // return((drsqr <= rsqr + EPSILON) ? TRUE : FALSE); - } - + // // return the total amount of chemical "ch" in the leaf double Mesh::SumChemical(int ch) { - + double sum=0.; for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { - + sum+=(*i)->chem[ch]; } return sum; - } void Mesh::CleanUpCellNodeLists(void) { - + typedef vector ::iterator> CellItVect; - + CellItVect cellstoberemoved; vector cellind; - + // Start of by removing all stale walls. //DeleteLooseWalls(); // collect all dead cells that need to be removed from the simulation for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { - + if ((*i)->DeadP()) { // collect the iterators cellstoberemoved.push_back(i); @@ -1301,12 +1288,12 @@ void Mesh::CleanUpCellNodeLists(void) { } } boundary_polygon->walls.remove(0); - + // Renumber cells; this is most efficient if the list of dead cell indices is sorted sort(cellind.begin(),cellind.end()); - - + + // Reindexing of Cells for (vector::reverse_iterator j=cellind.rbegin(); j!=cellind.rend(); @@ -1315,14 +1302,14 @@ void Mesh::CleanUpCellNodeLists(void) { for (vector::reverse_iterator i=cells.rbegin(); i!=cells.rend(); i++) { - + if (*j < (*i)->index) (*i)->index--; - + } - + } - + // Actual deleting of Cells // We must delete in reverse order, otherwise the iterators become redefined for ( CellItVect::reverse_iterator i=cellstoberemoved.rbegin(); @@ -1331,29 +1318,29 @@ void Mesh::CleanUpCellNodeLists(void) { Cell::NCells()--; cells.erase(*i); } - - + + // same for nodes typedef vector ::iterator> NodeItVect; - + NodeItVect nodestoberemoved; vector nodeindlist; - + // collect iterators and indices of dead nodes for (vector::iterator i=nodes.begin(); i!=nodes.end(); i++) { - + if ((*i)->DeadP()) { nodestoberemoved.push_back( i ); nodeindlist.push_back((*i)->index); - + } } // sort the list of dead nodes for renumbering sort(nodeindlist.begin(),nodeindlist.end()); - + // Reindicing of Nodes for (vector::reverse_iterator j=nodeindlist.rbegin(); @@ -1363,17 +1350,17 @@ void Mesh::CleanUpCellNodeLists(void) { for (vector::reverse_iterator i=nodes.rbegin(); i!=nodes.rend(); i++) { - + if (*j < (*i)->index) { (*i)->index--; } - - + + } - + } - + // Actual deleting of nodes // We must delete in reverse order, otherwise the iterators become redefined for ( NodeItVect::reverse_iterator i=nodestoberemoved.rbegin(); @@ -1382,9 +1369,9 @@ void Mesh::CleanUpCellNodeLists(void) { Node::nnodes--; nodes.erase(*i); } - - - + + + for (list::iterator w=walls.begin(); w!=walls.end(); w++) { @@ -1394,19 +1381,19 @@ void Mesh::CleanUpCellNodeLists(void) { *w = 0; } } - + walls.remove( 0 ); - - + + // Clean up all intercellular connections and redo everything for (vector::iterator i=nodes.begin(); i!=nodes.end(); i++) { - + (*i)->owners.clear(); } - + for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { @@ -1416,63 +1403,61 @@ void Mesh::CleanUpCellNodeLists(void) { } boundary_polygon->ConstructConnections(); - + /* for (list::iterator w=walls.begin(); - w!=walls.end(); - w++) { - delete *w; - } - - walls.clear(); - cerr << "Cleared walls\n"; - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - - (*i)->ConstructWalls(); - } + w!=walls.end(); + w++) { + delete *w; + } + + walls.clear(); + cerr << "Cleared walls\n"; + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + + (*i)->ConstructWalls(); + } */ - + // remake shuffled_nodes and shuffled cells shuffled_nodes.clear(); shuffled_nodes = nodes; - + shuffled_cells.clear(); shuffled_cells = cells; - } void Mesh::CutAwayBelowLine( Vector startpoint, Vector endpoint) { - + // Kills all cells below the line startpoint -> endpoint - + Vector perp = (endpoint-startpoint).Perp2D().Normalised(); - - #ifdef QDEBUG + +#ifdef QDEBUG qDebug() << "Before Apoptose" << endl; - #endif +#endif TestIllegalWalls(); for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { - + // do some vector geometry to check whether the cell is below the cutting line Vector cellvec = ((*i)->Centroid()-startpoint); - + if ( InnerProduct(perp, cellvec) < 0 ) { // remove those cells (*i)->Apoptose(); } } - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Before CleanUpCellNodeLists" << endl; - #endif +#endif TestIllegalWalls(); - + CleanUpCellNodeLists(); - } void Mesh::CutAwaySAM(void) { @@ -1480,18 +1465,16 @@ void Mesh::CutAwaySAM(void) { for (vector::iterator i=cells.begin(); i!=cells.end(); i++) { - + if( (*i)->Boundary() == Cell::SAM ) { - (*i)->Apoptose(); + (*i)->Apoptose(); } } TestIllegalWalls(); - + CleanUpCellNodeLists(); - - } void Mesh::TestIllegalWalls(void) { @@ -1499,12 +1482,11 @@ void Mesh::TestIllegalWalls(void) { w!=walls.end(); w++) { if ((*w)->IllegalP() ) { - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Wall " << **w << " is illegal." << endl; - #endif +#endif } } - } @@ -1512,7 +1494,7 @@ void Mesh::TestIllegalWalls(void) { class node_owners_eq : public unary_function { int no; public: - + explicit node_owners_eq(int nn) { no=nn; } bool operator() (const Node &n) const { @@ -1521,12 +1503,11 @@ public: else return false; } - }; void Mesh::RepairBoundaryPolygon(void) { - + // After serious manipulations (e.g. after cutting part off the // leaf) repair the boundary polygon. It assumes the cut line has // already been marked "boundary" and the original boundary marks @@ -1535,7 +1516,7 @@ void Mesh::RepairBoundaryPolygon(void) { // So, this function just puts boundary nodes into the boundary // polygon in the right order; it cannot detect boundaries from // scratch. - + Node *boundary_node=0, *next_boundary_node=0, *internal_node; set original_boundary_nodes, repaired_boundary_nodes; vector difference; // set difference result @@ -1567,7 +1548,7 @@ void Mesh::RepairBoundaryPolygon(void) { node->owners.erase(boundary_ref_pos); // remove the reference } } - + // Step 3: Search for the first boundary node. We reconstruct the // boundary polygon by moving along the boundary nodes until we've // encircled the polygon. Since manually adding nodes may have @@ -1624,7 +1605,7 @@ void Mesh::RepairBoundaryPolygon(void) { } boundary_polygon->walls.remove(0); boundary_polygon->ConstructNeighborList(); - + #ifdef QDEBUG qDebug() << "Repaired Boundary Polygon node indices: "; foreach (Node* node, boundary_polygon->nodes){ @@ -1632,7 +1613,7 @@ void Mesh::RepairBoundaryPolygon(void) { } qDebug() << endl ; - #ifdef _undefined_ +#ifdef _undefined_ qDebug() << "NODES:" << endl; foreach(Node* node, nodes) { qDebug() << *node; @@ -1650,9 +1631,8 @@ void Mesh::RepairBoundaryPolygon(void) { qDebug() << *cell; } qDebug() << endl; - #endif #endif - +#endif } @@ -1677,45 +1657,45 @@ Node* Mesh::findNextBoundaryNode(Node* b vector::iterator itt = neighborIds.begin(); vector *>::iterator it = nodeOwners.begin(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Boundary node: " << boundary_node->Index() << " is owned by the following cells: "; foreach (int i, boundary_node_owners){ qDebug() << i << " "; } qDebug() << endl; - #endif +#endif for (; it < nodeOwners.end(); it++, itt++) { intersection.clear(); set_intersection(boundary_node_owners.begin(), boundary_node_owners.end(), (*it)->begin(), (*it)->end(), back_inserter(intersection)); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "The intersection of the boundary node(" << boundary_node->Index() << ") owners and its 2nd neighbor(" << *itt << ") owners is: "; foreach (int i, intersection){ qDebug() << i << " "; } qDebug() << endl; - #endif +#endif if (intersection.size() == 1){ found_next_boundary_node = true; vector::iterator next_boundary_node_it = find_if (nodes.begin(), nodes.end(), bind2nd(mem_fun(&Node::IndexEquals), *itt)); next_boundary_node = *next_boundary_node_it; // defeference the itterator to get to the node pointer - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "The Current boundary node is: " << boundary_node->Index() << ". The Next boundary node is: " << *itt << ((next_boundary_node->Marked()) ? " Marked" : " Unmarked") << endl << endl; - #endif +#endif break; } } - #ifdef QDEBUG +#ifdef QDEBUG if (!found_next_boundary_node) { qDebug() << "OOPS! Didn't find the next boundrary node!" << endl; } - #endif +#endif return next_boundary_node; } @@ -1741,21 +1721,20 @@ void Mesh::Rotate(double angle, Vector c Matrix rotmat; rotmat.Rot2D(angle); - + for (vector::iterator n=nodes.begin(); n!=nodes.end(); n++) { (*n)->setPos ( rotmat * ( *(*n) - center ) + center ); - + } } void Mesh::PrintWallList( void ) { - - transform ( walls.begin(), walls.end(), ostream_iterator(cerr, "\n"), deref_ptr ); - + + transform ( walls.begin(), walls.end(), ostream_iterator(cerr, "\n"), deref_ptr ); } #include @@ -1763,84 +1742,83 @@ void Mesh::PrintWallList( void ) { #include "rungekutta.h" class SolveMesh : public RungeKutta { - + private: SolveMesh(void); - + public: - SolveMesh(Mesh *m_) { - - m = m_; - - kmax=0; - kount=0; - xp=0; yp=0; dxsav=0; - - - } - + SolveMesh(Mesh *m_) { + + m = m_; + + kmax=0; + kount=0; + xp=0; yp=0; dxsav=0; + + + } + protected: virtual void derivs(double x, double *y, double *dydx) { - + // set mesh with new values given by ODESolver // (we must do this, because only mesh knows the connections // between the variables) - + m->setValues(x,y); m->Derivatives(dydx); - + /*static int c=0; - QString fname("derivs%1.dat"); - - ofstream of(fname.arg(++c).ascii()); - - for (int i=0;iNEqs();i++) { - of << x << " " << dxdy[i] << endl; - } - of.close(); + QString fname("derivs%1.dat"); + + ofstream of(fname.arg(++c).ascii()); + + for (int i=0;iNEqs();i++) { + of << x << " " << dxdy[i] << endl; + } + of.close(); */ - + //cerr << "Calculated derivatives at " << x << "\n"; } - + private: Mesh *m; int kmax,kount; double *xp,**yp,dxsav; bool monitor_window; }; - + void Mesh::ReactDiffuse(double delta_t) { - + // Set Lengths of Walls for_each ( walls.begin(), walls.end(), mem_fun( &Wall::SetLength ) ); - + static SolveMesh *solver = new SolveMesh(this); - + int nok, nbad, nvar; double *ystart = getValues(&nvar); - + solver->odeint(ystart, nvar, getTime(), getTime() + delta_t, par.ode_accuracy, par.dt, 1e-10, &nok, &nbad); - + setTime(getTime()+delta_t); setValues(getTime(),ystart); - } Vector Mesh::FirstConcMoment(int chem) { - + Vector moment; for (vector::const_iterator c=cells.begin(); c!=cells.end(); c++) { - + moment += (*c)->Chemical(chem) * (*c)->Centroid(); - + } return moment / (double)cells.size(); @@ -1854,9 +1832,9 @@ Vector Mesh::FirstConcMoment(int chem) { void Mesh::DeleteLooseWalls(void) { list::iterator w=walls.begin(); - + while (w!=walls.end()) { - + // if both cells of the wall are dead, remove the wall if ((*w)->C1()->DeadP() || (*w)->C2()->DeadP()) { if ((*w)->C1()->DeadP() && (*w)->C2()->DeadP()) { @@ -1872,83 +1850,79 @@ void Mesh::DeleteLooseWalls(void) { } else { w++; } - + } - } /*void Mesh::FitLeafToCanvas(double width, double height) { Vector bbll,bbur; BoundingBox(bbll,bbur); - + double scale_x = width/(bbur.x-bbll.x); double scale_y = height/(bbur.y-bbll.y); - + double factor = scale_x &clean_chem) { - - if (clean_chem.size()!=(unsigned)Cell::NChem()) { - throw "Run time error in Mesh::CleanChemicals: size of clean_chem should be equal to Cell::NChem()"; - } - for (vector::iterator c=cells.begin(); - c!=cells.end(); - c++) { - - for (int i=0;iSetChemical(i,clean_chem[i]); - } - (*c)->SetNewChemToChem(); - - } - - + + if (clean_chem.size()!=(unsigned)Cell::NChem()) { + throw "Run time error in Mesh::CleanChemicals: size of clean_chem should be equal to Cell::NChem()"; + } + for (vector::iterator c=cells.begin(); + c!=cells.end(); + c++) { + + for (int i=0;iSetChemical(i,clean_chem[i]); + } + (*c)->SetNewChemToChem(); + + } } void Mesh::CleanTransporters(const vector &clean_transporters) { - - if (clean_transporters.size()!=(unsigned)Cell::NChem()) { - throw "Run time error in Mesh::CleanTransporters: size ofclean_transporters should be equal to Cell::NChem()"; - } - - - // clean transporters - for (list::iterator w=walls.begin(); - w!=walls.end(); - w++) { - - for (int i=0;isetTransporters1(i,clean_transporters[i]); (*w)->setNewTransporters1(i,clean_transporters[i]); - (*w)->setTransporters2(i,clean_transporters[i]); (*w)->setNewTransporters2(i,clean_transporters[i]); - } - } - + + if (clean_transporters.size()!=(unsigned)Cell::NChem()) { + throw "Run time error in Mesh::CleanTransporters: size ofclean_transporters should be equal to Cell::NChem()"; + } + + + // clean transporters + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + + for (int i=0;isetTransporters1(i,clean_transporters[i]); (*w)->setNewTransporters1(i,clean_transporters[i]); + (*w)->setTransporters2(i,clean_transporters[i]); (*w)->setNewTransporters2(i,clean_transporters[i]); + } + } } void Mesh::RandomizeChemicals(const vector &max_chem, const vector &max_transporters) { - + if (max_chem.size()!=(unsigned)Cell::NChem() || max_transporters.size()!=(unsigned)Cell::NChem()) { throw "Run time error in Mesh::CleanChemicals: size of max_chem and max_transporters should be equal to Cell::NChem()"; } - + for (vector::iterator c=cells.begin(); c!=cells.end(); c++) { - + for (int i=0;iSetChemical(i,max_chem[i]*RANDOM()); } @@ -1960,33 +1934,32 @@ void Mesh::RandomizeChemicals(const vect for (list::iterator w=walls.begin(); w!=walls.end(); w++) { - + for (int i=0;isetTransporters1(i,max_transporters[i] * RANDOM()); (*w)->setNewTransporters1(i, (*w)->Transporters1(i) ); (*w)->setTransporters2(i,max_transporters[i] * RANDOM()); (*w)->setNewTransporters2(i, (*w)->Transporters1(i) ); } } - } //!\brief Calculates a vector with derivatives of all variables, which // we can pass to an ODESolver. void Mesh::Derivatives(double *derivs) { - + int nwalls = walls.size(); int ncells = cells.size(); int nchems = Cell::NChem(); - + // two eqs per chemical for each walls, and one eq per chemical for each cell // This is for generality. For a specific model you may optimize // this by removing superfluous (empty) equations. int neqs = 2 * nwalls * nchems + ncells * nchems; - + //static double *derivs = 0; // derivs is allocated by RungeKutta class. for (int i=0;iCellDynamics(*c, &(derivs[i])); - i+=nchems; + plugin->CellDynamics(*c, &(derivs[i])); + i+=nchems; } - + for (list::iterator w=walls.begin(); w!=walls.end(); w++) { - // (*wr)(*w, &(derivs[i]), &(derivs[i+nchems])); - plugin->WallDynamics(*w, &(derivs[i]), &(derivs[i+nchems])); + // (*wr)(*w, &(derivs[i]), &(derivs[i+nchems])); + plugin->WallDynamics(*w, &(derivs[i]), &(derivs[i+nchems])); // Transport function adds to derivatives of cell chemicals - double *dchem_c1 = &(derivs[(*w)->c1->Index() * nchems]); - double *dchem_c2 = &(derivs[(*w)->c2->Index() * nchems]); - //plugin->CelltoCellTransport(*w, &(derivs[(*w)->c1->Index() * nchems]), - // &(derivs[(*w)->c2->Index() * nchems])); - // quick fix: dummy values to prevent end user from writing into outer space and causing a crash :-) - // start here if you want to implement chemical input/output into environment over boundaries - double dummy1, dummy2; - if ((*w)->c1->Index()<0) { // tests if c1 is the boundary pol - dchem_c1 = &dummy1; - } - if ((*w)->c2->Index()<0) { - dchem_c2 = &dummy2; - } - plugin->CelltoCellTransport(*w, dchem_c1, dchem_c2); - - //(*tf)(*w, &(derivs[(*w)->c1->Index() * nchems]), - //&(derivs[(*w)->c2->Index() * nchems] ) ); + double *dchem_c1 = &(derivs[(*w)->c1->Index() * nchems]); + double *dchem_c2 = &(derivs[(*w)->c2->Index() * nchems]); + //plugin->CelltoCellTransport(*w, &(derivs[(*w)->c1->Index() * nchems]), + // &(derivs[(*w)->c2->Index() * nchems])); + // quick fix: dummy values to prevent end user from writing into outer space and causing a crash :-) + // start here if you want to implement chemical input/output into environment over boundaries + double dummy1, dummy2; + if ((*w)->c1->Index()<0) { // tests if c1 is the boundary pol + dchem_c1 = &dummy1; + } + if ((*w)->c2->Index()<0) { + dchem_c2 = &dummy2; + } + plugin->CelltoCellTransport(*w, dchem_c1, dchem_c2); + + //(*tf)(*w, &(derivs[(*w)->c1->Index() * nchems]), + //&(derivs[(*w)->c2->Index() * nchems] ) ); i+=2*nchems; } - - } void Mesh::setValues(double x, double *y) { @@ -2033,12 +2004,12 @@ void Mesh::setValues(double x, double *y //int nwalls = walls.size(); //int ncells = cells.size(); int nchems = Cell::NChem(); - + // two eqs per chemical for each walls, and one eq per chemical for each cell // This is for generality. For a specific model you may optimize // this by removing superfluous (empty) equations. //int neqs = 2 * nwalls * nchems + ncells * nchems; - + // Layout of derivatives: cells [ chem1 ... chem n] walls [ [ w1(chem 1) ... w1(chem n) ] [ w2(chem 1) ... w2(chem n) ] ] int i=0; @@ -2055,16 +2026,16 @@ void Mesh::setValues(double x, double *y } i+=nchems; } - + for (list::iterator w=walls.begin(); w!=walls.end(); w++) { - + for (int ch=0;chsetTransporters1(ch,y[i+ch]); } i+=nchems; - + for (int ch=0;chsetTransporters2(ch,y[i+ch]); } @@ -2076,23 +2047,23 @@ void Mesh::setValues(double x, double *y } double *Mesh::getValues(int *neqs) { - + int nwalls = walls.size(); int ncells = cells.size(); int nchems = Cell::NChem(); - + // two eqs per chemical for each wall, and one eq per chemical for each cell // This is for generality. For a specific model you may optimize // this by removing superfluous (empty) equations. (*neqs) = 2 * nwalls * nchems + ncells * nchems; - + // Layout of derivatives: cells [ chem1 ... chem n] walls [ [ w1(chem 1) ... w1(chem n) ] [ w2(chem 1) ... w2(chem n) ] ] static double *values = 0; if (values!=0) { delete[] values; } - + values = new double[*neqs]; - + int i=0; for (vector::iterator c=cells.begin(); c!=cells.end(); @@ -2102,16 +2073,16 @@ double *Mesh::getValues(int *neqs) { } i+=nchems; } - + for (list::iterator w=walls.begin(); w!=walls.end(); w++) { - + for (int ch=0;chTransporters1(ch); } i+=nchems; - + for (int ch=0;chTransporters2(ch); } @@ -2123,22 +2094,21 @@ double *Mesh::getValues(int *neqs) { } void Mesh::DrawNodes(QGraphicsScene *c) const { - + for (vector::const_iterator n=nodes.begin(); n!=nodes.end(); n++) { - + Node *i=*n; - + NodeItem *item = new NodeItem ( &(*i), c ); item->setColor(); - + item->setZValue(5); item->show(); item ->setPos(((Cell::offset[0]+i->x)*Cell::factor), ((Cell::offset[1]+i->y)*Cell::factor) ); } - } /*! Returns the sum of protein "ch" of a cycling protein in cells and walls */ @@ -2159,19 +2129,18 @@ double Mesh::CalcProtCellsWalls(int ch) for (vector::const_iterator c=cells.begin(); c!=cells.end(); c++) { - + sum_prot += (*c)->Chemical(ch); } - + return sum_prot; - } void Mesh::SettoInitVals(void) { - + vector clean_chem(Cell::NChem()); vector clean_transporters(Cell::NChem()); - + for (int i=0;i Mesh::VertexAngles(void) { - QVector angles; - for (vector::const_iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - if ((*n)->Value()>2 && !(*n)->BoundaryP() ) { - angles+=(*n)->NeighbourAngles(); - } - } - return angles; + QVector angles; + for (vector::const_iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + if ((*n)->Value()>2 && !(*n)->BoundaryP() ) { + angles+=(*n)->NeighbourAngles(); + } + } + return angles; } QVector< QPair > Mesh::VertexAnglesValues(void) { - QVector< QPair > anglesvalues; - for (vector::const_iterator n=nodes.begin(); - n!=nodes.end(); - n++) { - if ((*n)->Value()>2 && !(*n)->BoundaryP() ) { - - QVector angles = (*n)->NeighbourAngles(); - int value_vertex = angles.size(); - for (QVector::ConstIterator i=angles.begin(); - i!=angles.end(); - i++) { - - anglesvalues += QPair< qreal, int > (*i, value_vertex); - } - } - } - return anglesvalues; + QVector< QPair > anglesvalues; + for (vector::const_iterator n=nodes.begin(); + n!=nodes.end(); + n++) { + if ((*n)->Value()>2 && !(*n)->BoundaryP() ) { + + QVector angles = (*n)->NeighbourAngles(); + int value_vertex = angles.size(); + for (QVector::ConstIterator i=angles.begin(); + i!=angles.end(); + i++) { + + anglesvalues += QPair< qreal, int > (*i, value_vertex); + } + } + } + return anglesvalues; } void Mesh::Clean(void) { - #ifdef QDEBUG - qDebug() << "Freeing nodes" << endl; - #endif - for (vector::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - delete *i; - } - nodes.clear(); - Node::nnodes=0; - - #ifdef QDEBUG - qDebug() << "Freeing node sets" << endl; - #endif - for (vector::iterator i=node_sets.begin(); - i!=node_sets.end(); - i++) { - delete *i; - } - node_sets.clear(); - - - #ifdef QDEBUG - qDebug() << "Freeing cells" << endl; - #endif - //CellsStaticDatamembers *old_static_data_mem = Cell::GetStaticDataMemberPointer(); - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - delete *i; - } - //Cell::static_data_members = old_static_data_mem; - - cells.clear(); - Cell::NCells()=0; - - delete boundary_polygon; // (already deleted during cleaning of cells?) - - #ifdef QDEBUG - qDebug() << "Freeing walls" << endl; - #endif - for (list::iterator i=walls.begin(); - i!=walls.end(); - i++) { - delete *i; - } - walls.clear(); - Wall::nwalls=0; - - node_insertion_queue.clear(); - shuffled_nodes.clear(); - shuffled_cells.clear(); - time = 0.0; +#ifdef QDEBUG + qDebug() << "Freeing nodes" << endl; +#endif + for (vector::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + delete *i; + } + nodes.clear(); + Node::nnodes=0; + +#ifdef QDEBUG + qDebug() << "Freeing node sets" << endl; +#endif + for (vector::iterator i=node_sets.begin(); + i!=node_sets.end(); + i++) { + delete *i; + } + node_sets.clear(); + + +#ifdef QDEBUG + qDebug() << "Freeing cells" << endl; +#endif + //CellsStaticDatamembers *old_static_data_mem = Cell::GetStaticDataMemberPointer(); + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + delete *i; + } + //Cell::static_data_members = old_static_data_mem; + + cells.clear(); + Cell::NCells()=0; + + delete boundary_polygon; // (already deleted during cleaning of cells?) + +#ifdef QDEBUG + qDebug() << "Freeing walls" << endl; +#endif + for (list::iterator i=walls.begin(); + i!=walls.end(); + i++) { + delete *i; + } + walls.clear(); + Wall::nwalls=0; + + node_insertion_queue.clear(); + shuffled_nodes.clear(); + shuffled_cells.clear(); + time = 0.0; } void Mesh::StandardInit(void) { - boundary_polygon = new BoundaryPolygon(); - Cell &circle=CircularCell(0,0,10,10); - - circle.SetTargetArea(circle.CalcArea()); - circle.SetTargetLength(par.target_length); - circle.SetLambdaLength(par.lambda_celllength); - SetBaseArea(); - // clean up chemicals - for (int c=0; c > class unique_queue : public queue { - -public: - typedef typename C::value_type value_type; - // reimplements push: reject element if it exists already - void push(const value_type &x) { - if (find (queue::c.begin(),queue::c.end(),x)==queue::c.end()) { - queue::c.push_back(x); - } - } - void clear(void) { - queue::c.clear(); - } + + public: + typedef typename C::value_type value_type; + // reimplements push: reject element if it exists already + void push(const value_type &x) { + if (find (queue::c.begin(),queue::c.end(),x)==queue::c.end()) { + queue::c.push_back(x); + } + } + void clear(void) { + queue::c.clear(); + } }; template P& deref_ptr ( P *obj) { return *obj; } class Mesh { - - friend class Cell; - friend class Node; - friend class FigureEditor; - -public: - Mesh(void) { - // Make sure the reserved value is large enough if a cell is added - // in "Divide" when the capacity is insufficient, "cells" might be - // relocated including the current Cell (i.e. the value of *this) - // calling "Mesh::IncreaseCapacityIfNecessary" (from another - // object than Cell, e.g. Mesh) before entering Divide will solve - // this issue (solved now). - cells.reserve(2); - nodes.reserve(500); - - time = 0.; - plugin = 0; - }; - ~Mesh(void) { - delete boundary_polygon; - }; - - void Clean(void); - Cell &EllipticCell(double xc, double yc, double ra, double rb, int nnodes=10, double rotation=0); - Cell &CircularCell(double xc, double yc, double r, int nnodes=10) { - return EllipticCell(xc, yc, r, r, nnodes, 0); - } - Cell &LeafPrimordium(int n, double pet_length); - Cell &LeafPrimordium2(int n); - Cell *RectangularCell(const Vector ll, const Vector ur, double rotation = 0); - void CellFiles(const Vector ll, const Vector ur); - - inline Cell &getCell(int i) { - if ((unsigned)i void LoopCells(Op f) { + for (vector ::iterator i=cells.begin(); + i!=cells.end(); + i++) { + f(**i); + } + } + + template void LoopWalls(Op f) { + for (list ::iterator i=walls.begin(); + i!=walls.end(); + i++) { + f(**i); + } + } - template void LoopCells(Op f) { - for (vector ::iterator i=cells.begin(); - i!=cells.end(); - i++) { - f(**i); - } - } - - template void LoopWalls(Op f) { - for (list ::iterator i=walls.begin(); - i!=walls.end(); - i++) { - f(**i); - } - } - - // if the amount of cells might increase, during looping, use this template - template void LoopCurrentCells(Op f) { - vector current_cells = cells; - for (vector ::iterator i=current_cells.begin(); - i!=current_cells.end(); - i++) { - f(**i); - - } - } - - template void LoopNodes(Op f) { - for (vector::iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - f(**i); - } - } - - template void RandomlyLoopNodes(Op f) { - - MyUrand r(shuffled_nodes.size()); - random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r); - - for (vector::const_iterator i=shuffled_nodes.begin(); - i!=shuffled_nodes.end(); - i++) { - f(*shuffled_nodes[*i]); - } - - } - - template void RandomlyLoopCells(Op f) { - - MyUrand r(shuffled_cells.size()); - random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r); - - for (vector::const_iterator i=shuffled_cells.begin(); - i!=shuffled_cells.end(); - i++) { - f(*shuffled_cells[*i]); - } - - - } - - template void LoopCells(Op1 f, Op2 &g) { - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - f(**i,g); - } - } - - template void LoopCells(Op1 f, Op2 &g, Op3 &h) { - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - f(**i,g,h); - } - } - - void DoCellHouseKeeping(void) { - vector current_cells = cells; - for (vector::iterator i = current_cells.begin(); - i != current_cells.end(); - i ++) { - plugin->CellHouseKeeping(*i); - - // Call functions of Cell that cannot be called from CellBase, including Division - if ((*i)->flag_for_divide) { - if ((*i)->division_axis) { - (*i)->DivideOverAxis(*(*i)->division_axis); - delete (*i)->division_axis; - (*i)->division_axis = 0; - } else { - (*i)->Divide(); - } - (*i)->flag_for_divide=false; - } - } - } - - // Apply "f" to cell i - // i.e. this is an adapter which allows you to call a function - // operating on Cell on its numeric index index - template void cell_index_adapter(Op f,int i) { - f(cells[i]); - } - - double DisplaceNodes(void); - - void BoundingBox(Vector &LowerLeft, Vector &UpperRight); - int NEqs(void) { int nwalls = walls.size(); - int ncells =cells.size(); - int nchems = Cell::NChem(); - - // two eqs per chemical for each walls, and one eq per chemical for each cell - // This is for generality. For a specific model you may optimize - // this by removing superfluous (empty) equations. - int neqs = 2 * nwalls * nchems + ncells * nchems; - - return neqs; + // if the amount of cells might increase, during looping, use this template + template void LoopCurrentCells(Op f) { + vector current_cells = cells; + for (vector ::iterator i=current_cells.begin(); + i!=current_cells.end(); + i++) { + f(**i); + + } + } + + template void LoopNodes(Op f) { + for (vector::iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + f(**i); + } + } + + template void RandomlyLoopNodes(Op f) { + + MyUrand r(shuffled_nodes.size()); + random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r); + + for (vector::const_iterator i=shuffled_nodes.begin(); + i!=shuffled_nodes.end(); + i++) { + f(*shuffled_nodes[*i]); + } + } + + template void RandomlyLoopCells(Op f) { + + MyUrand r(shuffled_cells.size()); + random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r); + + for (vector::const_iterator i=shuffled_cells.begin(); + i!=shuffled_cells.end(); + i++) { + f(*shuffled_cells[*i]); + } + } + + template void LoopCells(Op1 f, Op2 &g) { + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + f(**i,g); + } + } + + template void LoopCells(Op1 f, Op2 &g, Op3 &h) { + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + f(**i,g,h); + } + } + + void DoCellHouseKeeping(void) { + vector current_cells = cells; + for (vector::iterator i = current_cells.begin(); + i != current_cells.end(); + i ++) { + plugin->CellHouseKeeping(*i); + + // Call functions of Cell that cannot be called from CellBase, including Division + if ((*i)->flag_for_divide) { + if ((*i)->division_axis) { + (*i)->DivideOverAxis(*(*i)->division_axis); + delete (*i)->division_axis; + (*i)->division_axis = 0; + } else { + (*i)->Divide(); } - void IncreaseCellCapacityIfNecessary(void) { - - return; - // cerr << "Entering Mesh::IncreaseCellCapacityIfNecessary \n"; - // make sure we always have enough space - // to have each cell divide at least once - // - // Note that we must do this, because Cell::Divide pushes a new Cell - // onto Mesh::cells. As a result, Mesh::cells might be relocated - // if we are _within_ a Cell object: i.e. pointer "this" will be changed!! - // - // An alternative solution could be to make "Mesh::cells" a list, - // but this won't work because we need random access for - // the Monte Carlo algorithm. - - if (2*cells.size()>cells.capacity()) { - cerr << "Increasing capacity to " << 2*cells.capacity() << endl; - cerr << "Current capacity is " << cells.capacity() << endl; - cells.reserve(cells.capacity()*2); - } - } - - void ReserveMoreCells(int n) { - if (nodes.size()+n>nodes.capacity()) { - nodes.reserve(size()+n); - } - } - double Area(void); - double MeanArea(void) { - double sum=0.; - for (vector::const_iterator i=cells.begin(); - i!=cells.end(); - i++) { - sum+=(*i)->Area(); - } - return sum/(double)NCells(); - } - - void SetBaseArea(void); - int NCells(void) const { - return cells.size(); - } - inline int NNodes(void) const { - return nodes.size(); - } - void PrintQueue(ostream &os) { - while (!node_insertion_queue.empty()) { - os << node_insertion_queue.front() << endl; - node_insertion_queue.pop(); - } - } - - void InsertNodes(void) { - // insert the nodes in the insertion queue - while (!node_insertion_queue.empty()) { - - //cerr << node_insertion_queue.front() << endl; - InsertNode(node_insertion_queue.front()); - node_insertion_queue.pop(); - } - - } - - void Clear(); - - void ReactDiffuse( double delta_t = 1 ); - double SumChemical(int ch); - void SetChemical(int ch, double value) { - for (vector::iterator c=cells.begin(); - c!=cells.end(); - c++) { - (*c)->chem[ch]=value; - } - } - - // used for interacing with ODE-solvers (e.g. NRCRungeKutta) - void setValues(double x, double *y); - double *getValues(int *neqs); - void Derivatives(double *derivs); + (*i)->flag_for_divide=false; + } + } + } + + // Apply "f" to cell i + // i.e. this is an adapter which allows you to call a function + // operating on Cell on its numeric index index + template void cell_index_adapter(Op f,int i) { + f(cells[i]); + } + + double DisplaceNodes(void); + + void BoundingBox(Vector &LowerLeft, Vector &UpperRight); + int NEqs(void) { int nwalls = walls.size(); + int ncells =cells.size(); + int nchems = Cell::NChem(); + + // two eqs per chemical for each walls, and one eq per chemical for each cell + // This is for generality. For a specific model you may optimize + // this by removing superfluous (empty) equations. + int neqs = 2 * nwalls * nchems + ncells * nchems; + + return neqs; + } + void IncreaseCellCapacityIfNecessary(void) { + + return; + // cerr << "Entering Mesh::IncreaseCellCapacityIfNecessary \n"; + // make sure we always have enough space + // to have each cell divide at least once + // + // Note that we must do this, because Cell::Divide pushes a new Cell + // onto Mesh::cells. As a result, Mesh::cells might be relocated + // if we are _within_ a Cell object: i.e. pointer "this" will be changed!! + // + // An alternative solution could be to make "Mesh::cells" a list, + // but this won't work because we need random access for + // the Monte Carlo algorithm. + + if (2*cells.size()>cells.capacity()) { + cerr << "Increasing capacity to " << 2*cells.capacity() << endl; + cerr << "Current capacity is " << cells.capacity() << endl; + cells.reserve(cells.capacity()*2); + } + } + + void ReserveMoreCells(int n) { + if (nodes.size()+n>nodes.capacity()) { + nodes.reserve(size()+n); + } + } + double Area(void); + double MeanArea(void) { + double sum=0.; + for (vector::const_iterator i=cells.begin(); + i!=cells.end(); + i++) { + sum+=(*i)->Area(); + } + return sum/(double)NCells(); + } + + void SetBaseArea(void); + int NCells(void) const { + return cells.size(); + } + inline int NNodes(void) const { + return nodes.size(); + } + void PrintQueue(ostream &os) { + while (!node_insertion_queue.empty()) { + os << node_insertion_queue.front() << endl; + node_insertion_queue.pop(); + } + } + + void InsertNodes(void) { + // insert the nodes in the insertion queue + while (!node_insertion_queue.empty()) { + + //cerr << node_insertion_queue.front() << endl; + InsertNode(node_insertion_queue.front()); + node_insertion_queue.pop(); + } + + } + + void Clear(); + + void ReactDiffuse( double delta_t = 1 ); + double SumChemical(int ch); + void SetChemical(int ch, double value) { + for (vector::iterator c=cells.begin(); + c!=cells.end(); + c++) { + (*c)->chem[ch]=value; + } + } + + // used for interacing with ODE-solvers (e.g. NRCRungeKutta) + void setValues(double x, double *y); + double *getValues(int *neqs); + void Derivatives(double *derivs); #ifdef QTGRAPHICS - inline void DrawBoundary(QGraphicsScene *c) { - boundary_polygon->Draw(c); - } - void DrawNodes(QGraphicsScene *c) const; - + inline void DrawBoundary(QGraphicsScene *c) { + boundary_polygon->Draw(c); + } + void DrawNodes(QGraphicsScene *c) const; + #endif - double max_chem; - - void XMLSave(const char *docname, xmlNode *settings=0) const; - void XMLRead(const char *docname, xmlNode **settings=0, bool geometry = true, bool pars = true, bool simtime = true); - void XMLReadPars(const xmlNode * root_node); - void XMLReadGeometry(const xmlNode *root_node); - void XMLReadSimtime(const xmlNode *root_node); - void XMLReadNodes(xmlNode *cur); - void XMLReadCells(xmlNode *cur); - void XMLParseTree(const xmlNode * root_node); - void XMLReadWalls(xmlNode *cur, vector *tmp_cells); - void XMLReadWallsToCells(xmlNode *root, vector *tmp_walls); - void XMLReadNodeSets(xmlNode *root); - void XMLReadNodeSetsToNodes(xmlNode *root); - void PerturbChem(int chemnum, double range); - void CleanUpCellNodeLists(void); - void CleanUpWalls(void); - void CutAwayBelowLine( Vector startpoint, Vector endpoint ); - void CutAwaySAM(void); - void RepairBoundaryPolygon(void); - void Rotate(double angle, Vector center); - void PrintWallList( void ); - void TestIllegalWalls(void); - Vector FirstConcMoment(int chem); - inline Vector Centroid(void) { - return boundary_polygon->Centroid(); - } - - inline Vector Offset(void) { - return boundary_polygon->Offset(); - } - - inline double Factor(void) { - return boundary_polygon->Factor(); - } - - void DeleteLooseWalls(void); - void FitLeafToCanvas(double width, double height); - void AddNodeSet(NodeSet *node_set) { - node_sets.push_back(node_set); - } - - void CleanChemicals(const vector &clean_chem); - void CleanTransporters(const vector &clean_transporters); - void RandomizeChemicals(const vector &max_chem, const vector &max_transporters); - inline double getTime(void) const { return time; } - string getTimeHours(void) const; - inline void setTime(double t) { time = t; } - double CalcProtCellsWalls(int ch) const; - void SettoInitVals(void); - QVector VertexAngles(void); - QVector< QPair > VertexAnglesValues(void); - void SetSimPlugin(SimPluginInterface *new_plugin) { - plugin=new_plugin; - } - QString ModelID(void) { return plugin?plugin->ModelID():QString("undefined"); } - void StandardInit(void); + double max_chem; + + void XMLSave(const char *docname, xmlNode *settings=0) const; + void XMLRead(const char *docname, xmlNode **settings=0, bool geometry = true, bool pars = true, bool simtime = true); + void XMLReadPars(const xmlNode * root_node); + void XMLReadGeometry(const xmlNode *root_node); + void XMLReadSimtime(const xmlNode *root_node); + void XMLReadNodes(xmlNode *cur); + void XMLReadCells(xmlNode *cur); + void XMLParseTree(const xmlNode * root_node); + void XMLReadWalls(xmlNode *cur, vector *tmp_cells); + void XMLReadWallsToCells(xmlNode *root, vector *tmp_walls); + void XMLReadNodeSets(xmlNode *root); + void XMLReadNodeSetsToNodes(xmlNode *root); + void PerturbChem(int chemnum, double range); + void CleanUpCellNodeLists(void); + void CleanUpWalls(void); + void CutAwayBelowLine( Vector startpoint, Vector endpoint ); + void CutAwaySAM(void); + void RepairBoundaryPolygon(void); + void Rotate(double angle, Vector center); + void PrintWallList( void ); + void TestIllegalWalls(void); + Vector FirstConcMoment(int chem); + inline Vector Centroid(void) { + return boundary_polygon->Centroid(); + } + + inline Vector Offset(void) { + return boundary_polygon->Offset(); + } + + inline double Factor(void) { + return boundary_polygon->Factor(); + } + + void DeleteLooseWalls(void); + void FitLeafToCanvas(double width, double height); + void AddNodeSet(NodeSet *node_set) { + node_sets.push_back(node_set); + } - Node* findNextBoundaryNode(Node*); + void CleanChemicals(const vector &clean_chem); + void CleanTransporters(const vector &clean_transporters); + void RandomizeChemicals(const vector &max_chem, const vector &max_transporters); + inline double getTime(void) const { return time; } + string getTimeHours(void) const; + inline void setTime(double t) { time = t; } + double CalcProtCellsWalls(int ch) const; + void SettoInitVals(void); + QVector VertexAngles(void); + QVector< QPair > VertexAnglesValues(void); + void SetSimPlugin(SimPluginInterface *new_plugin) { + plugin=new_plugin; + } + QString ModelID(void) { return plugin?plugin->ModelID():QString("undefined"); } + void StandardInit(void); + + Node* findNextBoundaryNode(Node*); + + private: -private: - - // Data members - vector cells; - vector nodes; - list walls; // we need to erase elements from this container frequently, hence a list. -public: - vector node_sets; -private: - vector shuffled_nodes; - vector shuffled_cells; - unique_queue node_insertion_queue; - BoundaryPolygon *boundary_polygon; - double time; - SimPluginInterface *plugin; - - // Private member functions - void AddNodeToCell(Cell *c, Node *n, Node *nb1 , Node *nb2); - void AddNodeToCellAtIndex(Cell *c, Node *n, Node *nb1 , Node *nb2, list::iterator ins_pos); - void InsertNode(Edge &e); - inline Node *AddNode(Node *n) { - nodes.push_back(n); - shuffled_nodes.push_back(n); - n->m=this; - return n; - } - - inline Cell *AddCell(Cell *c) { - cells.push_back(c); - shuffled_cells.push_back(c); - //cerr << "Shuffled cell indices: "; - /*copy(shuffled_cells.begin(),shuffled_cells.end(),ostream_iterator(cerr," ")); - cerr << endl;*/ - c->m=this; - return c; - } - - void CircumCircle(double x1,double y1,double x2,double y2,double x3,double y3, - double *xc,double *yc,double *r); + // Data members + vector cells; + vector nodes; + list walls; // we need to erase elements from this container frequently, hence a list. + public: + vector node_sets; + private: + vector shuffled_nodes; + vector shuffled_cells; + unique_queue node_insertion_queue; + BoundaryPolygon *boundary_polygon; + double time; + SimPluginInterface *plugin; + + // Private member functions + void AddNodeToCell(Cell *c, Node *n, Node *nb1 , Node *nb2); + void AddNodeToCellAtIndex(Cell *c, Node *n, Node *nb1 , Node *nb2, list::iterator ins_pos); + void InsertNode(Edge &e); + inline Node *AddNode(Node *n) { + nodes.push_back(n); + shuffled_nodes.push_back(n); + n->m=this; + return n; + } + + inline Cell *AddCell(Cell *c) { + cells.push_back(c); + shuffled_cells.push_back(c); + //cerr << "Shuffled cell indices: "; + /*copy(shuffled_cells.begin(),shuffled_cells.end(),ostream_iterator(cerr," ")); + cerr << endl;*/ + c->m=this; + return c; + } + + void CircumCircle(double x1,double y1,double x2,double y2,double x3,double y3, + double *xc,double *yc,double *r); }; #endif + +/* finis */ diff --git a/src/miscq.cpp b/src/miscq.cpp --- a/src/miscq.cpp +++ b/src/miscq.cpp @@ -26,12 +26,13 @@ static const std::string _module_id("$Id$"); // Returns the extension of a filename -QString getExtension(const QString fn) { - +QString getExtension(const QString fn) +{ // split on dots QStringList parts = fn.split("."); - + // return last part, this should be the extension return QString(parts.last()); - } + +/* finis */ diff --git a/src/miscq.h b/src/miscq.h --- a/src/miscq.h +++ b/src/miscq.h @@ -33,3 +33,4 @@ QString getExtension(const QString fn); #endif +/* finis */ diff --git a/src/modelcatalogue.cpp b/src/modelcatalogue.cpp --- a/src/modelcatalogue.cpp +++ b/src/modelcatalogue.cpp @@ -26,64 +26,64 @@ static const std::string _module_id("$Id$"); ModelCatalogue::ModelCatalogue(Mesh *_mesh, Main *_mainwin, const char *model=0) { - mesh = _mesh; - mainwin = _mainwin; - if (model) { - cerr << "Loading model: " << model << endl; - LoadPlugin(model); - } else { - cerr << "Loading all models." << endl; - LoadPlugins(); - } + mesh = _mesh; + mainwin = _mainwin; + if (model) { + cerr << "Loading model: " << model << endl; + LoadPlugin(model); + } else { + cerr << "Loading all models." << endl; + LoadPlugins(); + } } void ModelCatalogue::LoadPlugins() { - - QDir pluginDir(QApplication::applicationDirPath()); - QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib" + + QDir pluginDir(QApplication::applicationDirPath()); + QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib" #if defined(Q_OS_WIN) - if (pluginDir.dirName().toLower() =="debug" - ||pluginDir.dirName().toLower() =="release") - pluginDir.cdUp(); - plugin_filters << "*.dll"; - #elif defined(Q_OS_MAC) - if (pluginDir.dirName() =="MacOS"){ - pluginDir.cdUp(); - pluginDir.cdUp(); - pluginDir.cdUp(); - } - plugin_filters << "*.dylib"; + if (pluginDir.dirName().toLower() =="debug" + ||pluginDir.dirName().toLower() =="release") + pluginDir.cdUp(); + plugin_filters << "*.dll"; +#elif defined(Q_OS_MAC) + if (pluginDir.dirName() =="MacOS"){ + pluginDir.cdUp(); + pluginDir.cdUp(); + pluginDir.cdUp(); + } + plugin_filters << "*.dylib"; #endif - pluginDir.setNameFilters(plugin_filters); + pluginDir.setNameFilters(plugin_filters); - if (!pluginDir.cd("models")) { - MyWarning::error("Directory 'models' not found!"); - } - - - //QVector plugins; - foreach (QString fileName, pluginDir.entryList(QDir::Files)){ - QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); - if (SimPluginInterface *plugin = - qobject_cast(loader.instance())) { - models.append(plugin); - } else { - cerr << loader.errorString().toStdString().c_str() << endl; - MyWarning::warning("Could not load model %s: %s",fileName.toStdString().c_str(), loader.errorString().toStdString().c_str()); - } - } - if (models.size()==0) { - MyWarning::error("No models could be loaded."); - } + if (!pluginDir.cd("models")) { + MyWarning::error("Directory 'models' not found!"); + } + + + //QVector plugins; + foreach (QString fileName, pluginDir.entryList(QDir::Files)){ + QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); + if (SimPluginInterface *plugin = + qobject_cast(loader.instance())) { + models.append(plugin); + } else { + cerr << loader.errorString().toStdString().c_str() << endl; + MyWarning::warning("Could not load model %s: %s",fileName.toStdString().c_str(), loader.errorString().toStdString().c_str()); + } + } + if (models.size()==0) { + MyWarning::error("No models could be loaded."); + } } void ModelCatalogue::LoadPlugin(const char *model) { - + QDir pluginDir(QApplication::applicationDirPath()); QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib" - - + + #if defined(Q_OS_WIN) if (pluginDir.dirName().toLower() =="debug" ||pluginDir.dirName().toLower() =="release") @@ -99,18 +99,18 @@ void ModelCatalogue::LoadPlugin(const ch #endif plugin_filters << model; pluginDir.setNameFilters(plugin_filters); - + if (!pluginDir.cd("models")) { MyWarning::error("Directory 'models' not found!"); } - + QStringList modelnames=pluginDir.entryList(QDir::Files); if (modelnames.empty()) { MyWarning::error("Model %s not found - hint: do not include path in filename.",model); } foreach (QString fileName, modelnames){ QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); - + if (SimPluginInterface *plugin = qobject_cast(loader.instance())) { models.append(plugin); @@ -122,33 +122,33 @@ void ModelCatalogue::LoadPlugin(const ch } void ModelCatalogue::InstallFirstModel() { - InstallModel(models[0]); + InstallModel(models[0]); } void ModelCatalogue::PopulateModelMenu() { - foreach (SimPluginInterface *model, models) { - QAction *modelaction = new QAction(model->ModelID(), mainwin); - QVariant data; - data.setValue(model); - modelaction->setData(data); - mainwin->modelmenu->addAction(modelaction); - - } - connect(mainwin->modelmenu, SIGNAL(triggered(QAction *)), this, SLOT(InstallModel(QAction *)) ); + foreach (SimPluginInterface *model, models) { + QAction *modelaction = new QAction(model->ModelID(), mainwin); + QVariant data; + data.setValue(model); + modelaction->setData(data); + mainwin->modelmenu->addAction(modelaction); + + } + connect(mainwin->modelmenu, SIGNAL(triggered(QAction *)), this, SLOT(InstallModel(QAction *)) ); } void ModelCatalogue::InstallModel(QAction *modelaction) { - QVariant data = modelaction->data(); - SimPluginInterface *model = data.value(); - cerr << "You chose model " << model->ModelID().toStdString() << "!\n"; - mesh->Clean(); - InstallModel(model); + QVariant data = modelaction->data(); + SimPluginInterface *model = data.value(); + cerr << "You chose model " << model->ModelID().toStdString() << "!\n"; + mesh->Clean(); + InstallModel(model); } void ModelCatalogue::InstallModel(SimPluginInterface *plugin) { - + // make sure both main and plugin use the same static datamembers (ncells, nchems...) plugin->SetCellsStaticDatamembers(CellBase::GetStaticDataMemberPointer()); - + mesh->SetSimPlugin(plugin); Cell::SetNChem(plugin->NChem()); plugin->SetParameters(&par); diff --git a/src/modelcatalogue.h b/src/modelcatalogue.h --- a/src/modelcatalogue.h +++ b/src/modelcatalogue.h @@ -39,22 +39,21 @@ #include class ModelCatalogue : public QObject { -Q_OBJECT -public: - ModelCatalogue(Mesh *mesh, Main *mainwin, const char *model); - void LoadPlugins(); - void LoadPlugin(const char *model); - - void InstallFirstModel(); - void PopulateModelMenu(); + Q_OBJECT + public: + ModelCatalogue(Mesh *mesh, Main *mainwin, const char *model); + void LoadPlugins(); + void LoadPlugin(const char *model); -public slots: - void InstallModel(SimPluginInterface *model); - void InstallModel(QAction *modelaction); -private: - QVector models; - Mesh *mesh; - Main *mainwin; + void InstallFirstModel(); + void PopulateModelMenu(); + public slots: + void InstallModel(SimPluginInterface *model); + void InstallModel(QAction *modelaction); + private: + QVector models; + Mesh *mesh; + Main *mainwin; }; #endif diff --git a/src/modelelement.h b/src/modelelement.h --- a/src/modelelement.h +++ b/src/modelelement.h @@ -30,7 +30,7 @@ // pure virtual base class for all model elements class ModelElement { - + public: virtual void Displace(void) {}; virtual ~ModelElement() {}; diff --git a/src/node.cpp b/src/node.cpp --- a/src/node.cpp +++ b/src/node.cpp @@ -46,20 +46,19 @@ ostream &Edge::print(ostream &os) const } ostream &Neighbor::print(ostream &os) const { - + os << " {" << cell->Index() << " " << nb1->Index() << " " << nb2->Index() << "}"; return os; - } ostream &operator<<(ostream &os, const Neighbor &n) { n.print(os); return os; } - + -Node::Node(void) : Vector() { - +Node::Node(void) : Vector() +{ index=(nnodes++); node_set =0; fixed=false; @@ -68,7 +67,8 @@ Node::Node(void) : Vector() { dead=false; } -Node::Node(int ind) : Vector() { +Node::Node(int ind) : Vector() +{ node_set =0; index=ind; fixed=false; @@ -77,8 +77,8 @@ Node::Node(int ind) : Vector() { dead=false; } -Node::Node(const Vector &src) : Vector(src) { - +Node::Node(const Vector &src) : Vector(src) +{ node_set = 0; index=(nnodes++); fixed=false; @@ -87,8 +87,8 @@ Node::Node(const Vector &src) : Vector(s dead = false; } -Node::Node(double x,double y, double z) : Vector (x,y,z) { - +Node::Node(double x,double y, double z) : Vector (x,y,z) +{ node_set = 0; index=(nnodes++); fixed=false; @@ -97,8 +97,8 @@ Node::Node(double x,double y, double z) dead = false; } -Node::Node(const Node &src) : Vector(src) { - +Node::Node(const Node &src) : Vector(src) +{ node_set=0; owners=src.owners; m=src.m; @@ -110,20 +110,21 @@ Node::Node(const Node &src) : Vector(src } -Cell &Node::getCell(const Neighbor &i) { +Cell &Node::getCell(const Neighbor &i) +{ return *i.getCell(); // use accessor! } ostream &Node::print(ostream &os) const { - + if (!dead) os << "Node "; else os << "DEAD NODE "; - + os << index << "[ {" << x << ", " << y << ", " << z << "}: {"; - + os << "Neighbors = { "; for (list::const_iterator i = owners.begin(); i!=owners.end(); i++) { @@ -132,7 +133,6 @@ ostream &Node::print(ostream &os) const os << " } " << endl; return os; - } @@ -154,70 +154,65 @@ void Node::DrawIndex(QGraphicsScene *c) } void Node::DrawOwners(QGraphicsScene *c) const { - + stringstream text; - - + text << owners.size(); - text << owners.size(); - - QGraphicsSimpleTextItem *number = new QGraphicsSimpleTextItem ( QString (text.str().c_str()), 0, c ); number->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); number->setPen( QPen(par.textcolor) ); number->setZValue(20); number->show(); Vector offs=Cell::Offset(); - + number ->setPos(((offs.x+x)*Cell::Factor()), ((offs.y+y)*Cell::Factor()) ); } +QVector Node::NeighbourAngles(void) +{ + QVector angles; + for (list::iterator i=owners.begin(); + i!=owners.end(); + i++) { -QVector Node::NeighbourAngles(void) { - - QVector angles; - for (list::iterator i=owners.begin(); - i!=owners.end(); - i++) { - - Vector v1 = (*this - *i->nb1).Normalised(); - Vector v2 = (*this - *i->nb2).Normalised(); - - double angle = v1.SignedAngle(v2); - if (angle<0) { - //cerr << "Changing sign of angle " << angle << endl; - angle = angle + 2*Pi; - } - angles.push_back(angle); - - //cerr << "Cell " << i->cell->Index() << ": " << v1 << " and " << v2 << ": angle = " << angles.back() << ", " << v1.Angle(v2) << endl; - - } - - double sum=0.; - for (QVector::iterator i=angles.begin(); - i!=angles.end(); - i++) { - sum+=*i; - } - //cerr << "Angle sum = " << sum << endl; - // Check if the summed angle is different from 2 Pi - if (fabs(sum-(2*Pi))>0.0001) { - - MyWarning::warning("sum = %f",sum); - } - return angles; + Vector v1 = (*this - *i->nb1).Normalised(); + Vector v2 = (*this - *i->nb2).Normalised(); + + double angle = v1.SignedAngle(v2); + if (angle<0) { + //cerr << "Changing sign of angle " << angle << endl; + angle = angle + 2*Pi; + } + angles.push_back(angle); + + //cerr << "Cell " << i->cell->Index() << ": " << v1 << " and " << v2 + // << ": angle = " << angles.back() << ", " << v1.Angle(v2) << endl; + + } + + double sum=0.; + for (QVector::iterator i=angles.begin(); + i!=angles.end(); + i++) { + sum+=*i; + } + //cerr << "Angle sum = " << sum << endl; + // Check if the summed angle is different from 2 Pi + if (fabs(sum-(2*Pi))>0.0001) { + + MyWarning::warning("sum = %f",sum); + } + return angles; } - #endif - ostream &operator<<(ostream &os, const Node &n) { n.print(os); return os; } +/* finis */ diff --git a/src/node.h b/src/node.h --- a/src/node.h +++ b/src/node.h @@ -49,8 +49,8 @@ extern Parameter par; class Edge { - -public: + + public: Edge(void) { first=0; @@ -61,7 +61,7 @@ public: first=f; second=s; } - + // Copy Constructor Edge(const Edge &src) { first=src.first; @@ -73,12 +73,11 @@ public: return ( (first==e.first && second==e.second) || (first==e.second && second==e.first) ); } - + // Output the Edge ostream &print(ostream &os) const; - - + Node *first, *second; }; @@ -96,7 +95,7 @@ class Node : public Vector { friend class NodeSet; friend class FigureEditor; -public: + public: Node(void); Node(int index); // if want to construct a node, and not increase nnodes @@ -124,75 +123,62 @@ public: inline void toggleBoundary(void) { boundary = !boundary; } - + Cell &getCell(const Neighbor &i); - + ostream &print(ostream &os) const; void XMLAdd(xmlNodePtr nodes_node) const; - + #ifdef QTGRAPHICS void Draw(QGraphicsScene &c, QColor color=QColor("black"), int size = 10) const; void DrawIndex(QGraphicsScene *c) const; void DrawOwners(QGraphicsScene *c) const; #endif - + // temporary function for easier debugging - inline int CellsSize(void) const { - return owners.size(); - } + inline int CellsSize(void) const { return owners.size(); } + + inline int Value(void) const { return owners.size(); } - inline int Value(void) const { - return owners.size(); - } + void Fix(void) { fixed=true; } + + inline bool Fixed(void) const { return fixed; } - void Fix(void) { - fixed=true; - } - inline bool Fixed(void) const { - return fixed; - } - inline void Unfix(void) { - fixed=false; - } - inline void MarkDead(void) { - dead=true; - } - inline bool DeadP(void) { - return dead; - } + inline void Unfix(void) { fixed=false; } + + inline void MarkDead(void) { dead=true; } + + inline bool DeadP(void) { return dead; } - inline void Mark(void) { - marked=true; - } - inline void Unmark(void) { - marked=false; - } - inline bool Marked(void) const { - return marked; - } - + inline void Mark(void) { marked=true; } + + inline void Unmark(void) { marked=false; } + + inline bool Marked(void) const { return marked; } + inline void setPos( Vector p ) { x = p.x; y = p.y; z = p.z; } + inline bool SamP(void) const { return sam; } //!\brief Calculate angles with neighboring vertices //! Sum of angles should be 2*Pi QVector NeighbourAngles(void); -private: - + private: + // "owners" lists the cells to which this cell belong // and the two neighboring nodes relative to each cell list< Neighbor > owners; - + Mesh *m; int index; static int nnodes; static double target_length; - + // if the node belongs to a NodeSet, node_set contains the pointer. Otherwise it is 0. NodeSet *node_set; // fixed nodes cannot move. E.g. to represent the petiole @@ -210,5 +196,6 @@ inline ostream &operator<<(ostream &os, return os; } +#endif -#endif +/* finis */ diff --git a/src/nodeitem.cpp b/src/nodeitem.cpp --- a/src/nodeitem.cpp +++ b/src/nodeitem.cpp @@ -34,17 +34,17 @@ extern Parameter par; NodeItem::NodeItem( Node *n, QGraphicsScene *canvas ) : QGraphicsItem( 0, canvas ), SimItemBase( n, canvas) { - + brush = Qt::darkGray; - + const double mag = par.node_mag; ellipsesize=QRectF(-1*mag, -1*mag, 2*mag, 2*mag); - } -void NodeItem::userMove(double dx, double dy) { +void NodeItem::userMove(double dx, double dy) +{ QGraphicsItem::moveBy( dx, dy ); - + class_cast(obj)->x += (dx/Cell::Magnification()); class_cast(obj)->y += (dy/Cell::Magnification()); } @@ -53,9 +53,8 @@ void NodeItem::userMove(double dx, doubl void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { + option = NULL; // use assignment merely to obviate compilation warning - option = NULL; // use assignment merely to obviate compilation warning - painter->setBrush(brush); painter->setPen(Qt::NoPen); painter->drawEllipse(ellipsesize); @@ -64,9 +63,9 @@ void NodeItem::paint(QPainter *painter, QPainterPath NodeItem::shape() const { - QPainterPath path; - path.addEllipse(ellipsesize); - return path; + QPainterPath path; + path.addEllipse(ellipsesize); + return path; } QRectF NodeItem::boundingRect() const @@ -77,29 +76,30 @@ QRectF NodeItem::boundingRect() const } // polymorphic OnClick functions -void NodeItem::OnClick(void) { +void NodeItem::OnClick(void) +{ Node *n = &getNode(); n->toggleBoundary(); setColor(); update(); } -void NodeItem::OnClick(const Qt::MouseButton &mb) { +void NodeItem::OnClick(const Qt::MouseButton &mb) +{ if (mb == Qt::LeftButton) { Node *n = &getNode(); n->toggleBoundary(); setColor(); update(); - } } -void NodeItem::setColor(void) { - +void NodeItem::setColor(void) +{ static QColor indian_red("IndianRed"); static QColor deep_sky_blue("DeepSkyBlue"); static QColor purple("Purple"); - + Node &n=getNode(); if (n.SamP()) { @@ -113,3 +113,5 @@ void NodeItem::setColor(void) { } } } + +/* finis */ diff --git a/src/nodeitem.h b/src/nodeitem.h --- a/src/nodeitem.h +++ b/src/nodeitem.h @@ -33,12 +33,12 @@ class NodeItem: public QGraphicsItem, public SimItemBase { -public: + public: NodeItem( Node *n, QGraphicsScene *canvas ); ~NodeItem() {} Node &getNode(void) const { return *class_cast(obj); } virtual void userMove(double dx, double dy); - + QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QPainterPath shape() const; @@ -48,11 +48,13 @@ public: Simply put the property to be change upon clicking a node in this function. */ void OnClick( const Qt::MouseButton &mb ); void OnClick(void); -protected: + protected: QBrush brush; QRectF ellipsesize; -private: + private: }; #endif + +/* finis */ diff --git a/src/nodeset.cpp b/src/nodeset.cpp --- a/src/nodeset.cpp +++ b/src/nodeset.cpp @@ -29,3 +29,5 @@ ostream &operator<<(ostream &os, const N ns.print(os); return os; } + +/* finis */ diff --git a/src/nodeset.h b/src/nodeset.h --- a/src/nodeset.h +++ b/src/nodeset.h @@ -32,66 +32,65 @@ #include "node.h" class NodeSet : public list { - + public: NodeSet(void) { done = false; } - + inline bool DoneP(void) { return done; } inline void ResetDone(void) { done = false; } - + void AddNode(Node * n) { push_back(n); n->node_set = this; } list getCells(void) { - + list cellset; - + for (list::const_iterator i=begin(); i!=end(); i++) { transform ( (*i)->owners.begin(), (*i)->owners.end(), back_inserter( cellset ) , mem_fun_ref ( &Neighbor::getCell )); } - + cellset.sort(); - + // remove all non-unique elements // (unique moves all unique elements to the front and returns an iterator to the end of the unique elements; // so we simply erase all remaining elements. - cellset.erase(::unique(cellset.begin(), cellset.end() ), - cellset.end() ); - + cellset.erase(::unique(cellset.begin(), cellset.end() ), cellset.end() ); + // remove boundary_polygon cellset.erase( find_if ( cellset.begin(), cellset.end(), mem_fun( &Cell::BoundaryPolP ) ) ); return cellset; } void CleanUp(void) { - + // remove double Nodes from the set sort(); erase(::unique(begin(), end() ), - end() ); - - + end() ); + + } void print(ostream &os) const { transform( begin(), end(), ostream_iterator( os, " " ), mem_fun( &Node::Index ) ); } - + /*! Attempt a move over (rx, ry) reject if energetically unfavourable. */ void AttemptMove(double rx, double ry) { - + done = true; // 1. Collect list of all attached to the nodes in the set list celllist = getCells(); - + // 2. Sum the current energy of these cells double old_energy=0.; double sum_stiff = 0.; @@ -102,60 +101,57 @@ class NodeSet : public list { old_energy += (*i)->Energy(); sum_stiff += (*i)->Stiffness(); } - + // 3. (Temporarily) move the set's nodes. for ( list::iterator n = begin(); n!=end(); ++n ) { - + (*n)->x+=rx; (*n)->y+=ry; // (*n)->z += rz; - } - + // 4. Recalculate the energy double new_energy = 0.; for ( list::const_iterator i = celllist.begin(); i!=celllist.end(); ++i ) { - + new_energy += (*i)->Energy(); } - - + + // 5. Accept or Reject DeltaH - double dh = new_energy - old_energy; - - list new_areas; - - // cerr << "Nodeset says: dh = " << dh << " ..."; - if (dh < -sum_stiff || RANDOM() new_areas; + + // cerr << "Nodeset says: dh = " << dh << " ..."; + if (dh < -sum_stiff || RANDOM()::iterator n = begin(); n!= end(); ++n ) { - + (*n)->x-=rx; (*n)->y-=ry; - } - - + } } } - + void XMLAdd(xmlNode *root) const; void XMLRead(xmlNode *root, Mesh *m); private: @@ -164,3 +160,5 @@ class NodeSet : public list { ostream &operator<<(ostream &os, const NodeSet &ns); #endif + +/* finis */ diff --git a/src/output.cpp b/src/output.cpp --- a/src/output.cpp +++ b/src/output.cpp @@ -41,11 +41,11 @@ using namespace MyWarning; #define FNAMESIZE 100 int OpenFileAndCheckExistance(FILE **fp,const char *fname,char *ftype) { - + *fp=fopen(fname,ftype); if (*fp==NULL) return FALSE; - + if (!strncmp(ftype,"a",1)) { if (ftell(*fp)>0L) return TRUE; else return FALSE; @@ -53,49 +53,46 @@ int OpenFileAndCheckExistance(FILE **fp, } int FileExistsP(const char *fname) { - + FILE *fp; fp=fopen(fname,"r"); if (fp==NULL) return FALSE; - + fclose(fp); return TRUE; +} -} - int YesNoP(const char *message) { - + char answer[100]; fprintf(stderr,"%s (y/n) ",message); fflush(stderr); - + scanf("%s",answer); while (strcmp(answer,"y") && strcmp(answer,"n")) { fprintf(stderr,"\n\bPlease answer 'y' or 'n'. "); fflush(stderr); scanf("%s",answer); } - + if (!strcmp(answer,"y")) return TRUE; - + return FALSE; - } FILE *OpenWriteFile(const char *filename) { - char fname[FNAMESIZE]; FILE *fp; fprintf(stderr,"Opening %s for writing\n",filename); - + if(FileExistsP(filename)==TRUE) { - + if (false/*par.interactive*/) { char *message=(char *)malloc(2000*sizeof(char)); if (!YesNoP("File exists, overwrite?")) { @@ -108,12 +105,11 @@ FILE *OpenWriteFile(const char *filename /* Rename old file */ sprintf(fname, "%s~",filename); rename(filename, fname); - } } - + strncpy(fname, filename, FNAMESIZE-1); - + if ((fp=fopen(fname,"w"))==NULL) { char *message=(char *)malloc(2000*sizeof(char)); sprintf(message," Could not open file %s for writing: " @@ -121,7 +117,6 @@ FILE *OpenWriteFile(const char *filename perror(""); throw(message); } - return fp; } @@ -131,7 +126,7 @@ FILE *OpenReadFile(const char *filename) FILE *fp; fprintf(stderr,"Opening %s for reading\n",filename); - + if((OpenFileAndCheckExistance(&fp,filename,"r"))==FALSE) { char *message=(char *)malloc(2000*sizeof(char)); sprintf(message," File %s not found or empty, exiting... \n" ,filename); @@ -144,15 +139,15 @@ FILE *OpenReadFile(const char *filename) char *ReadLine(FILE *fp) { /* does almost the same as fgetln(), but DEC Unix doesn't understand - fgetln(). Also I want my function to return a real C string, - terminated by a \0. */ + fgetln(). Also I want my function to return a real C string, + terminated by a \0. */ /* The function reads a line from file *fp, and returns a pointer to the - line read, which can be freed with a normal free(). The length of the - string is written in *len */ - + line read, which can be freed with a normal free(). The length of the + string is written in *len */ + #define INITIAL_BUFSIZE 100 - + char *tmpstring; int character; long bufsize; @@ -160,62 +155,54 @@ char *ReadLine(FILE *fp) int pos; CheckFile(fp); - + /* first allocate a string with a standard length */ bufsize=INITIAL_BUFSIZE; MEMORYCHECK(tmpstring=(char *)malloc(bufsize*sizeof(char))); pos=0; - + while ((character=getc(fp))!=EOF && /* read a character and check */ - character!='\n') { - - - tmpstring[pos]=(char)character; - (pos)++; + character!='\n') { - if (pos >= bufsize) { - /* line is longer than initial_bufsize, reallocate space */ - bufsize+=INITIAL_BUFSIZE; - MEMORYCHECK(tmpstring=(char *)realloc(tmpstring,bufsize*sizeof(char))); - - } - + tmpstring[pos]=(char)character; + (pos)++; + + if (pos >= bufsize) { + /* line is longer than initial_bufsize, reallocate space */ + bufsize+=INITIAL_BUFSIZE; + MEMORYCHECK(tmpstring=(char *)realloc(tmpstring,bufsize*sizeof(char))); + } } - if (character==EOF) { - - if (pos==0) { - /* EOF was reached, while no characters were read */ - free(tmpstring); - return NULL; - } - if (ferror(fp)) { - error("I/O error in ReadLine(%ld): %s\n",fp, strerror(errno)); - } - + if (pos==0) { + /* EOF was reached, while no characters were read */ + free(tmpstring); + return NULL; + } + if (ferror(fp)) { + error("I/O error in ReadLine(%ld): %s\n",fp, strerror(errno)); + } + } - } - /* Allocate enough memory for the line */ MEMORYCHECK(line=(char *)malloc((++(pos))*sizeof(char))); strncpy(line,tmpstring,(pos)-1); free(tmpstring); - + line[pos-1]='\0'; return line; - } void CheckFile(FILE *fp) { if (ftell(fp)<0) { - /* file is probably not open, or another error occured */ - error("File error (fp=%ld): %d %s\n",fp,errno,strerror(errno)); + /* file is probably not open, or another error occured */ + error("File error (fp=%ld): %d %s\n",fp,errno,strerror(errno)); } /* File pointer is ok */ } @@ -223,12 +210,12 @@ void CheckFile(FILE *fp) char *Chext(char *filename) { /* Chop the extension from a filename */ - + /* Search backwards until a dot */ - + /* Remember to free the memory allocated by this function */ /* ( free(result) ) */ - + /* not yet tested */ int i; @@ -237,32 +224,29 @@ char *Chext(char *filename) { for (i=strlen(filename)-1;i>=0;i--) { if (filename[i]=='.') break; - } - + /* No . found */ if (i==0) { - + result=strdup(filename); } else { - + /* . found */ result=(char *)malloc((i+1)*sizeof(char)); strncpy(result, filename, i); } return result; - - } void MakeDir(const char *dirname) { #ifdef QTGRAPHICS QFileInfo file_info(dirname); - + //check for existance if (file_info.exists()) { - + if (file_info.isDir()) { // OK cerr << "Using existing directory " << dirname << " for data storage." << endl; @@ -273,7 +257,6 @@ void MakeDir(const char *dirname) { cerr << message << endl; throw(message); } - } // make directory @@ -286,23 +269,23 @@ void MakeDir(const char *dirname) { //exit(1); return; } - + // check - + #else - + int status; char message[MESS_BUF_SIZE]; - + status=mkdir(dirname, S_IRWXU); // S_IRWXU: Read, Write, Execute by Owner - + if (status<0) { // error occurred - + //check for existance - + if (errno==EEXIST) { - + // Check whether it is a directory struct stat buf; stat(dirname, &buf); @@ -325,17 +308,15 @@ void MakeDir(const char *dirname) { } } else { // a different error occurred. Print error and quit - + snprintf(message,MESS_BUF_SIZE,"Error in making directory %s",dirname); perror(message); exit(1); - } - - - } #endif } + +/* finis */ diff --git a/src/output.h b/src/output.h --- a/src/output.h +++ b/src/output.h @@ -29,17 +29,17 @@ extern "C" { #endif -int OpenFileAndCheckExistance(FILE **fp,const char *fname,char *ftype); -int YesNoP(const char *message); -FILE *OpenWriteFile(const char *filename); -FILE *OpenGZippedWriteFile(const char *filename); -FILE *OpenReadFile(const char *filename); -char *ReadLine(FILE *fp); -void CheckFile(FILE *fp); -int FileExistsP(const char *fname); -char *Chext(char *filename); -void MakeDir(const char *dirname); -bool CanWeWriteP(char *filename); + int OpenFileAndCheckExistance(FILE **fp,const char *fname,char *ftype); + int YesNoP(const char *message); + FILE *OpenWriteFile(const char *filename); + FILE *OpenGZippedWriteFile(const char *filename); + FILE *OpenReadFile(const char *filename); + char *ReadLine(FILE *fp); + void CheckFile(FILE *fp); + int FileExistsP(const char *fname); + char *Chext(char *filename); + void MakeDir(const char *dirname); + bool CanWeWriteP(char *filename); #ifdef __cplusplus } @@ -53,3 +53,5 @@ bool CanWeWriteP(char *filename); #endif #endif + +/* finis */ diff --git a/src/parameter.cpp b/src/parameter.cpp --- a/src/parameter.cpp +++ b/src/parameter.cpp @@ -183,52 +183,50 @@ Parameter::Parameter() { } Parameter::~Parameter() { - + // destruct parameter object // free string parameter CleanUp(); - } void Parameter::CleanUp(void) { if (arrowcolor) - free(arrowcolor); + free(arrowcolor); if (textcolor) - free(textcolor); + free(textcolor); if (cell_outline_color) - free(cell_outline_color); + free(cell_outline_color); if (D) - free(D); + free(D); if (initval) - free(initval); + free(initval); if (datadir) - free(datadir); + free(datadir); if (k) - free(k); + free(k); if (s1) - free(s1); + free(s1); if (s2) - free(s2); + free(s2); if (s3) - free(s3); + free(s3); if (dir1) - free(dir1); + free(dir1); if (dir2) - free(dir2); - + free(dir2); } void Parameter::Read(const char *filename) { - + static bool ReadP=false; if (ReadP) { //throw "Run Time Error in parameter.cpp: Please Read parameter file only once!!"; CleanUp(); - + } else ReadP=true; @@ -339,7 +337,6 @@ void Parameter::Read(const char *filenam dir2 = sgetpar(fp, "dir2", ".", true); if (strcmp(dir2, ".")) MakeDir(dir2); - } const char *sbool(const bool &p) { @@ -473,1411 +470,1410 @@ void Parameter::Write(ostream &os) const } void Parameter::XMLAdd(xmlNode *root) const { xmlNode *xmlparameter = xmlNewChild(root, NULL, BAD_CAST "parameter", NULL); -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowcolor" ); - ostringstream text; + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowcolor" ); + ostringstream text; - if (arrowcolor) - text << arrowcolor; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowsize" ); - ostringstream text; - text << arrowsize; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "textcolor" ); - ostringstream text; + if (arrowcolor) + text << arrowcolor; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowsize" ); + ostringstream text; + text << arrowsize; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "textcolor" ); + ostringstream text; - if (textcolor) - text << textcolor; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cellnumsize" ); - ostringstream text; - text << cellnumsize; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nodenumsize" ); - ostringstream text; - text << nodenumsize; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "node_mag" ); - ostringstream text; - text << node_mag; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "outlinewidth" ); - ostringstream text; - text << outlinewidth; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_outline_color" ); - ostringstream text; + if (textcolor) + text << textcolor; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cellnumsize" ); + ostringstream text; + text << cellnumsize; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nodenumsize" ); + ostringstream text; + text << nodenumsize; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "node_mag" ); + ostringstream text; + text << node_mag; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "outlinewidth" ); + ostringstream text; + text << outlinewidth; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_outline_color" ); + ostringstream text; - if (cell_outline_color) - text << cell_outline_color; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "resize_stride" ); - ostringstream text; - text << resize_stride; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "T" ); - ostringstream text; - text << T; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_length" ); - ostringstream text; - text << lambda_length; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_celllength" ); - ostringstream text; - text << lambda_celllength; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "target_length" ); - ostringstream text; - text << target_length; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_expansion_rate" ); - ostringstream text; - text << cell_expansion_rate; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_div_expansion_rate" ); - ostringstream text; - text << cell_div_expansion_rate; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "auxin_dependent_growth" ); - ostringstream text; -text << sbool(auxin_dependent_growth); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "ode_accuracy" ); - ostringstream text; - text << ode_accuracy; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_stepsize" ); - ostringstream text; - text << mc_stepsize; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_cell_stepsize" ); - ostringstream text; - text << mc_cell_stepsize; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "energy_threshold" ); - ostringstream text; - text << energy_threshold; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "bend_lambda" ); - ostringstream text; - text << bend_lambda; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "alignment_lambda" ); - ostringstream text; - text << alignment_lambda; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_cell_div_threshold" ); - ostringstream text; - text << rel_cell_div_threshold; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_perimeter_stiffness" ); - ostringstream text; - text << rel_perimeter_stiffness; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "collapse_node_threshold" ); - ostringstream text; - text << collapse_node_threshold; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_div_threshold" ); - ostringstream text; - text << morphogen_div_threshold; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_expansion_threshold" ); - ostringstream text; - text << morphogen_expansion_threshold; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "copy_wall" ); - ostringstream text; -text << sbool(copy_wall); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "source" ); - ostringstream text; - text << source; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "D" ); - xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); + if (cell_outline_color) + text << cell_outline_color; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "resize_stride" ); + ostringstream text; + text << resize_stride; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "T" ); + ostringstream text; + text << T; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_length" ); + ostringstream text; + text << lambda_length; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_celllength" ); + ostringstream text; + text << lambda_celllength; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "target_length" ); + ostringstream text; + text << target_length; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_expansion_rate" ); + ostringstream text; + text << cell_expansion_rate; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_div_expansion_rate" ); + ostringstream text; + text << cell_div_expansion_rate; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "auxin_dependent_growth" ); + ostringstream text; + text << sbool(auxin_dependent_growth); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "ode_accuracy" ); + ostringstream text; + text << ode_accuracy; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_stepsize" ); + ostringstream text; + text << mc_stepsize; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_cell_stepsize" ); ostringstream text; - text << D[0]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << mc_cell_stepsize; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "energy_threshold" ); + ostringstream text; + text << energy_threshold; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "bend_lambda" ); + ostringstream text; + text << bend_lambda; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "alignment_lambda" ); + ostringstream text; + text << alignment_lambda; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_cell_div_threshold" ); + ostringstream text; + text << rel_cell_div_threshold; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_perimeter_stiffness" ); + ostringstream text; + text << rel_perimeter_stiffness; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "collapse_node_threshold" ); + ostringstream text; + text << collapse_node_threshold; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_div_threshold" ); + ostringstream text; + text << morphogen_div_threshold; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_expansion_threshold" ); + ostringstream text; + text << morphogen_expansion_threshold; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "copy_wall" ); + ostringstream text; + text << sbool(copy_wall); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "source" ); + ostringstream text; + text << source; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { - ostringstream text; - text << D[1]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[2]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[3]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[4]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[5]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[6]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[7]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[8]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[9]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[10]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[11]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[12]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << D[13]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "D" ); + xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); + { + ostringstream text; + text << D[0]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[1]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[2]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[3]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[4]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[5]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[6]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[7]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[8]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[9]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[10]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[11]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[12]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[13]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << D[14]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } } { - ostringstream text; - text << D[14]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "initval" ); - xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); - { - ostringstream text; - text << initval[0]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << initval[1]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << initval[2]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << initval[3]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << initval[4]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << initval[5]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "initval" ); + xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); + { + ostringstream text; + text << initval[0]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[1]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[2]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[3]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[4]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[5]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[6]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[7]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[8]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[9]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[10]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[11]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[12]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[13]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << initval[14]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k1" ); ostringstream text; - text << initval[6]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << k1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k2" ); + ostringstream text; + text << k2; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "r" ); ostringstream text; - text << initval[7]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << r; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kr" ); ostringstream text; - text << initval[8]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << kr; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "km" ); + ostringstream text; + text << km; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "Pi_tot" ); ostringstream text; - text << initval[9]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << Pi_tot; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "transport" ); ostringstream text; - text << initval[10]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << transport; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "ka" ); + ostringstream text; + text << ka; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_prod" ); ostringstream text; - text << initval[11]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << pin_prod; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_prod_in_epidermis" ); ostringstream text; - text << initval[12]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << pin_prod_in_epidermis; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_breakdown" ); ostringstream text; - text << initval[13]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << pin_breakdown; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_breakdown_internal" ); + ostringstream text; + text << pin_breakdown_internal; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1prod" ); ostringstream text; - text << initval[14]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << aux1prod; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1prodmeso" ); + ostringstream text; + text << aux1prodmeso; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1decay" ); + ostringstream text; + text << aux1decay; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1decaymeso" ); + ostringstream text; + text << aux1decaymeso; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1transport" ); + ostringstream text; + text << aux1transport; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux_cons" ); + ostringstream text; + text << aux_cons; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux_breakdown" ); + ostringstream text; + text << aux_breakdown; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kaux1" ); + ostringstream text; + text << kaux1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kap" ); + ostringstream text; + text << kap; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "leaf_tip_source" ); + ostringstream text; + text << leaf_tip_source; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_efflux" ); + ostringstream text; + text << sam_efflux; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_auxin" ); + ostringstream text; + text << sam_auxin; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_auxin_breakdown" ); + ostringstream text; + text << sam_auxin_breakdown; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3prod" ); + ostringstream text; + text << van3prod; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3autokat" ); + ostringstream text; + text << van3autokat; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3sat" ); + ostringstream text; + text << van3sat; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k2van3" ); + ostringstream text; + text << k2van3; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k1" ); - ostringstream text; - text << k1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k2" ); - ostringstream text; - text << k2; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "r" ); - ostringstream text; - text << r; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kr" ); - ostringstream text; - text << kr; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "km" ); - ostringstream text; - text << km; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "Pi_tot" ); - ostringstream text; - text << Pi_tot; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "transport" ); - ostringstream text; - text << transport; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "ka" ); - ostringstream text; - text << ka; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_prod" ); - ostringstream text; - text << pin_prod; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_prod_in_epidermis" ); - ostringstream text; - text << pin_prod_in_epidermis; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_breakdown" ); - ostringstream text; - text << pin_breakdown; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "pin_breakdown_internal" ); - ostringstream text; - text << pin_breakdown_internal; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1prod" ); - ostringstream text; - text << aux1prod; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1prodmeso" ); - ostringstream text; - text << aux1prodmeso; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1decay" ); - ostringstream text; - text << aux1decay; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1decaymeso" ); - ostringstream text; - text << aux1decaymeso; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux1transport" ); - ostringstream text; - text << aux1transport; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux_cons" ); - ostringstream text; - text << aux_cons; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "aux_breakdown" ); - ostringstream text; - text << aux_breakdown; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kaux1" ); - ostringstream text; - text << kaux1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kap" ); - ostringstream text; - text << kap; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "leaf_tip_source" ); - ostringstream text; - text << leaf_tip_source; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_efflux" ); - ostringstream text; - text << sam_efflux; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_auxin" ); - ostringstream text; - text << sam_auxin; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "sam_auxin_breakdown" ); - ostringstream text; - text << sam_auxin_breakdown; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3prod" ); - ostringstream text; - text << van3prod; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3autokat" ); - ostringstream text; - text << van3autokat; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "van3sat" ); - ostringstream text; - text << van3sat; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k2van3" ); - ostringstream text; - text << k2van3; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dt" ); - ostringstream text; - text << dt; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rd_dt" ); - ostringstream text; - text << rd_dt; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "datadir" ); - ostringstream text; + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dt" ); + ostringstream text; + text << dt; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rd_dt" ); + ostringstream text; + text << rd_dt; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "datadir" ); + ostringstream text; - if (datadir) - text << datadir; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "movie" ); - ostringstream text; -text << sbool(movie); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nit" ); - ostringstream text; - text << nit; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "maxt" ); - ostringstream text; - text << maxt; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "storage_stride" ); - ostringstream text; - text << storage_stride; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "xml_storage_stride" ); - ostringstream text; - text << xml_storage_stride; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rseed" ); - ostringstream text; - text << rseed; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "constituous_expansion_limit" ); - ostringstream text; - text << constituous_expansion_limit; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "vessel_inh_level" ); - ostringstream text; - text << vessel_inh_level; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "vessel_expansion_rate" ); - ostringstream text; - text << vessel_expansion_rate; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "d" ); - ostringstream text; - text << d; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "e" ); - ostringstream text; - text << e; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "f" ); - ostringstream text; - text << f; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "c" ); - ostringstream text; - text << c; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mu" ); - ostringstream text; - text << mu; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nu" ); - ostringstream text; - text << nu; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rho0" ); - ostringstream text; - text << rho0; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rho1" ); - ostringstream text; - text << rho1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "c0" ); - ostringstream text; - text << c0; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "gamma" ); - ostringstream text; - text << gamma; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "eps" ); - ostringstream text; - text << eps; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k" ); - xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); + if (datadir) + text << datadir; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "movie" ); + ostringstream text; + text << sbool(movie); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nit" ); + ostringstream text; + text << nit; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "maxt" ); + ostringstream text; + text << maxt; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "storage_stride" ); + ostringstream text; + text << storage_stride; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "xml_storage_stride" ); + ostringstream text; + text << xml_storage_stride; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rseed" ); + ostringstream text; + text << rseed; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "constituous_expansion_limit" ); ostringstream text; - text << k[0]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << constituous_expansion_limit; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "vessel_inh_level" ); + ostringstream text; + text << vessel_inh_level; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "vessel_expansion_rate" ); + ostringstream text; + text << vessel_expansion_rate; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "d" ); + ostringstream text; + text << d; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "e" ); + ostringstream text; + text << e; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "f" ); + ostringstream text; + text << f; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "c" ); + ostringstream text; + text << c; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mu" ); + ostringstream text; + text << mu; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nu" ); ostringstream text; - text << k[1]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << k[2]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << nu; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { - ostringstream text; - text << k[3]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rho0" ); ostringstream text; - text << k[4]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << k[5]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << k[6]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << rho0; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { - ostringstream text; - text << k[7]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rho1" ); ostringstream text; - text << k[8]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << k[9]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << rho1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "c0" ); ostringstream text; - text << k[10]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << c0; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "gamma" ); ostringstream text; - text << k[11]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << gamma; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "eps" ); ostringstream text; - text << k[12]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << k[13]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + text << eps; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); } { - ostringstream text; - text << k[14]; - xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); - xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k" ); + xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL); + { + ostringstream text; + text << k[0]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[1]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[2]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[3]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[4]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[5]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[6]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[7]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[8]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[9]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[10]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[11]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[12]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[13]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << k[14]; + xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL); + xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str()); + } } -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i1" ); - ostringstream text; - text << i1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i2" ); - ostringstream text; - text << i2; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i3" ); - ostringstream text; - text << i3; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i4" ); - ostringstream text; - text << i4; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i5" ); - ostringstream text; - text << i5; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s1" ); - ostringstream text; - - if (s1) - text << s1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s2" ); - ostringstream text; + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i1" ); + ostringstream text; + text << i1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i2" ); + ostringstream text; + text << i2; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i3" ); + ostringstream text; + text << i3; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i4" ); + ostringstream text; + text << i4; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "i5" ); + ostringstream text; + text << i5; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s1" ); + ostringstream text; - if (s2) - text << s2; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s3" ); - ostringstream text; + if (s1) + text << s1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s2" ); + ostringstream text; + + if (s2) + text << s2; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "s3" ); + ostringstream text; - if (s3) - text << s3; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b1" ); - ostringstream text; -text << sbool(b1); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b2" ); - ostringstream text; -text << sbool(b2); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b3" ); - ostringstream text; -text << sbool(b3); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b4" ); - ostringstream text; -text << sbool(b4); -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dir1" ); - ostringstream text; + if (s3) + text << s3; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b1" ); + ostringstream text; + text << sbool(b1); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b2" ); + ostringstream text; + text << sbool(b2); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b3" ); + ostringstream text; + text << sbool(b3); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "b4" ); + ostringstream text; + text << sbool(b4); + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dir1" ); + ostringstream text; - if (dir1) - text << dir1; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} -{ - xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); - xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dir2" ); - ostringstream text; + if (dir1) + text << dir1; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } + { + xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL); + xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "dir2" ); + ostringstream text; - if (dir2) - text << dir2; -xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); -} + if (dir2) + text << dir2; + xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str()); + } } void Parameter::AssignValToPar(const char *namec, const char *valc) { QLocale standardlocale(QLocale::C); bool ok; -if (!strcmp(namec, "arrowcolor")) { - if (arrowcolor) { free(arrowcolor); } - arrowcolor=strdup(valc); -} -if (!strcmp(namec, "arrowsize")) { - arrowsize = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'arrowsize' from XML file.",valc); } -} -if (!strcmp(namec, "textcolor")) { - if (textcolor) { free(textcolor); } - textcolor=strdup(valc); -} -if (!strcmp(namec, "cellnumsize")) { - cellnumsize = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'cellnumsize' from XML file.",valc); } -} -if (!strcmp(namec, "nodenumsize")) { - nodenumsize = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'nodenumsize' from XML file.",valc); } -} -if (!strcmp(namec, "node_mag")) { - node_mag = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'node_mag' from XML file.",valc); } -} -if (!strcmp(namec, "outlinewidth")) { - outlinewidth = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'outlinewidth' from XML file.",valc); } -} -if (!strcmp(namec, "cell_outline_color")) { - if (cell_outline_color) { free(cell_outline_color); } - cell_outline_color=strdup(valc); -} -if (!strcmp(namec, "resize_stride")) { - resize_stride = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'resize_stride' from XML file.",valc); } -} -if (!strcmp(namec, "T")) { - T = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'T' from XML file.",valc); } -} -if (!strcmp(namec, "lambda_length")) { - lambda_length = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'lambda_length' from XML file.",valc); } -} -if (!strcmp(namec, "lambda_celllength")) { - lambda_celllength = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'lambda_celllength' from XML file.",valc); } -} -if (!strcmp(namec, "target_length")) { - target_length = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'target_length' from XML file.",valc); } -} -if (!strcmp(namec, "cell_expansion_rate")) { - cell_expansion_rate = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'cell_expansion_rate' from XML file.",valc); } -} -if (!strcmp(namec, "cell_div_expansion_rate")) { - cell_div_expansion_rate = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'cell_div_expansion_rate' from XML file.",valc); } -} -if (!strcmp(namec, "auxin_dependent_growth")) { -auxin_dependent_growth = strtobool(valc); -} -if (!strcmp(namec, "ode_accuracy")) { - ode_accuracy = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'ode_accuracy' from XML file.",valc); } -} -if (!strcmp(namec, "mc_stepsize")) { - mc_stepsize = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mc_stepsize' from XML file.",valc); } -} -if (!strcmp(namec, "mc_cell_stepsize")) { - mc_cell_stepsize = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mc_cell_stepsize' from XML file.",valc); } -} -if (!strcmp(namec, "energy_threshold")) { - energy_threshold = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'energy_threshold' from XML file.",valc); } -} -if (!strcmp(namec, "bend_lambda")) { - bend_lambda = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'bend_lambda' from XML file.",valc); } -} -if (!strcmp(namec, "alignment_lambda")) { - alignment_lambda = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'alignment_lambda' from XML file.",valc); } -} -if (!strcmp(namec, "rel_cell_div_threshold")) { - rel_cell_div_threshold = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rel_cell_div_threshold' from XML file.",valc); } -} -if (!strcmp(namec, "rel_perimeter_stiffness")) { - rel_perimeter_stiffness = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rel_perimeter_stiffness' from XML file.",valc); } -} -if (!strcmp(namec, "collapse_node_threshold")) { - collapse_node_threshold = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'collapse_node_threshold' from XML file.",valc); } -} -if (!strcmp(namec, "morphogen_div_threshold")) { - morphogen_div_threshold = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'morphogen_div_threshold' from XML file.",valc); } -} -if (!strcmp(namec, "morphogen_expansion_threshold")) { - morphogen_expansion_threshold = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'morphogen_expansion_threshold' from XML file.",valc); } -} -if (!strcmp(namec, "copy_wall")) { -copy_wall = strtobool(valc); -} -if (!strcmp(namec, "source")) { - source = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'source' from XML file.",valc); } -} -if (!strcmp(namec, "k1")) { - k1 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k1' from XML file.",valc); } -} -if (!strcmp(namec, "k2")) { - k2 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k2' from XML file.",valc); } -} -if (!strcmp(namec, "r")) { - r = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'r' from XML file.",valc); } -} -if (!strcmp(namec, "kr")) { - kr = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kr' from XML file.",valc); } -} -if (!strcmp(namec, "km")) { - km = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'km' from XML file.",valc); } -} -if (!strcmp(namec, "Pi_tot")) { - Pi_tot = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'Pi_tot' from XML file.",valc); } -} -if (!strcmp(namec, "transport")) { - transport = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'transport' from XML file.",valc); } -} -if (!strcmp(namec, "ka")) { - ka = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'ka' from XML file.",valc); } -} -if (!strcmp(namec, "pin_prod")) { - pin_prod = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_prod' from XML file.",valc); } -} -if (!strcmp(namec, "pin_prod_in_epidermis")) { - pin_prod_in_epidermis = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_prod_in_epidermis' from XML file.",valc); } -} -if (!strcmp(namec, "pin_breakdown")) { - pin_breakdown = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_breakdown' from XML file.",valc); } -} -if (!strcmp(namec, "pin_breakdown_internal")) { - pin_breakdown_internal = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_breakdown_internal' from XML file.",valc); } -} -if (!strcmp(namec, "aux1prod")) { - aux1prod = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1prod' from XML file.",valc); } -} -if (!strcmp(namec, "aux1prodmeso")) { - aux1prodmeso = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1prodmeso' from XML file.",valc); } -} -if (!strcmp(namec, "aux1decay")) { - aux1decay = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1decay' from XML file.",valc); } -} -if (!strcmp(namec, "aux1decaymeso")) { - aux1decaymeso = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1decaymeso' from XML file.",valc); } -} -if (!strcmp(namec, "aux1transport")) { - aux1transport = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1transport' from XML file.",valc); } -} -if (!strcmp(namec, "aux_cons")) { - aux_cons = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux_cons' from XML file.",valc); } -} -if (!strcmp(namec, "aux_breakdown")) { - aux_breakdown = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux_breakdown' from XML file.",valc); } -} -if (!strcmp(namec, "kaux1")) { - kaux1 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kaux1' from XML file.",valc); } -} -if (!strcmp(namec, "kap")) { - kap = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kap' from XML file.",valc); } -} -if (!strcmp(namec, "leaf_tip_source")) { - leaf_tip_source = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'leaf_tip_source' from XML file.",valc); } -} -if (!strcmp(namec, "sam_efflux")) { - sam_efflux = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_efflux' from XML file.",valc); } -} -if (!strcmp(namec, "sam_auxin")) { - sam_auxin = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_auxin' from XML file.",valc); } -} -if (!strcmp(namec, "sam_auxin_breakdown")) { - sam_auxin_breakdown = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_auxin_breakdown' from XML file.",valc); } -} -if (!strcmp(namec, "van3prod")) { - van3prod = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3prod' from XML file.",valc); } -} -if (!strcmp(namec, "van3autokat")) { - van3autokat = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3autokat' from XML file.",valc); } -} -if (!strcmp(namec, "van3sat")) { - van3sat = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3sat' from XML file.",valc); } -} -if (!strcmp(namec, "k2van3")) { - k2van3 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k2van3' from XML file.",valc); } -} -if (!strcmp(namec, "dt")) { - dt = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'dt' from XML file.",valc); } -} -if (!strcmp(namec, "rd_dt")) { - rd_dt = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rd_dt' from XML file.",valc); } -} -if (!strcmp(namec, "datadir")) { - if (datadir) { free(datadir); } - datadir=strdup(valc); -} -if (!strcmp(namec, "movie")) { -movie = strtobool(valc); -} -if (!strcmp(namec, "nit")) { - nit = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'nit' from XML file.",valc); } -} -if (!strcmp(namec, "maxt")) { - maxt = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'maxt' from XML file.",valc); } -} -if (!strcmp(namec, "storage_stride")) { - storage_stride = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'storage_stride' from XML file.",valc); } -} -if (!strcmp(namec, "xml_storage_stride")) { - xml_storage_stride = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'xml_storage_stride' from XML file.",valc); } -} -if (!strcmp(namec, "rseed")) { - rseed = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'rseed' from XML file.",valc); } -} -if (!strcmp(namec, "constituous_expansion_limit")) { - constituous_expansion_limit = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'constituous_expansion_limit' from XML file.",valc); } -} -if (!strcmp(namec, "vessel_inh_level")) { - vessel_inh_level = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'vessel_inh_level' from XML file.",valc); } -} -if (!strcmp(namec, "vessel_expansion_rate")) { - vessel_expansion_rate = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'vessel_expansion_rate' from XML file.",valc); } -} -if (!strcmp(namec, "d")) { - d = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'd' from XML file.",valc); } -} -if (!strcmp(namec, "e")) { - e = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'e' from XML file.",valc); } -} -if (!strcmp(namec, "f")) { - f = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'f' from XML file.",valc); } -} -if (!strcmp(namec, "c")) { - c = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'c' from XML file.",valc); } -} -if (!strcmp(namec, "mu")) { - mu = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mu' from XML file.",valc); } -} -if (!strcmp(namec, "nu")) { - nu = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'nu' from XML file.",valc); } -} -if (!strcmp(namec, "rho0")) { - rho0 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rho0' from XML file.",valc); } -} -if (!strcmp(namec, "rho1")) { - rho1 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rho1' from XML file.",valc); } -} -if (!strcmp(namec, "c0")) { - c0 = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'c0' from XML file.",valc); } -} -if (!strcmp(namec, "gamma")) { - gamma = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'gamma' from XML file.",valc); } -} -if (!strcmp(namec, "eps")) { - eps = standardlocale.toDouble(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'eps' from XML file.",valc); } -} -if (!strcmp(namec, "i1")) { - i1 = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i1' from XML file.",valc); } -} -if (!strcmp(namec, "i2")) { - i2 = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i2' from XML file.",valc); } -} -if (!strcmp(namec, "i3")) { - i3 = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i3' from XML file.",valc); } -} -if (!strcmp(namec, "i4")) { - i4 = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i4' from XML file.",valc); } -} -if (!strcmp(namec, "i5")) { - i5 = standardlocale.toInt(valc, &ok); - if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i5' from XML file.",valc); } -} -if (!strcmp(namec, "s1")) { - if (s1) { free(s1); } - s1=strdup(valc); -} -if (!strcmp(namec, "s2")) { - if (s2) { free(s2); } - s2=strdup(valc); -} -if (!strcmp(namec, "s3")) { - if (s3) { free(s3); } - s3=strdup(valc); -} -if (!strcmp(namec, "b1")) { -b1 = strtobool(valc); -} -if (!strcmp(namec, "b2")) { -b2 = strtobool(valc); -} -if (!strcmp(namec, "b3")) { -b3 = strtobool(valc); -} -if (!strcmp(namec, "b4")) { -b4 = strtobool(valc); -} -if (!strcmp(namec, "dir1")) { - if (dir1) { free(dir1); } - dir1=strdup(valc); -} -if (!strcmp(namec, "dir2")) { - if (dir2) { free(dir2); } - dir2=strdup(valc); -} + if (!strcmp(namec, "arrowcolor")) { + if (arrowcolor) { free(arrowcolor); } + arrowcolor=strdup(valc); + } + if (!strcmp(namec, "arrowsize")) { + arrowsize = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'arrowsize' from XML file.",valc); } + } + if (!strcmp(namec, "textcolor")) { + if (textcolor) { free(textcolor); } + textcolor=strdup(valc); + } + if (!strcmp(namec, "cellnumsize")) { + cellnumsize = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'cellnumsize' from XML file.",valc); } + } + if (!strcmp(namec, "nodenumsize")) { + nodenumsize = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'nodenumsize' from XML file.",valc); } + } + if (!strcmp(namec, "node_mag")) { + node_mag = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'node_mag' from XML file.",valc); } + } + if (!strcmp(namec, "outlinewidth")) { + outlinewidth = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'outlinewidth' from XML file.",valc); } + } + if (!strcmp(namec, "cell_outline_color")) { + if (cell_outline_color) { free(cell_outline_color); } + cell_outline_color=strdup(valc); + } + if (!strcmp(namec, "resize_stride")) { + resize_stride = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'resize_stride' from XML file.",valc); } + } + if (!strcmp(namec, "T")) { + T = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'T' from XML file.",valc); } + } + if (!strcmp(namec, "lambda_length")) { + lambda_length = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'lambda_length' from XML file.",valc); } + } + if (!strcmp(namec, "lambda_celllength")) { + lambda_celllength = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'lambda_celllength' from XML file.",valc); } + } + if (!strcmp(namec, "target_length")) { + target_length = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'target_length' from XML file.",valc); } + } + if (!strcmp(namec, "cell_expansion_rate")) { + cell_expansion_rate = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'cell_expansion_rate' from XML file.",valc); } + } + if (!strcmp(namec, "cell_div_expansion_rate")) { + cell_div_expansion_rate = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'cell_div_expansion_rate' from XML file.",valc); } + } + if (!strcmp(namec, "auxin_dependent_growth")) { + auxin_dependent_growth = strtobool(valc); + } + if (!strcmp(namec, "ode_accuracy")) { + ode_accuracy = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'ode_accuracy' from XML file.",valc); } + } + if (!strcmp(namec, "mc_stepsize")) { + mc_stepsize = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mc_stepsize' from XML file.",valc); } + } + if (!strcmp(namec, "mc_cell_stepsize")) { + mc_cell_stepsize = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mc_cell_stepsize' from XML file.",valc); } + } + if (!strcmp(namec, "energy_threshold")) { + energy_threshold = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'energy_threshold' from XML file.",valc); } + } + if (!strcmp(namec, "bend_lambda")) { + bend_lambda = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'bend_lambda' from XML file.",valc); } + } + if (!strcmp(namec, "alignment_lambda")) { + alignment_lambda = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'alignment_lambda' from XML file.",valc); } + } + if (!strcmp(namec, "rel_cell_div_threshold")) { + rel_cell_div_threshold = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rel_cell_div_threshold' from XML file.",valc); } + } + if (!strcmp(namec, "rel_perimeter_stiffness")) { + rel_perimeter_stiffness = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rel_perimeter_stiffness' from XML file.",valc); } + } + if (!strcmp(namec, "collapse_node_threshold")) { + collapse_node_threshold = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'collapse_node_threshold' from XML file.",valc); } + } + if (!strcmp(namec, "morphogen_div_threshold")) { + morphogen_div_threshold = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'morphogen_div_threshold' from XML file.",valc); } + } + if (!strcmp(namec, "morphogen_expansion_threshold")) { + morphogen_expansion_threshold = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'morphogen_expansion_threshold' from XML file.",valc); } + } + if (!strcmp(namec, "copy_wall")) { + copy_wall = strtobool(valc); + } + if (!strcmp(namec, "source")) { + source = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'source' from XML file.",valc); } + } + if (!strcmp(namec, "k1")) { + k1 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k1' from XML file.",valc); } + } + if (!strcmp(namec, "k2")) { + k2 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k2' from XML file.",valc); } + } + if (!strcmp(namec, "r")) { + r = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'r' from XML file.",valc); } + } + if (!strcmp(namec, "kr")) { + kr = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kr' from XML file.",valc); } + } + if (!strcmp(namec, "km")) { + km = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'km' from XML file.",valc); } + } + if (!strcmp(namec, "Pi_tot")) { + Pi_tot = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'Pi_tot' from XML file.",valc); } + } + if (!strcmp(namec, "transport")) { + transport = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'transport' from XML file.",valc); } + } + if (!strcmp(namec, "ka")) { + ka = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'ka' from XML file.",valc); } + } + if (!strcmp(namec, "pin_prod")) { + pin_prod = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_prod' from XML file.",valc); } + } + if (!strcmp(namec, "pin_prod_in_epidermis")) { + pin_prod_in_epidermis = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_prod_in_epidermis' from XML file.",valc); } + } + if (!strcmp(namec, "pin_breakdown")) { + pin_breakdown = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_breakdown' from XML file.",valc); } + } + if (!strcmp(namec, "pin_breakdown_internal")) { + pin_breakdown_internal = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'pin_breakdown_internal' from XML file.",valc); } + } + if (!strcmp(namec, "aux1prod")) { + aux1prod = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1prod' from XML file.",valc); } + } + if (!strcmp(namec, "aux1prodmeso")) { + aux1prodmeso = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1prodmeso' from XML file.",valc); } + } + if (!strcmp(namec, "aux1decay")) { + aux1decay = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1decay' from XML file.",valc); } + } + if (!strcmp(namec, "aux1decaymeso")) { + aux1decaymeso = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1decaymeso' from XML file.",valc); } + } + if (!strcmp(namec, "aux1transport")) { + aux1transport = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux1transport' from XML file.",valc); } + } + if (!strcmp(namec, "aux_cons")) { + aux_cons = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux_cons' from XML file.",valc); } + } + if (!strcmp(namec, "aux_breakdown")) { + aux_breakdown = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'aux_breakdown' from XML file.",valc); } + } + if (!strcmp(namec, "kaux1")) { + kaux1 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kaux1' from XML file.",valc); } + } + if (!strcmp(namec, "kap")) { + kap = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'kap' from XML file.",valc); } + } + if (!strcmp(namec, "leaf_tip_source")) { + leaf_tip_source = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'leaf_tip_source' from XML file.",valc); } + } + if (!strcmp(namec, "sam_efflux")) { + sam_efflux = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_efflux' from XML file.",valc); } + } + if (!strcmp(namec, "sam_auxin")) { + sam_auxin = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_auxin' from XML file.",valc); } + } + if (!strcmp(namec, "sam_auxin_breakdown")) { + sam_auxin_breakdown = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'sam_auxin_breakdown' from XML file.",valc); } + } + if (!strcmp(namec, "van3prod")) { + van3prod = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3prod' from XML file.",valc); } + } + if (!strcmp(namec, "van3autokat")) { + van3autokat = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3autokat' from XML file.",valc); } + } + if (!strcmp(namec, "van3sat")) { + van3sat = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'van3sat' from XML file.",valc); } + } + if (!strcmp(namec, "k2van3")) { + k2van3 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'k2van3' from XML file.",valc); } + } + if (!strcmp(namec, "dt")) { + dt = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'dt' from XML file.",valc); } + } + if (!strcmp(namec, "rd_dt")) { + rd_dt = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rd_dt' from XML file.",valc); } + } + if (!strcmp(namec, "datadir")) { + if (datadir) { free(datadir); } + datadir=strdup(valc); + } + if (!strcmp(namec, "movie")) { + movie = strtobool(valc); + } + if (!strcmp(namec, "nit")) { + nit = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'nit' from XML file.",valc); } + } + if (!strcmp(namec, "maxt")) { + maxt = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'maxt' from XML file.",valc); } + } + if (!strcmp(namec, "storage_stride")) { + storage_stride = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'storage_stride' from XML file.",valc); } + } + if (!strcmp(namec, "xml_storage_stride")) { + xml_storage_stride = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'xml_storage_stride' from XML file.",valc); } + } + if (!strcmp(namec, "rseed")) { + rseed = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'rseed' from XML file.",valc); } + } + if (!strcmp(namec, "constituous_expansion_limit")) { + constituous_expansion_limit = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'constituous_expansion_limit' from XML file.",valc); } + } + if (!strcmp(namec, "vessel_inh_level")) { + vessel_inh_level = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'vessel_inh_level' from XML file.",valc); } + } + if (!strcmp(namec, "vessel_expansion_rate")) { + vessel_expansion_rate = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'vessel_expansion_rate' from XML file.",valc); } + } + if (!strcmp(namec, "d")) { + d = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'd' from XML file.",valc); } + } + if (!strcmp(namec, "e")) { + e = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'e' from XML file.",valc); } + } + if (!strcmp(namec, "f")) { + f = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'f' from XML file.",valc); } + } + if (!strcmp(namec, "c")) { + c = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'c' from XML file.",valc); } + } + if (!strcmp(namec, "mu")) { + mu = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'mu' from XML file.",valc); } + } + if (!strcmp(namec, "nu")) { + nu = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'nu' from XML file.",valc); } + } + if (!strcmp(namec, "rho0")) { + rho0 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rho0' from XML file.",valc); } + } + if (!strcmp(namec, "rho1")) { + rho1 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'rho1' from XML file.",valc); } + } + if (!strcmp(namec, "c0")) { + c0 = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'c0' from XML file.",valc); } + } + if (!strcmp(namec, "gamma")) { + gamma = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'gamma' from XML file.",valc); } + } + if (!strcmp(namec, "eps")) { + eps = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'eps' from XML file.",valc); } + } + if (!strcmp(namec, "i1")) { + i1 = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i1' from XML file.",valc); } + } + if (!strcmp(namec, "i2")) { + i2 = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i2' from XML file.",valc); } + } + if (!strcmp(namec, "i3")) { + i3 = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i3' from XML file.",valc); } + } + if (!strcmp(namec, "i4")) { + i4 = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i4' from XML file.",valc); } + } + if (!strcmp(namec, "i5")) { + i5 = standardlocale.toInt(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to integer while reading parameter 'i5' from XML file.",valc); } + } + if (!strcmp(namec, "s1")) { + if (s1) { free(s1); } + s1=strdup(valc); + } + if (!strcmp(namec, "s2")) { + if (s2) { free(s2); } + s2=strdup(valc); + } + if (!strcmp(namec, "s3")) { + if (s3) { free(s3); } + s3=strdup(valc); + } + if (!strcmp(namec, "b1")) { + b1 = strtobool(valc); + } + if (!strcmp(namec, "b2")) { + b2 = strtobool(valc); + } + if (!strcmp(namec, "b3")) { + b3 = strtobool(valc); + } + if (!strcmp(namec, "b4")) { + b4 = strtobool(valc); + } + if (!strcmp(namec, "dir1")) { + if (dir1) { free(dir1); } + dir1=strdup(valc); + } + if (!strcmp(namec, "dir2")) { + if (dir2) { free(dir2); } + dir2=strdup(valc); + } } void Parameter::AssignValArrayToPar(const char *namec, vector valarray) { -if (!strcmp(namec, "D")) { - int i=0; - vector::const_iterator v=valarray.begin(); - while (v!=valarray.end() && i <= 14 ) { - D[i++]=*(v++); + if (!strcmp(namec, "D")) { + int i=0; + vector::const_iterator v=valarray.begin(); + while (v!=valarray.end() && i <= 14 ) { + D[i++]=*(v++); + } } -} -if (!strcmp(namec, "initval")) { - int i=0; - vector::const_iterator v=valarray.begin(); - while (v!=valarray.end() && i <= 14 ) { - initval[i++]=*(v++); + if (!strcmp(namec, "initval")) { + int i=0; + vector::const_iterator v=valarray.begin(); + while (v!=valarray.end() && i <= 14 ) { + initval[i++]=*(v++); + } } -} -if (!strcmp(namec, "k")) { - int i=0; - vector::const_iterator v=valarray.begin(); - while (v!=valarray.end() && i <= 14 ) { - k[i++]=*(v++); + if (!strcmp(namec, "k")) { + int i=0; + vector::const_iterator v=valarray.begin(); + while (v!=valarray.end() && i <= 14 ) { + k[i++]=*(v++); + } } } -} /* void Parameter::XMLRead(xmlNode *root) { - - xmlNode *cur = root->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ - xmlNode *par_node = cur->xmlChildrenNode; - while (par_node!=NULL) { - { - if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { - xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); - xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); - if (valc) { - AssignValToPar((const char*)namec,(const char*)valc); - } else { - // Probably a valarray - xmlNode *sub_par_node = par_node->xmlChildrenNode; - vector valarray; - while (sub_par_node != NULL) { - if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { - valarray = XMLIO::XMLReadValArray(sub_par_node); - } - sub_par_node = sub_par_node->next; - } - AssignValArrayToPar((const char*)namec, valarray); - } - } - } - par_node = par_node->next; - } - } - cur=cur->next; - } - -}*/ + xmlNode *cur = root->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ + xmlNode *par_node = cur->xmlChildrenNode; + while (par_node!=NULL) { + { + if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { + xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); + xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); + if (valc) { + AssignValToPar((const char*)namec,(const char*)valc); + } else { + // Probably a valarray + xmlNode *sub_par_node = par_node->xmlChildrenNode; + vector valarray; + while (sub_par_node != NULL) { + if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { + valarray = XMLIO::XMLReadValArray(sub_par_node); + } + sub_par_node = sub_par_node->next; + } + AssignValArrayToPar((const char*)namec, valarray); + } + } + } + par_node = par_node->next; + } + + } + cur=cur->next; + } + }*/ ostream &operator<<(ostream &os, Parameter &p) { p.Write(os); diff --git a/src/parameter.h b/src/parameter.h --- a/src/parameter.h +++ b/src/parameter.h @@ -30,7 +30,7 @@ #include class Parameter { - + public: Parameter(); ~Parameter(); diff --git a/src/pardialog.cpp b/src/pardialog.cpp --- a/src/pardialog.cpp +++ b/src/pardialog.cpp @@ -137,7 +137,7 @@ ParameterDialog::ParameterDialog(QWidget dir2_edit = new QLineEdit( QString("%1").arg(par.dir2), this, "dir2_edit" ); // make a 1x1 grid; it will auto-expand QGridLayout *grid = new QGridLayout( this, 1, 1 ); - + // add the first four widgets with (row, column) addressing setWindowTitle( QString( " Parameter values for The Virtual Leaf") ); grid->addWidget( new QLabel( "

Parameter values for The Virtual Leaf

",this), 0, 0, 1, -1, Qt::AlignCenter); @@ -362,108 +362,108 @@ ParameterDialog::ParameterDialog(QWidget }; ParameterDialog::~ParameterDialog(void) { -delete arrowcolor_edit; -delete arrowsize_edit; -delete textcolor_edit; -delete cellnumsize_edit; -delete nodenumsize_edit; -delete node_mag_edit; -delete outlinewidth_edit; -delete cell_outline_color_edit; -delete resize_stride_edit; -delete T_edit; -delete lambda_length_edit; -delete lambda_celllength_edit; -delete target_length_edit; -delete cell_expansion_rate_edit; -delete cell_div_expansion_rate_edit; -delete auxin_dependent_growth_edit; -delete ode_accuracy_edit; -delete mc_stepsize_edit; -delete mc_cell_stepsize_edit; -delete energy_threshold_edit; -delete bend_lambda_edit; -delete alignment_lambda_edit; -delete rel_cell_div_threshold_edit; -delete rel_perimeter_stiffness_edit; -delete collapse_node_threshold_edit; -delete morphogen_div_threshold_edit; -delete morphogen_expansion_threshold_edit; -delete copy_wall_edit; -delete source_edit; -delete D_edit; -delete initval_edit; -delete k1_edit; -delete k2_edit; -delete r_edit; -delete kr_edit; -delete km_edit; -delete Pi_tot_edit; -delete transport_edit; -delete ka_edit; -delete pin_prod_edit; -delete pin_prod_in_epidermis_edit; -delete pin_breakdown_edit; -delete pin_breakdown_internal_edit; -delete aux1prod_edit; -delete aux1prodmeso_edit; -delete aux1decay_edit; -delete aux1decaymeso_edit; -delete aux1transport_edit; -delete aux_cons_edit; -delete aux_breakdown_edit; -delete kaux1_edit; -delete kap_edit; -delete leaf_tip_source_edit; -delete sam_efflux_edit; -delete sam_auxin_edit; -delete sam_auxin_breakdown_edit; -delete van3prod_edit; -delete van3autokat_edit; -delete van3sat_edit; -delete k2van3_edit; -delete dt_edit; -delete rd_dt_edit; -delete datadir_edit; -delete movie_edit; -delete nit_edit; -delete maxt_edit; -delete storage_stride_edit; -delete xml_storage_stride_edit; -delete rseed_edit; -delete constituous_expansion_limit_edit; -delete vessel_inh_level_edit; -delete vessel_expansion_rate_edit; -delete d_edit; -delete e_edit; -delete f_edit; -delete c_edit; -delete mu_edit; -delete nu_edit; -delete rho0_edit; -delete rho1_edit; -delete c0_edit; -delete gamma_edit; -delete eps_edit; -delete k_edit; -delete i1_edit; -delete i2_edit; -delete i3_edit; -delete i4_edit; -delete i5_edit; -delete s1_edit; -delete s2_edit; -delete s3_edit; -delete b1_edit; -delete b2_edit; -delete b3_edit; -delete b4_edit; -delete dir1_edit; -delete dir2_edit; + delete arrowcolor_edit; + delete arrowsize_edit; + delete textcolor_edit; + delete cellnumsize_edit; + delete nodenumsize_edit; + delete node_mag_edit; + delete outlinewidth_edit; + delete cell_outline_color_edit; + delete resize_stride_edit; + delete T_edit; + delete lambda_length_edit; + delete lambda_celllength_edit; + delete target_length_edit; + delete cell_expansion_rate_edit; + delete cell_div_expansion_rate_edit; + delete auxin_dependent_growth_edit; + delete ode_accuracy_edit; + delete mc_stepsize_edit; + delete mc_cell_stepsize_edit; + delete energy_threshold_edit; + delete bend_lambda_edit; + delete alignment_lambda_edit; + delete rel_cell_div_threshold_edit; + delete rel_perimeter_stiffness_edit; + delete collapse_node_threshold_edit; + delete morphogen_div_threshold_edit; + delete morphogen_expansion_threshold_edit; + delete copy_wall_edit; + delete source_edit; + delete D_edit; + delete initval_edit; + delete k1_edit; + delete k2_edit; + delete r_edit; + delete kr_edit; + delete km_edit; + delete Pi_tot_edit; + delete transport_edit; + delete ka_edit; + delete pin_prod_edit; + delete pin_prod_in_epidermis_edit; + delete pin_breakdown_edit; + delete pin_breakdown_internal_edit; + delete aux1prod_edit; + delete aux1prodmeso_edit; + delete aux1decay_edit; + delete aux1decaymeso_edit; + delete aux1transport_edit; + delete aux_cons_edit; + delete aux_breakdown_edit; + delete kaux1_edit; + delete kap_edit; + delete leaf_tip_source_edit; + delete sam_efflux_edit; + delete sam_auxin_edit; + delete sam_auxin_breakdown_edit; + delete van3prod_edit; + delete van3autokat_edit; + delete van3sat_edit; + delete k2van3_edit; + delete dt_edit; + delete rd_dt_edit; + delete datadir_edit; + delete movie_edit; + delete nit_edit; + delete maxt_edit; + delete storage_stride_edit; + delete xml_storage_stride_edit; + delete rseed_edit; + delete constituous_expansion_limit_edit; + delete vessel_inh_level_edit; + delete vessel_expansion_rate_edit; + delete d_edit; + delete e_edit; + delete f_edit; + delete c_edit; + delete mu_edit; + delete nu_edit; + delete rho0_edit; + delete rho1_edit; + delete c0_edit; + delete gamma_edit; + delete eps_edit; + delete k_edit; + delete i1_edit; + delete i2_edit; + delete i3_edit; + delete i4_edit; + delete i5_edit; + delete s1_edit; + delete s2_edit; + delete s3_edit; + delete b1_edit; + delete b2_edit; + delete b3_edit; + delete b4_edit; + delete dir1_edit; + delete dir2_edit; } void ParameterDialog::write(void) { - + extern Parameter par; QString tmpval; par.arrowcolor = strdup((const char *)arrowcolor_edit->text()); @@ -486,7 +486,7 @@ void ParameterDialog::write(void) { else if (tmpval == "false" || tmpval == "no") par.auxin_dependent_growth = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("auxin_dependent_growth"),"True","False", QString::null, 0, 1)==0) par.auxin_dependent_growth=true; - else par.auxin_dependent_growth=false; + else par.auxin_dependent_growth=false; } par.ode_accuracy = ode_accuracy_edit->text().toDouble(); par.mc_stepsize = mc_stepsize_edit->text().toDouble(); @@ -504,7 +504,7 @@ void ParameterDialog::write(void) { else if (tmpval == "false" || tmpval == "no") par.copy_wall = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("copy_wall"),"True","False", QString::null, 0, 1)==0) par.copy_wall=true; - else par.copy_wall=false; + else par.copy_wall=false; } par.source = source_edit->text().toDouble(); tmpval = D_edit->text().section(',', 0, 0); @@ -604,7 +604,7 @@ void ParameterDialog::write(void) { else if (tmpval == "false" || tmpval == "no") par.movie = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("movie"),"True","False", QString::null, 0, 1)==0) par.movie=true; - else par.movie=false; + else par.movie=false; } par.nit = nit_edit->text().toInt(); par.maxt = maxt_edit->text().toDouble(); @@ -668,33 +668,32 @@ void ParameterDialog::write(void) { else if (tmpval == "false" || tmpval == "no") par.b1 = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("b1"),"True","False", QString::null, 0, 1)==0) par.b1=true; - else par.b1=false; + else par.b1=false; } tmpval = b2_edit->text().stripWhiteSpace(); if (tmpval == "true" || tmpval == "yes" ) par.b2 = true; else if (tmpval == "false" || tmpval == "no") par.b2 = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("b2"),"True","False", QString::null, 0, 1)==0) par.b2=true; - else par.b2=false; + else par.b2=false; } tmpval = b3_edit->text().stripWhiteSpace(); if (tmpval == "true" || tmpval == "yes" ) par.b3 = true; else if (tmpval == "false" || tmpval == "no") par.b3 = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("b3"),"True","False", QString::null, 0, 1)==0) par.b3=true; - else par.b3=false; + else par.b3=false; } tmpval = b4_edit->text().stripWhiteSpace(); if (tmpval == "true" || tmpval == "yes" ) par.b4 = true; else if (tmpval == "false" || tmpval == "no") par.b4 = false; else { if (QMessageBox::question(this, "Syntax error", tr("Value %1 of parameter %2 is not recognized as Boolean.\nDo you mean TRUE or FALSE?").arg(tmpval).arg("b4"),"True","False", QString::null, 0, 1)==0) par.b4=true; - else par.b4=false; + else par.b4=false; } par.dir1 = strdup((const char *)dir1_edit->text()); par.dir2 = strdup((const char *)dir2_edit->text()); Reset(); - } void ParameterDialog::Reset(void) { extern Parameter par; diff --git a/src/pardialog.h b/src/pardialog.h --- a/src/pardialog.h +++ b/src/pardialog.h @@ -32,14 +32,14 @@ class ParameterDialog : public QDialog { Q_OBJECT - - public: + + public: ParameterDialog(QWidget *parent=0, const char *name = 0, Qt::WindowFlags f = 0); virtual ~ParameterDialog(void); - public slots: + public slots: void Reset(void); -private slots: + private slots: void write(void); private: diff --git a/src/parse.cpp b/src/parse.cpp --- a/src/parse.cpp +++ b/src/parse.cpp @@ -37,39 +37,38 @@ char *ParsePar(FILE *fp, char *parameter { char *line,*token; char *value; - + line=SearchToken(fp,parameter, wrapflag); if (line==NULL) { warning("Warning: Token %s not found.",parameter); value=0; return value; } - + /* parse the line on = sign */ token=strtok(line,"="); if (token==NULL) { - error("Parse error: no '=' sign found next to token %s, in line: \n %s.", - parameter,line); - } + error("Parse error: no '=' sign found next to token %s, in line: \n %s.", + parameter,line); + } // warning("Reading value for token %s...",token); fprintf(stderr, "[%s = ",token); - + token=strtok(NULL,"="); if (token==NULL) - error("\nParse error: no value found after '=' sign, in line: \n %s", - line); + error("\nParse error: no value found after '=' sign, in line: \n %s", + line); value=strdup(token); free(line); - + return value; - } int igetpar(FILE *fp,char *parameter, bool wrapflag) { - + // overloaded compatibility function. Doesn't need default parameter return igetpar(fp, parameter, 0, wrapflag); @@ -79,7 +78,7 @@ int igetpar(FILE *fp,char *parameter, in { char *token; int value; - + /* Get token representing the value */ token=ParsePar(fp,parameter, wrapflag); @@ -91,15 +90,14 @@ int igetpar(FILE *fp,char *parameter, in /* read it */ sscanf(token,"%d",&value); fprintf(stderr, "%d]\n",value); - + free(token); return value; - } float fgetpar(FILE *fp,char *parameter, bool wrapflag) { - + // overloaded compatibility function. Doesn't need default parameter return fgetpar(fp, parameter, 0., wrapflag); } @@ -120,13 +118,9 @@ float fgetpar(FILE *fp, char *parameter, /* read it */ sscanf(token,"%e",&value); - fprintf(stderr,"%e]\n",value); - free(token); - return value; - } @@ -139,48 +133,47 @@ double *dgetparlist(FILE *fp,char *param int i; value=(double *)malloc(n*sizeof(double)); - + /* Get token representing the value */ token=ParsePar(fp,parameter, wrapflag); - + if (token==0) { error("No token %s found.\n", parameter); } /* parse it */ number=strtok(token,","); /* make a pointer to "token" */ - + i=0; while (number!=NULL) { - + if (i>=n) { error("\nToo many values found for parameterlist '%s' (%d expected).",parameter,n); } - + sscanf(number,"%le",&value[i]); fprintf(stderr,"[%f]",value[i]); - + /* next value */ number=strtok(NULL,","); i++; } - + fprintf(stderr,"]\n"); - + if (i=initial_position)) { /* As long as the search was not wrapped and we are not * back to where we were, continue searching */ - + /* Read a line, and check whether an EOF was found */ if ((line=ReadLine(fp))==NULL) { /* Yes? wrapflag on? => Wrap. */ @@ -328,10 +317,10 @@ char *SearchToken(FILE *fp, char *token, int pos=strspn(line," \t\n"); if (line[pos]=='#') { - + continue; } - + len=strlen(line); if (strlen(tokenplusspace)<=len) { @@ -343,10 +332,8 @@ char *SearchToken(FILE *fp, char *token, return line; } } - free(line); - } free(tokenplusspace); return NULL; /* Token Not Found in the file */ @@ -362,30 +349,29 @@ int TokenInLineP(char *line,char *token) void SkipLine(FILE *fp) { - + /* Just skips a line in FILE *fp */ char *tmpstring; tmpstring=ReadLine(fp); free(tmpstring); - } void SkipToken(FILE *fp,char *token, bool wrapflag) { /* A very simple function: - call SearchToken() and get rid of the memory returned by + call SearchToken() and get rid of the memory returned by it. - Also, return an error if the desired token was not found in the file. + Also, return an error if the desired token was not found in the file. */ char *tmppointer; tmppointer=SearchToken(fp,token, wrapflag); if (tmppointer==NULL) { - error("Token `%s' not found by function SkipToken.\n",token); + error("Token `%s' not found by function SkipToken.\n",token); } free(tmppointer); - } +/* finis */ diff --git a/src/parse.h b/src/parse.h --- a/src/parse.h +++ b/src/parse.h @@ -44,3 +44,5 @@ void SkipLine(FILE *fp); char *bool_str(bool bool_var); #endif + +/* finis */ diff --git a/src/perl/deployapp.pl b/src/perl/deployapp.pl --- a/src/perl/deployapp.pl +++ b/src/perl/deployapp.pl @@ -24,42 +24,42 @@ # get dependencies for executable sub get_frameworks { - my $exec = shift; - my @frameworks = (); - my $fw; + my $exec = shift; + my @frameworks = (); + my $fw; # print "get_frameworks says: exec = $exec\n"; - open deps, "otool -L $exec |"; - # omit first line - ; + open deps, "otool -L $exec |"; + # omit first line + ; - while () { - # look for lines with ".framework", that do not start with / or @. - if (/\.framework/ && !/^[ \t]*\// && !/^[ \t]*\@/) { - chomp; - @line = split; - $f = $line[0]; - # get framework directory name - @line = split(/\//,$f); - for $d (@line) { - if ($d =~ /\.framework/) { - $fw = $d; + while () { + # look for lines with ".framework", that do not start with / or @. + if (/\.framework/ && !/^[ \t]*\// && !/^[ \t]*\@/) { + chomp; + @line = split; + $f = $line[0]; + # get framework directory name + @line = split(/\//,$f); + for $d (@line) { + if ($d =~ /\.framework/) { + $fw = $d; # print "get_framework finds framework $d\n"; - last; - } - } - if (defined($fw)) { + last; + } + } + if (defined($fw)) { # print "get_frameworks pushes $fw on stack\n"; - push @frameworks, $fw; - } - } - } - @frameworks; + push @frameworks, $fw; + } + } + } + @frameworks; } $app = $ARGV[0]; $appdir = $app.".app"; if ($appdir =~ /\.app\.app/) { - $appdir = $ARGV[0]; + $appdir = $ARGV[0]; } $exec = $appdir."/Contents/MacOS/$app"; @@ -73,42 +73,44 @@ if ($appdir =~ /\.app\.app/) { system ("mkdir $appdir/Contents/Frameworks"); for $fw (@frameworks) { - system "cp -R /Library/Frameworks/$fw $appdir/Contents/Frameworks/."; + system "cp -R /Library/Frameworks/$fw $appdir/Contents/Frameworks/."; } # set identification names for the frameworks for $fw (@frameworks) { - $lib = $fw; $lib =~ s/\.framework//g; - system "install_name_tool -id \@executable_path/../Frameworks/$fw/Versions/4.0/$lib $appdir/Contents/Frameworks/$fw/Versions/4.0/$lib"; + $lib = $fw; $lib =~ s/\.framework//g; + system "install_name_tool -id \@executable_path/../Frameworks/$fw/Versions/4.0/$lib $appdir/Contents/Frameworks/$fw/Versions/4.0/$lib"; - - # tell dynamic linker where to look for the frameworks - system "install_name_tool -change $fw/Versions/4/$lib \@executable_path/../Frameworks/$fw/Versions/4.0/$lib $appdir/Contents/MacOs/$app"; - + + # tell dynamic linker where to look for the frameworks + system "install_name_tool -change $fw/Versions/4/$lib \@executable_path/../Frameworks/$fw/Versions/4.0/$lib $appdir/Contents/MacOs/$app"; + } # now, set the frameworks' reciprocal dependencies right for $fw (@frameworks) { - $lib = $fw; $lib =~ s/\.framework//g; - my @frameworks_of_fw = get_frameworks ( "$appdir/Contents/Frameworks/$fw/Versions/4.0/$lib" ); - for $fwfw (@frameworks_of_fw) { + $lib = $fw; $lib =~ s/\.framework//g; + my @frameworks_of_fw = get_frameworks ( "$appdir/Contents/Frameworks/$fw/Versions/4.0/$lib" ); + for $fwfw (@frameworks_of_fw) { # print "$fwfw\n"; - $liblib = $fwfw; $liblib =~ s/\.framework//g; - system "install_name_tool -change $fwfw/Versions/4/$liblib \@executable_path/../Frameworks/$fwfw/Versions/4.0/$liblib $appdir/Contents/Frameworks/$fw/Versions/4.0/$lib"; - } + $liblib = $fwfw; $liblib =~ s/\.framework//g; + system "install_name_tool -change $fwfw/Versions/4/$liblib \@executable_path/../Frameworks/$fwfw/Versions/4.0/$liblib $appdir/Contents/Frameworks/$fw/Versions/4.0/$lib"; + } } # do the same for additional libs not in a framework depending on frameworks (e.g. libqwt...) @additionallibs = ( "libqwt.dylib" ); for $lib (@additionallibs) { - my @frameworks_of_lib = get_frameworks ( "$appdir/Contents/Frameworks/$lib" ); - for $fwfw (@frameworks_of_lib) { - # print "$fwfw\n"; - $liblib = $fwfw; $liblib =~ s/\.framework//g; - system "install_name_tool -change $fwfw/Versions/4/$liblib \@executable_path/../Frameworks/$fwfw/Versions/4.0/$liblib $appdir/Contents/Frameworks/$lib"; - } + my @frameworks_of_lib = get_frameworks ( "$appdir/Contents/Frameworks/$lib" ); + for $fwfw (@frameworks_of_lib) { + # print "$fwfw\n"; + $liblib = $fwfw; $liblib =~ s/\.framework//g; + system "install_name_tool -change $fwfw/Versions/4/$liblib \@executable_path/../Frameworks/$fwfw/Versions/4.0/$liblib $appdir/Contents/Frameworks/$lib"; + } } + +# finis diff --git a/src/perl/histogram.pl b/src/perl/histogram.pl --- a/src/perl/histogram.pl +++ b/src/perl/histogram.pl @@ -29,19 +29,22 @@ for ($i=0;$i<$n_bins;$i++) { - $bins[$i]=0; + $bins[$i]=0; } while (<>) { - @line=split; - $num=$line[0]; - $bin = int($num / $binsize); - # print "[$num, $bin] "; - $bins[$bin]++; + @line=split; + $num=$line[0]; + $bin = int($num / $binsize); + # print "[$num, $bin] "; + $bins[$bin]++; } for ($bin=0;$bin<=$#bins;$bin++) { - $halfwaybin = $bin * $binsize + $binsize/2.; - print $halfwaybin." ".$bins[$bin]."\n"; + $halfwaybin = $bin * $binsize + $binsize/2.; + print $halfwaybin." ".$bins[$bin]."\n"; } + +# finis + diff --git a/src/perl/make_parameter_source.pl b/src/perl/make_parameter_source.pl --- a/src/perl/make_parameter_source.pl +++ b/src/perl/make_parameter_source.pl @@ -28,68 +28,68 @@ # and sample parameter file %funname = ( - "double" => fgetpar, - "float" => fgetpar, - "int" => igetpar, - "bool" => bgetpar, - "char *" => sgetpar, - "string" => sgetpar, - "double *" => dgetparlist, - ); + "double" => fgetpar, + "float" => fgetpar, + "int" => igetpar, + "bool" => bgetpar, + "char *" => sgetpar, + "string" => sgetpar, + "double *" => dgetparlist, + ); %typetrans = ( - "double" => "double", - "float" => "double", - "int" => "int", - "bool" => "bool", - "char *" => "char *", - "string" => "char *", - "directory" => "char *", - "doublelist" => "double *", - "label" => "label", - "title" => "title", -); + "double" => "double", + "float" => "double", + "int" => "int", + "bool" => "bool", + "char *" => "char *", + "string" => "char *", + "directory" => "char *", + "doublelist" => "double *", + "label" => "label", + "title" => "title", + ); open parfile,"<$ARGV[0]"; open cppfile,">parameter.cpp"; $i=0; while () { #ignore comments - if (/^#/) { - next; - } - @line=split(/=/); + if (/^#/) { + next; + } + @line=split(/=/); #ignore empty lines - if ($#line<1) { - next; - } - $param[$i]=$line[0]; - $value_type=$line[1]; + if ($#line<1) { + next; + } + $param[$i]=$line[0]; + $value_type=$line[1]; - @typel=split(/ \/ /,$value_type); - $value[$i] = $typel[0]; - $type[$i] = $typel[1]; - + @typel=split(/ \/ /,$value_type); + $value[$i] = $typel[0]; + $type[$i] = $typel[1]; + #get rid of spaces - $param[$i] =~ s/ //g; - $value[$i] =~ s/ //g; - $type[$i] =~ s/ //g; - $type[$i] =~s/\n//g; - $convtype[$i]=$typetrans{$type[$i]}; + $param[$i] =~ s/ //g; + $value[$i] =~ s/ //g; + $type[$i] =~ s/ //g; + $type[$i] =~s/\n//g; + $convtype[$i]=$typetrans{$type[$i]}; - if ($convtype[$i] eq "char *") { - $value[$i] = "\"$value[$i]\""; - } - #print cppfile "param = $param, value = $value, type = $type\n"; + if ($convtype[$i] eq "char *") { + $value[$i] = "\"$value[$i]\""; + } + #print cppfile "param = $param, value = $value, type = $type\n"; - $i++; + $i++; } $lines=$i; print cppfile < @@ -104,292 +104,292 @@ print cppfile < -using namespace std; + using namespace std; Parameter::Parameter() { -END_HEADER + END_HEADER -for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { - if ($convtype[$i] eq "char *") { - print cppfile " $param[$i] = strdup($value[$i]);\n"; - } else { - if ($convtype[$i] eq "double *") { - #comma separated list expected - @paramlist = split(/,/, $value[$i]); - $length = $#paramlist+1; - print cppfile " $param[$i] = new double\[$length\];\n"; - for ($j=0;$j<=$#paramlist;$j++) { - print cppfile " $param[$i]\[$j\] = $paramlist[$j];\n"; - } - } else { - print cppfile " $param[$i] = $value[$i];\n"; - } + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { + if ($convtype[$i] eq "char *") { + print cppfile " $param[$i] = strdup($value[$i]);\n"; + } else { + if ($convtype[$i] eq "double *") { + #comma separated list expected + @paramlist = split(/,/, $value[$i]); + $length = $#paramlist+1; + print cppfile " $param[$i] = new double\[$length\];\n"; + for ($j=0;$j<=$#paramlist;$j++) { + print cppfile " $param[$i]\[$j\] = $paramlist[$j];\n"; + } + } else { + print cppfile " $param[$i] = $value[$i];\n"; + } + } + } } - } -} -print cppfile < valarray) {\n"; -print cppfile; + print cppfile "void Parameter::AssignValArrayToPar(const char *namec, vector valarray) {\n"; + print cppfile; -for ($i=0;$i<$lines;$i++) { + for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] eq "double *") { - @paramlist = split(/,/,$value[$i]); - print cppfile "if (!strcmp(namec, \"$param[$i]\")) {\n"; - print cppfile " int i=0;\n"; - print cppfile " vector::const_iterator v=valarray.begin();\n"; - print cppfile " while (v!=valarray.end() && i <= $#paramlist ) {\n"; - print cppfile " $param[$i]\[i++\]=*(v++);\n"; - print cppfile " }\n"; - print cppfile "}\n"; - } -} -print cppfile "}\n"; + if ($convtype[$i] eq "double *") { + @paramlist = split(/,/,$value[$i]); + print cppfile "if (!strcmp(namec, \"$param[$i]\")) {\n"; + print cppfile " int i=0;\n"; + print cppfile " vector::const_iterator v=valarray.begin();\n"; + print cppfile " while (v!=valarray.end() && i <= $#paramlist ) {\n"; + print cppfile " $param[$i]\[i++\]=*(v++);\n"; + print cppfile " }\n"; + print cppfile "}\n"; + } + } + print cppfile "}\n"; -print cppfile <xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ - xmlNode *par_node = cur->xmlChildrenNode; - while (par_node!=NULL) { - { - if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { - xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); - xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); - if (valc) { - AssignValToPar((const char*)namec,(const char*)valc); - } else { - // Probably a valarray - xmlNode *sub_par_node = par_node->xmlChildrenNode; - vector valarray; - while (sub_par_node != NULL) { - if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { - valarray = XMLIO::XMLReadValArray(sub_par_node); + /* void Parameter::XMLRead(xmlNode *root) { + + xmlNode *cur = root->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ + xmlNode *par_node = cur->xmlChildrenNode; + while (par_node!=NULL) { + { + if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { + xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); + xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); + if (valc) { + AssignValToPar((const char*)namec,(const char*)valc); + } else { + // Probably a valarray + xmlNode *sub_par_node = par_node->xmlChildrenNode; + vector valarray; + while (sub_par_node != NULL) { + if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { + valarray = XMLIO::XMLReadValArray(sub_par_node); + } + sub_par_node = sub_par_node->next; + } + AssignValArrayToPar((const char*)namec, valarray); + } + } + } + par_node = par_node->next; + } + } - sub_par_node = sub_par_node->next; - } - AssignValArrayToPar((const char*)namec, valarray); + cur=cur->next; } - } - } - par_node = par_node->next; - } + + }*/ - } - cur=cur->next; - } - -}*/ + ostream &operator<<(ostream &os, Parameter &p) { + p.Write(os); + return os; + } -ostream &operator<<(ostream &os, Parameter &p) { - p.Write(os); - return os; -} - -END_TRAILER + END_TRAILER # parameter.h -open hfile, ">parameter.h"; -print hfile <parameter.h"; + print hfile < #include -class Parameter { - - public: - Parameter(); - ~Parameter(); - void CleanUp(void); - void Read(const char *filename); - void Write(ostream &os) const; - void XMLAdd(xmlNode *root) const; - void XMLRead(xmlNode *root); - void AssignValToPar(const char *namec, const char *valc); - void AssignValArrayToPar(const char *namec, vector valarray); -END_HEADER2 + class Parameter { + + public: + Parameter(); + ~Parameter(); + void CleanUp(void); + void Read(const char *filename); + void Write(ostream &os) const; + void XMLAdd(xmlNode *root) const; + void XMLRead(xmlNode *root); + void AssignValToPar(const char *namec, const char *valc); + void AssignValArrayToPar(const char *namec, vector valarray); + END_HEADER2 - for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { - print hfile " $convtype[$i] $param[$i];\n"; - } - } + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { + print hfile " $convtype[$i] $param[$i];\n"; + } + } -print hfile <default.par"; + open parfile,">default.par"; -for ($i=0;$i<$lines;$i++) { - if ($type[$i] ne "title" && $type[$i] ne "label") { - $value[$i] =~ s/\"//g; - print parfile " $param[$i] = $value[$i]\n"; - } -} + for ($i=0;$i<$lines;$i++) { + if ($type[$i] ne "title" && $type[$i] ne "label") { + $value[$i] =~ s/\"//g; + print parfile " $param[$i] = $value[$i]\n"; + } + } + +# finis diff --git a/src/perl/make_pardialog_source.pl b/src/perl/make_pardialog_source.pl --- a/src/perl/make_pardialog_source.pl +++ b/src/perl/make_pardialog_source.pl @@ -28,22 +28,22 @@ # and sample parameter file %funname = ( - "double" => "toDouble", - "int" => "toInt", -); + "double" => "toDouble", + "int" => "toInt", + ); %typetrans = ( - "double" => "double", - "float" => "double", - "int" => "int", - "bool" => "bool", - "char *" => "char *", - "string" => "char *", - "directory" => "char *", - "doublelist" => "double *", - "label" => "label", - "title" => "title", -); + "double" => "double", + "float" => "double", + "int" => "int", + "bool" => "bool", + "char *" => "char *", + "string" => "char *", + "directory" => "char *", + "doublelist" => "double *", + "label" => "label", + "title" => "title", + ); $basename = "pardialog"; @@ -52,36 +52,36 @@ open cppfile,">$basename.cpp"; $i=0; while () { - if (/^#/) { - next; - } - @line=split(/=/); + if (/^#/) { + next; + } + @line=split(/=/); #ignore empty lines - if ($#line<1) { - next; - } - $param[$i]=$line[0]; - $value_type=$line[1]; - - @typel=split(/ \/ /,$value_type); - $value[$i] = $typel[0]; - $type[$i] = $typel[1]; + if ($#line<1) { + next; + } + $param[$i]=$line[0]; + $value_type=$line[1]; + + @typel=split(/ \/ /,$value_type); + $value[$i] = $typel[0]; + $type[$i] = $typel[1]; - #get rid of spaces - $type[$i] =~ s/ //g; - $type[$i] =~s/\n//g; - $convtype[$i]=$typetrans{$type[$i]}; - $param[$i] =~ s/ //g; - if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { - #get rid of spaces - $value[$i] =~ s/ //g; - } - if ($convtype[$i] eq "char *") { - $value[$i] = "\"$value[$i]\""; - } - #print cppfile "param = $param, value = $value, type = $type\n"; + #get rid of spaces + $type[$i] =~ s/ //g; + $type[$i] =~s/\n//g; + $convtype[$i]=$typetrans{$type[$i]}; + $param[$i] =~ s/ //g; + if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { + #get rid of spaces + $value[$i] =~ s/ //g; + } + if ($convtype[$i] eq "char *") { + $value[$i] = "\"$value[$i]\""; + } + #print cppfile "param = $param, value = $value, type = $type\n"; - $i++; + $i++; } $lines=$i; @@ -97,167 +97,167 @@ print cppfile < ParameterDialog::ParameterDialog(QWidget *parent, const char *name, Qt::WindowFlags f) : QDialog(parent,name,false,f) { - extern Parameter par; -END_HEADER + extern Parameter par; + END_HEADER -for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] eq "label" || $convtype[$i] eq "title") { - next; - } - if ($convtype[$i] eq "double *") { - print cppfile " QString $param[$i]_string(\""; - @paramlist = split(/,/,$value[$i]); - for ($j=1;$j<=$#paramlist;$j++) { - print cppfile "%$j,"; + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] eq "label" || $convtype[$i] eq "title") { + next; + } + if ($convtype[$i] eq "double *") { + print cppfile " QString $param[$i]_string(\""; + @paramlist = split(/,/,$value[$i]); + for ($j=1;$j<=$#paramlist;$j++) { + print cppfile "%$j,"; + } + print cppfile "%$j\");\n"; + print cppfile " $param[$i]_string = $param[$i]_string"; + for ($j=0;$j<=$#paramlist;$j++) { + print cppfile ".arg(par.$param[$i]\[$j\])"; + } + print cppfile ";\n"; + print cppfile " $param[$i]_edit = new QLineEdit( $param[$i]_string, this, \"$param[$i]_edit\" );\n"; + } else { + if ($convtype[$i] eq "bool") { + print cppfile " $param[$i]_edit = new QLineEdit( QString(\"%1\").arg(sbool(par.$param[$i])), this, \"$param[$i]_edit\" );\n"; + } else { + print cppfile " $param[$i]_edit = new QLineEdit( QString(\"%1\").arg(par.$param[$i]), this, \"$param[$i]_edit\" );\n"; + } + } } - print cppfile "%$j\");\n"; - print cppfile " $param[$i]_string = $param[$i]_string"; - for ($j=0;$j<=$#paramlist;$j++) { - print cppfile ".arg(par.$param[$i]\[$j\])"; - } - print cppfile ";\n"; - print cppfile " $param[$i]_edit = new QLineEdit( $param[$i]_string, this, \"$param[$i]_edit\" );\n"; - } else { - if ($convtype[$i] eq "bool") { - print cppfile " $param[$i]_edit = new QLineEdit( QString(\"%1\").arg(sbool(par.$param[$i])), this, \"$param[$i]_edit\" );\n"; - } else { - print cppfile " $param[$i]_edit = new QLineEdit( QString(\"%1\").arg(par.$param[$i]), this, \"$param[$i]_edit\" );\n"; - } - } -} -print cppfile <addWidget( new QLabel( \"$value[$i]\", this), $row, $col, 1, 2 );\n"; - $c++; - } else { - if ($convtype[$i] eq "title") { - if ($ntitles) { - print stderr "Sorry, only one title allowed. Aborting source construction...\n"; - exit(1); - } - print cppfile " setWindowTitle( QString( \"$value[$i]\") );\n"; - print cppfile " grid->addWidget( new QLabel( \"

$value[$i]

\",this), $row, $col, 1, -1, Qt::AlignCenter);\n"; - print cppfile " grid->addWidget( new QLabel( \"\", this), $row+1, $col, 1, -1);\n"; - $ntitles++; - } else { - print cppfile " grid->addWidget( new QLabel( \"$param[$i]\", this ),$row, $col );\n"; - print cppfile " grid->addWidget( $param[$i]_edit, $row, $col+1 );\n"; - $c++; + $numrows = 30; + $c = 0; + for ($i=0;$i<$lines;$i++) { + $col = 2*int($c/($numrows-3)); + $row = $c % ($numrows-3) + $ntitles * 3; + if ($convtype[$i] eq "label") { + print cppfile " grid->addWidget( new QLabel( \"$value[$i]\", this), $row, $col, 1, 2 );\n"; + $c++; + } else { + if ($convtype[$i] eq "title") { + if ($ntitles) { + print stderr "Sorry, only one title allowed. Aborting source construction...\n"; + exit(1); + } + print cppfile " setWindowTitle( QString( \"$value[$i]\") );\n"; + print cppfile " grid->addWidget( new QLabel( \"

$value[$i]

\",this), $row, $col, 1, -1, Qt::AlignCenter);\n"; + print cppfile " grid->addWidget( new QLabel( \"\", this), $row+1, $col, 1, -1);\n"; + $ntitles++; + } else { + print cppfile " grid->addWidget( new QLabel( \"$param[$i]\", this ),$row, $col );\n"; + print cppfile " grid->addWidget( $param[$i]_edit, $row, $col+1 );\n"; + $c++; + } + } } - } -} -$row = $numrows+1; -$col = 2*int($i/$numrows); + $row = $numrows+1; + $col = 2*int($i/$numrows); -print cppfile <addWidget(pb, $row, $col ); - connect( pb, SIGNAL( clicked() ), this, SLOT( write() ) ); - QPushButton *pb2 = new QPushButton( \"&Close\", this ); - grid->addWidget(pb2,$row, $col+1 ); - connect( pb2, SIGNAL( clicked() ), this, SLOT( close() ) ); - QPushButton *pb3 = new QPushButton( \"&Reset\", this ); - grid->addWidget(pb3, $row, $col+2 ); - connect( pb3, SIGNAL( clicked() ), this, SLOT( Reset() ) ); - show(); + print cppfile <addWidget(pb, $row, $col ); + connect( pb, SIGNAL( clicked() ), this, SLOT( write() ) ); + QPushButton *pb2 = new QPushButton( \"&Close\", this ); + grid->addWidget(pb2,$row, $col+1 ); + connect( pb2, SIGNAL( clicked() ), this, SLOT( close() ) ); + QPushButton *pb3 = new QPushButton( \"&Reset\", this ); + grid->addWidget(pb3, $row, $col+2 ); + connect( pb3, SIGNAL( clicked() ), this, SLOT( Reset() ) ); + show(); }; ParameterDialog::~ParameterDialog(void) { -ANOTHER_LABEL + ANOTHER_LABEL -for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { - print cppfile "delete $param[$i]_edit;\n"; - } -} + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { + print cppfile "delete $param[$i]_edit;\n"; + } + } -print cppfile <text().section(',', $j, $j);\n"; - print cppfile " par.$param[$i]\[$j\] = tmpval.toDouble();\n"; - } - } else { - if ($convtype[$i] eq "bool") { - print cppfile " tmpval = $param[$i]_edit->text().stripWhiteSpace();\n"; - print cppfile " if (tmpval == \"true\" || tmpval == \"yes\" ) par.$param[$i] = true;\n"; - print cppfile " else if (tmpval == \"false\" || tmpval == \"no\") par.$param[$i] = false;\n"; - print cppfile " else {\n"; - print cppfile " if (QMessageBox::question(this, \"Syntax error\", tr(\"Value %1 of parameter %2 is not recognized as Boolean.\\nDo you mean TRUE or FALSE?\").arg(tmpval).arg(\"$param[$i]\"),\"True\",\"False\", QString::null, 0, 1)==0) par.$param[$i]=true;\n"; - print cppfile " else par.$param[$i]=false;\n"; - print cppfile " }\n"; - } else { - if ($convtype[$i] eq "char *") { - print cppfile " par.$param[$i] = strdup((const char *)$param[$i]_edit->text());\n"; - } else { - print cppfile " par.$param[$i] = $param[$i]_edit->text().$funname{$convtype[$i]}();\n"; - } - } - } -} + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] eq "label" || $convtype[$i] eq "title") { + next; + } + if ($convtype[$i] eq "double *") { + @paramlist = split(/,/,$value[$i]); + for ($j=0;$j<=$#paramlist;$j++) { + print cppfile " tmpval = $param[$i]_edit->text().section(',', $j, $j);\n"; + print cppfile " par.$param[$i]\[$j\] = tmpval.toDouble();\n"; + } + } else { + if ($convtype[$i] eq "bool") { + print cppfile " tmpval = $param[$i]_edit->text().stripWhiteSpace();\n"; + print cppfile " if (tmpval == \"true\" || tmpval == \"yes\" ) par.$param[$i] = true;\n"; + print cppfile " else if (tmpval == \"false\" || tmpval == \"no\") par.$param[$i] = false;\n"; + print cppfile " else {\n"; + print cppfile " if (QMessageBox::question(this, \"Syntax error\", tr(\"Value %1 of parameter %2 is not recognized as Boolean.\\nDo you mean TRUE or FALSE?\").arg(tmpval).arg(\"$param[$i]\"),\"True\",\"False\", QString::null, 0, 1)==0) par.$param[$i]=true;\n"; + print cppfile " else par.$param[$i]=false;\n"; + print cppfile " }\n"; + } else { + if ($convtype[$i] eq "char *") { + print cppfile " par.$param[$i] = strdup((const char *)$param[$i]_edit->text());\n"; + } else { + print cppfile " par.$param[$i] = $param[$i]_edit->text().$funname{$convtype[$i]}();\n"; + } + } + } + } -print cppfile <setText( $param[$i]_string );\n"; + } else { + if ($convtype[$i] eq "bool") { + print cppfile " $param[$i]_edit->setText( QString(\"%1\").arg(sbool(par.$param[$i])));\n"; + } else { + print cppfile " $param[$i]_edit->setText( QString(\"%1\").arg(par.$param[$i]) );\n"; + } } - print cppfile ";\n"; - print cppfile " $param[$i]_edit->setText( $param[$i]_string );\n"; - } else { - if ($convtype[$i] eq "bool") { - print cppfile " $param[$i]_edit->setText( QString(\"%1\").arg(sbool(par.$param[$i])));\n"; - } else { - print cppfile " $param[$i]_edit->setText( QString(\"%1\").arg(par.$param[$i]) );\n"; - } - } } print cppfile "}\n\n"; @@ -276,28 +276,29 @@ print hfile < class ParameterDialog : public QDialog { - Q_OBJECT - - public: - ParameterDialog(QWidget *parent=0, const char *name = 0, Qt::WindowFlags f = 0); - virtual ~ParameterDialog(void); - public slots: - void Reset(void); + Q_OBJECT + + public: + ParameterDialog(QWidget *parent=0, const char *name = 0, Qt::WindowFlags f = 0); + virtual ~ParameterDialog(void); + public slots: + void Reset(void); -private slots: - void write(void); + private slots: + void write(void); - private: -END_HEADER2 + private: + END_HEADER2 -for ($i=0;$i<$lines;$i++) { - if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { - print hfile " QLineEdit *$param[$i]_edit;\n"; - } -} + for ($i=0;$i<$lines;$i++) { + if ($convtype[$i] ne "label" && $convtype[$i] ne "title") { + print hfile " QLineEdit *$param[$i]_edit;\n"; + } + } -print hfile <) { - chomp; - push @projectfiles, $_; + chomp; + push @projectfiles, $_; } if ($#projectfiles > 0) { - print stderr "Oops, I found several project files: "; - for $p (@projectfiles) { - print stderr "$p "; - } - print stderr "\n"; - print stderr "Please make sure you have only one, and try again\n"; - exit(1); + print stderr "Oops, I found several project files: "; + for $p (@projectfiles) { + print stderr "$p "; + } + print stderr "\n"; + print stderr "Please make sure you have only one, and try again\n"; + exit(1); } if ($#projectfiles < 0) { - print stderr "No project files found. Please add a project file.\n"; - exit(1); + print stderr "No project files found. Please add a project file.\n"; + exit(1); } $project = $projectfiles[0]; @@ -64,35 +64,35 @@ print stderr "Using project file \"$proj open pfile,"<$project"; my @targets = (); while () { - if (/^[ \t]*TARGET/) { - my @line = split(/=/); - my $target = $line[1]; - chomp $target; - $target =~ s/[ \t]//g; - push @targets, $target; - } - if (/^[ \t]*REACTIONS/) { - my @line = split(/=/); - my $reaction = $line[1]; - chomp $reaction; - $reaction =~ s/[ \t]//g; - push @reactions, $reaction; - } + if (/^[ \t]*TARGET/) { + my @line = split(/=/); + my $target = $line[1]; + chomp $target; + $target =~ s/[ \t]//g; + push @targets, $target; + } + if (/^[ \t]*REACTIONS/) { + my @line = split(/=/); + my $reaction = $line[1]; + chomp $reaction; + $reaction =~ s/[ \t]//g; + push @reactions, $reaction; + } } if ($#targets > 0) { - print stderr "Too many targets found: "; - for $t (@targets) { - print stderr "$t "; - } - print stderr "\n"; - exit(1); + print stderr "Too many targets found: "; + for $t (@targets) { + print stderr "$t "; + } + print stderr "\n"; + exit(1); } if ($#targets < 0) { - print stderr "No targets found in project $project\n"; - exit(1); + print stderr "No targets found in project $project\n"; + exit(1); } $target = $targets[0]; @@ -100,17 +100,17 @@ if ($#targets < 0) { print "Target is $target\n"; if ($#reactions > 0) { - print stderr "Too many reactions found: "; - for $t (@reactions) { - print stderr "$t "; - } - print stderr "\n"; - exit(1); + print stderr "Too many reactions found: "; + for $t (@reactions) { + print stderr "$t "; + } + print stderr "\n"; + exit(1); } if ($#reactions < 0) { - print stderr "No reactions found in project $project\n"; - exit(1); + print stderr "No reactions found in project $project\n"; + exit(1); } $reaction = $reactions[0]; @@ -171,53 +171,54 @@ print xmlsrc <) { - chomp; - s/\\/\\\\/g; - s/\"/\\\"/g; - s/\&/\&/g; - $str.=$_."\\n"; - } - $str .= "\";\n"; - return $str; -} + my $fname = shift; + my $str = ""; + + open srcfile, "<$fname"; + while () { + chomp; + s/\\/\\\\/g; + s/\"/\\\"/g; + s/\&/\&/g; + $str.=$_."\\n"; + } + $str .= "\";\n"; + return $str; + } -print xmlsrc "xmlChar *sourcecode = (xmlChar *)\"".construct_string_constant_from_file( "$mainsource" ); - print xmlsrc <setPen(pen()); - // Draw arrow head - p->drawLine( end, arwp1 ); - p->drawLine( end, arwp2 ); - // Draw arrow line - p->drawLine( start, end); - } + + p->setPen(pen()); + // Draw arrow head + p->drawLine( end, arwp1 ); + p->drawLine( end, arwp2 ); + // Draw arrow line + p->drawLine( start, end); + } }; #endif + +/* finis */ diff --git a/src/random.cpp b/src/random.cpp --- a/src/random.cpp +++ b/src/random.cpp @@ -44,7 +44,7 @@ double RANDOM(void) counter++; long mj,mk; int i,ii,k; - + if (idum < 0 || iff == 0) { iff=1; mj=MSEED-(idum < 0 ? -idum : idum); @@ -86,9 +86,9 @@ int Seed(int seed) { if (seed < 0) { int rseed=Randomize(); - #ifdef QDEBUG +#ifdef QDEBUG qDebug() << "Randomizing random generator, seed is " << rseed << endl; - #endif +#endif return rseed; } else { int i; @@ -106,12 +106,12 @@ int Seed(int seed) **/ long RandomNumber(long max) { - return((long)(RANDOM()*max+1)); + return((long)(RANDOM()*max+1)); } /*! Interactively ask for the seed -\param void -\return void + \param void + \return void **/ void AskSeed(void) { @@ -127,18 +127,18 @@ int RandomCounter(void) { } /*! Make a random seed based on the local time -\param void -\return void + \param void + \return void **/ int Randomize(void) { - + // Set the seed according to the local time struct timeb t; int seed; ftime(&t); - + seed=abs((int)((t.time*t.millitm)%655337)); Seed(seed); #ifdef QDEBUG @@ -147,3 +147,4 @@ int Randomize(void) { return seed; } +/* finis */ diff --git a/src/random.h b/src/random.h --- a/src/random.h +++ b/src/random.h @@ -42,25 +42,22 @@ int RandomCounter(void); // Class MyUrand, so we can pass the random generator to STL's random_shuffle, // and get identical simulations for a given random seed. class MyUrand { - + long n; public: MyUrand(long nn) { n=nn; } MyUrand(void){}; - + void seed(long s) { Seed(s); } - + long operator()(long nn) { return RandomNumber(nn)-1; } long operator()(void) { return RandomNumber(n); } }; - - +#endif - - -#endif +/* finis */ diff --git a/src/rseed.cpp b/src/rseed.cpp --- a/src/rseed.cpp +++ b/src/rseed.cpp @@ -27,7 +27,8 @@ static const std::string _module_id("$Id int main() { - long rseed=Randomize(); - std::cout << rseed << "\n"; + long rseed=Randomize(); + std::cerr << rseed << std::endl; +} -} +/* finis */ diff --git a/src/rungekutta.cpp b/src/rungekutta.cpp --- a/src/rungekutta.cpp +++ b/src/rungekutta.cpp @@ -31,13 +31,13 @@ static const std::string _module_id("$Id // The value Errcon equals (5/Safety) raised to the power (1/PGrow), see use below. /* -static float maxarg1,maxarg2; -#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\ -(maxarg1) : (maxarg2)) -static float minarg1,minarg2; -#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\ -(minarg1) : (minarg2)) -#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) + static float maxarg1,maxarg2; + #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\ + (maxarg1) : (maxarg2)) + static float minarg1,minarg2; + #define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\ + (minarg1) : (minarg2)) + #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) */ const double RungeKutta::Safety = 0.9; @@ -46,9 +46,9 @@ const double RungeKutta::Pshrnk = -0.25; const double RungeKutta::Errcon = 1.89e-4; const double RungeKutta::Maxstp = 10000; const double RungeKutta::Tiny = 1.0e-30; - + void RungeKutta::rkqs(double *y, double *dydx, int n, double *x, double htry, double eps, - double *yscal, double *hdid, double *hnext) + double *yscal, double *hdid, double *hnext) /* Fifth-order Runge-Kutta step with monitoring of local truncation error to ensure accuracy and adjust stepsize. Input are the dependent variable vector y[1..n] and its derivative dydx[1..n] at the starting value of the independent variable x. Also input are the stepsize to be attempted @@ -61,7 +61,7 @@ void RungeKutta::rkqs(double *y, double double errmax,h,htemp,xnew,*yerr,*ytemp; yerr=new double[n]; ytemp=new double[n]; - + h=htry; // Set stepsize to the initial trial value. for (;;) { rkck(y,dydx,n,*x,h,ytemp,yerr); // Take a step. @@ -85,7 +85,6 @@ void RungeKutta::rkqs(double *y, double for (i=0;i 0.0) h=x2-x;// If stepsize can overshoot, decrease. - + rkqs(y,dydx,nvar,&x,h,eps,yscal,&hdid,&hnext); if (hdid == h) ++(*nok); else ++(*nbad); if ((x-x2)*(x2-x1) >= 0.0) { //Are we done? @@ -203,3 +202,5 @@ void RungeKutta::odeint(double *ystart, } MyWarning::error("Too many steps in routine odeint"); } + +/* finis */ diff --git a/src/rungekutta.h b/src/rungekutta.h --- a/src/rungekutta.h +++ b/src/rungekutta.h @@ -35,21 +35,21 @@ class RungeKutta { yp=0; } virtual ~RungeKutta() {} - + void odeint(double ystart[], int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad); - + protected: // implement "derivs" in a derived class virtual void derivs(double x, double *y, double *dxdy) = 0; int kmax,kount; double *xp,**yp,dxsav; - + private: void rkqs(double *y, double *dydx, int n, double *x, double htry, double eps, - double *yscal, double *hdid, double *hnext); - + double *yscal, double *hdid, double *hnext); + void rkck(double *y, double *dydx, int n, double x, double h, double yout[], double *yerr); @@ -59,7 +59,7 @@ class RungeKutta { static const double Errcon; static const double Maxstp; static const double Tiny; - - }; #endif + +/* finis */ diff --git a/src/simitembase.cpp b/src/simitembase.cpp --- a/src/simitembase.cpp +++ b/src/simitembase.cpp @@ -25,14 +25,18 @@ static const std::string _module_id("$Id$"); -SimItemBase::SimItemBase( void *v, QGraphicsScene *canvas ) { +SimItemBase::SimItemBase( void *v, QGraphicsScene *canvas ) +{ canvas = NULL; // use assignment merely to obviate compilation warning - obj=v; + obj=v; }; SimItemBase::~SimItemBase(void) {}; -void SimItemBase::userMove(double dx, double dy) { +void SimItemBase::userMove(double dx, double dy) +{ dx = dy = 0.0; // use assignment merely to obviate compilation warning }; + +/* finis */ diff --git a/src/simitembase.h b/src/simitembase.h --- a/src/simitembase.h +++ b/src/simitembase.h @@ -40,28 +40,30 @@ TYPE class_cast(void * symbol) void * symbol; TYPE unknownclass; } cast; - + cast.symbol = symbol; return cast.unknownclass; } class SimItemBase { -public: + public: SimItemBase( void *v, QGraphicsScene *canvas ); virtual ~SimItemBase(void); virtual void userMove(double dx, double dy); - + protected: // I know which simulation object I represent, so if I am moved around // the canvas, the real object can be moved as well - + // (both Cell and Node have Vector as base class...) // Not proper design... sorry. - + void *obj; - }; +}; #endif + +/* finis */ diff --git a/src/simplugin.cpp b/src/simplugin.cpp --- a/src/simplugin.cpp +++ b/src/simplugin.cpp @@ -24,12 +24,14 @@ static const std::string _module_id("$Id$"); -void SimPluginInterface::SetParameters(Parameter *pass_pars) { - par = pass_pars; +void SimPluginInterface::SetParameters(Parameter *pass_pars) +{ + par = pass_pars; } void SimPluginInterface::SetCellsStaticDatamembers( CellsStaticDatamembers *cells_static_data_members_of_main) { - CellBase::static_data_members = cells_static_data_members_of_main; + CellBase::static_data_members = cells_static_data_members_of_main; } +/* finis */ diff --git a/src/simplugin.h b/src/simplugin.h --- a/src/simplugin.h +++ b/src/simplugin.h @@ -38,45 +38,44 @@ class Parameter; class SimPluginInterface { -public: - virtual QString ModelID(void) = 0; - - virtual ~SimPluginInterface() { } + public: + virtual QString ModelID(void) = 0; + + virtual ~SimPluginInterface() { } + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping(CellBase *c) = 0; + + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(Wall *, double *dchem_c1, double *dchem_c2) = 0; + + // Differential equations describing chemical reactions taking place at or near the cell walls + // (e.g. PIN accumulation) + virtual void WallDynamics(Wall *w, double *dw1, double *dw) = 0; - // Executed after the cellular mechanics steps have equillibrized - virtual void CellHouseKeeping(CellBase *c) = 0; - - // Differential equations describing transport of chemicals from cell to cell - virtual void CelltoCellTransport(Wall *, double *dchem_c1, double *dchem_c2) = 0; - - // Differential equations describing chemical reactions taking place at or near the cell walls - // (e.g. PIN accumulation) - virtual void WallDynamics(Wall *w, double *dw1, double *dw) = 0; - - // Differential equations describing chemical reactions inside the cells - virtual void CellDynamics(CellBase *c, double *dchem) = 0; + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem) = 0; + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) = 0; + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color) = 0; - // to be executed after a cell division - virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) = 0; - - // to be executed for coloring a cell - virtual void SetCellColor(CellBase *c, QColor *color) = 0; - - // Number of chemicals - virtual int NChem(void) = 0; - - // For internal use; not to be redefined by end users - virtual void SetParameters(Parameter *pass_pars);// { par = pass_pars; } - virtual void SetCellsStaticDatamembers (CellsStaticDatamembers *cells_static_data_members_of_main); + // Number of chemicals + virtual int NChem(void) = 0; -protected: - class Parameter *par; - + // For internal use; not to be redefined by end users + virtual void SetParameters(Parameter *pass_pars);// { par = pass_pars; } + virtual void SetCellsStaticDatamembers (CellsStaticDatamembers *cells_static_data_members_of_main); + + protected: + class Parameter *par; }; -Q_DECLARE_INTERFACE(SimPluginInterface, - "nl.cwi.VirtualLeaf.SimPluginInterface/1.2") +Q_DECLARE_INTERFACE(SimPluginInterface, "nl.cwi.VirtualLeaf.SimPluginInterface/1.2") Q_DECLARE_METATYPE(SimPluginInterface *) +#endif -#endif \ No newline at end of file +/* finis */ diff --git a/src/sqr.h b/src/sqr.h --- a/src/sqr.h +++ b/src/sqr.h @@ -34,20 +34,22 @@ // However, they seem to work, but it seems safer to redefine them. // Inline functions will behave like macros anyhow. inline double DSQR( double a ) { - + if (a == 0.0) { return 0.0; } else { return a*a; } - } inline float SQR( float a ) { - if (a == 0.0) { + if (a == 0.0) { return 0.0; } else { return a*a; } } + #endif + +/* finis */ diff --git a/src/tiny.h b/src/tiny.h --- a/src/tiny.h +++ b/src/tiny.h @@ -28,3 +28,5 @@ #define TINY 1e-5 #endif + +/* finis */ diff --git a/src/transporterdialog.cpp b/src/transporterdialog.cpp --- a/src/transporterdialog.cpp +++ b/src/transporterdialog.cpp @@ -41,8 +41,9 @@ TransporterDialog::TransporterDialog(Wal // compose a label for the dialog box std::stringstream label_text; - label_text << "C("<< wall->C1()->Index() << "," << wall->C2()->Index() << "), N(" << wall->N1()->Index() << "," << wall->N2()->Index() << ")"; - + label_text << "C("<< wall->C1()->Index() << "," << wall->C2()->Index() << "), N(" + << wall->N1()->Index() << "," << wall->N2()->Index() << ")"; + // retrieve the current transporters QVector transporters; // transporter vector ntransporters = cell->NChem(); // size of transporter vector @@ -86,13 +87,13 @@ TransporterDialog::TransporterDialog(Wal setWindowTitle(tr(label_text.str().c_str())); } -void TransporterDialog::setTransporterValues(){ - +void TransporterDialog::setTransporterValues() +{ // iterate over the editor widgets soliciting their values and setting the wall's transporters accordingly. for (int i=0; itext().toDouble() << endl; - #endif +#endif if (wall_num == 1) wall->setTransporters1(i, editors[i]->text().toDouble()); else @@ -102,5 +103,6 @@ void TransporterDialog::setTransporterVa close(); } -// finis +/* finis */ + diff --git a/src/transporterdialog.h b/src/transporterdialog.h --- a/src/transporterdialog.h +++ b/src/transporterdialog.h @@ -37,12 +37,12 @@ class CellBase; class TransporterDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: TransporterDialog(Wall *w, CellBase *c, int wn, QWidget *parent = 0); - private slots: + private slots: void setTransporterValues(); private: @@ -55,3 +55,5 @@ class TransporterDialog : public QDialog }; #endif + +/* finis */ diff --git a/src/vector.cpp b/src/vector.cpp --- a/src/vector.cpp +++ b/src/vector.cpp @@ -34,27 +34,24 @@ static const std::string _module_id("$Id$"); void Vector::operator=(const Vector &source) { - + // assignment - + // don't assign to self if (this==&source) return; - + x=source.x; y=source.y; z=source.z; - } - - - ostream &Vector::print(ostream &os) const { os << "(" << x << ", " << y << ", " << z << ")"; return os; } + ostream &operator<<(ostream &os, const Vector &v) { v.print(os); return os; @@ -62,75 +59,67 @@ ostream &operator<<(ostream &os, const V Vector Vector::operator+(const Vector &v) const { - + Vector result; result.x=x+v.x; result.y=y+v.y; result.z=z+v.z; - + return result; - } Vector& Vector::operator-=(const Vector &v) { - + x-=v.x; y-=v.y; z-=v.z; - + return *this; - } Vector Vector::operator/(const double divisor) const { - - + + Vector result; - + result.x=x/divisor; result.y=y/divisor; result.z=z/divisor; return result; - - } Vector Vector::operator*(const double multiplier) const { Vector result; - + result.x=x*multiplier; result.y=y*multiplier; result.z=z*multiplier; return result; - - } Vector operator*(const double multiplier, const Vector &v) { Vector result; - + result.x=v.x*multiplier; result.y=v.y*multiplier; result.z=v.z*multiplier; return result; - } Vector &Vector::operator/=(const double divisor) { x/=divisor; y/=divisor; z/=divisor; - + return *this; - } Vector &Vector::operator*=(const double multiplier) { @@ -140,21 +129,18 @@ Vector &Vector::operator*=(const double z*=multiplier; return *this; - } Vector Vector::operator*(const Vector &v) const { - + // cross product ("uitproduct") Vector result; - + result.x=y*v.z-z*v.y; result.y=z*v.x-x*v.z; result.z=x*v.y-y*v.x; - + return result; - - } @@ -164,146 +150,137 @@ double InnerProduct(const Vector &v1, co double result; result=v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; return result; - } double Vector::Angle(const Vector &v) const { - + // angle between this vector and another vector - + // angle is within range of [0,pi] radians - + // angle is arccosine of the inner product over the product of the norms of the vectors - + double cos_angle=InnerProduct(*this,v)/(Norm()*v.Norm()); - + // check for computational inaccuracies if (cos_angle<=-1) return Pi; - + if (cos_angle>=1) return 0.; - + double angle=acos(cos_angle); - + return angle; - } double Vector::SignedAngle(const Vector &v) const { - + // angle between this vector and another vector - + // angle is within range of [-pi,pi] radians - + // angle is arccosine of the inner product over the product of the norms of the vectors - + double cos_angle=InnerProduct(*this,v)/(Norm()*v.Norm()); - + // check for computational inaccuracies if (cos_angle<=-1) return Pi; - + if (cos_angle>=1) return 0.; - + double angle=acos(cos_angle); - + double sign = (InnerProduct ( Perp2D(), v ) )>0.?1.:-1.; return angle * sign; - } bool Vector::operator==(const Vector &v) const { - + // "sloppy equal" if ((fabs(x-v.x)0.) { // if the norm is 0, don't normalise // (otherwise division by zero occurs) - + (*this)/=norm; } - } Vector Vector::Normalised(void) const { - + double norm; norm=Norm(); // Absolute value; - + if (norm>0.) { // if the norm is 0, don't normalise // (otherwise division by zero occurs) return (*this)/norm; } else { return *this; } - } bool Vector::SameDirP(const Vector &v) { - + // return true if the two (parallel) vectors point in the same direction // if (x*v.x>=0 && y*v.y>=0 && z*v.z>=0) double angle=Angle(v); - + if (angle<(Pi/2)) return true; else return false; - } double Vector::Max(void) { - + // Find maximum value of vector double max; - + max=x > y ? x : y; max=max > z ? max : z; - + return max; } double Vector::Min(void) { - + // Find minimum value of vector double min; - + min=x < y ? x : y; min=min < z ? min : z; - + return min; } @@ -312,30 +289,30 @@ double Vector::Min(void) { #ifdef TEST void main() { - + Vector v(1.,2.,3.); - + Vector d; - + d=5*v; - -// cerr << d << "\n"; - + + // cerr << d << "\n"; + d=v*5; - -// cerr << d << "\n"; - + + // cerr << d << "\n"; + d=v/5; - -// cerr << d << "\n"; -// cerr << d.Norm() << "\n"; - + // cerr << d << "\n"; + + // cerr << d.Norm() << "\n"; + d.Normalise(); - -// cerr << d << " " << d.Norm() << "\n"; - - + + // cerr << d << " " << d.Norm() << "\n"; } #endif + +/* finis */ diff --git a/src/vector.h b/src/vector.h --- a/src/vector.h +++ b/src/vector.h @@ -29,7 +29,7 @@ #include #include "sqr.h" #ifdef QTGRAPHICS - #include +#include #endif // three dimensional vector @@ -37,7 +37,7 @@ using namespace std; class Vector { -public: + public: inline Vector(const double cx=0,const double cy=0,const double cz=0) { x=cx; y=cy; @@ -57,16 +57,16 @@ public: /* } */ inline Vector(const Vector &source) { - + // copy constructor - + x=source.x; y=source.y; z=source.z; - + } // type conversion from and to QPointF (2D vector class from Qt library; we throw away "z" here!!) - #ifdef QTGRAPHICS +#ifdef QTGRAPHICS inline operator QPointF() const { return QPointF( x, y ); } @@ -75,7 +75,7 @@ public: y = p.y(); z = 0.; } - #endif +#endif virtual ~Vector() { }; @@ -89,28 +89,26 @@ public: } Vector operator+(const Vector &v) const; // addition inline Vector operator-(const Vector &v) const { - + Vector result; - + result.x=x-v.x; result.y=y-v.y; result.z=z-v.z; - + return result; - } Vector &operator-=(const Vector &v); - + inline Vector &operator+=(const Vector &v) { - + x+=v.x; y+=v.y; z+=v.z; - + return *this; - } - + Vector operator/(const double divisor) const; // division by a double Vector operator*(const double multiplier) const; // multiply by a scalar (double) Vector &operator/=(const double divisor); @@ -119,9 +117,8 @@ public: bool operator==(const Vector &v) const; // comparison bool operator< (const Vector &v) const; // order x,y,z inline double Norm(void) const { - + return sqrt(DSQR(x)+DSQR(y)+DSQR(z)); - } // Quick and dirty Norm (i.e. Manhattan distance) @@ -129,7 +126,7 @@ public: inline double ManhattanNorm(void) const { return x+y+z; } - + double SqrNorm(void) const; // gives the square of |v| void Normalise(void); // normalise myself Vector Normalised(void) const; // return me normalised @@ -141,6 +138,7 @@ public: Vector Perp2D(void) const { return Vector(y,-x,0); } + // data members double x,y,z; @@ -150,8 +148,7 @@ public: void ReadDump(istream &is) { is >> x >> y >> z; } -private: - + private: }; ostream &operator<<(ostream &os, const Vector &v); @@ -159,3 +156,5 @@ Vector operator*(const double multiplier double InnerProduct(const Vector &v1, const Vector &v2); #endif + +/* finis */ diff --git a/src/vleafmodel.h b/src/vleafmodel.h --- a/src/vleafmodel.h +++ b/src/vleafmodel.h @@ -37,3 +37,5 @@ #include "flux_function.h" #endif + +/* finis */ diff --git a/src/wall.cpp b/src/wall.cpp --- a/src/wall.cpp +++ b/src/wall.cpp @@ -31,201 +31,192 @@ static const std::string _module_id("$Id$"); /*! Check if this Wall still belongs to Cell a, otherwise gives it to Cell b. - \return true: Wall was corrected - \return false: Wall was still correct - */ + \return true: Wall was corrected + \return false: Wall was still correct +*/ bool Wall::CorrectWall( void ) { - - - // collect all cells to which my nodes are connected on one list - list owners; - transform(n1->owners.begin(),n1->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); - transform(n2->owners.begin(),n2->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); - - // get the list of duplicates - list wall_owners; - owners.sort(); - //transform(owners.begin(), owners.end(), ostream_iterator(cerr, ", "), mem_fun(&Cell::Index)); - duplicates_copy( owners.begin(), owners.end(), back_inserter(wall_owners) ); - - // duplicates are the cells to which the Wall belongs - // For the first division, wall finds three "owners", including the boundary_polygon. - // Remove that one from the list. - //cerr << "wall_owners.size() = " << wall_owners.size() << endl; - if (wall_owners.size() == 3 && nwalls==1 /* bug-fix 22/10/2007; confine this condition to first division only */) { - - #ifdef QDEBUG - qDebug() << "nwalls = " << nwalls << endl; - #endif - // special case for first cleavage - - // find boundary polygon in the wall owners list - list::iterator bpit = find_if ( - wall_owners.begin(), wall_owners.end(), - mem_fun( &CellBase::BoundaryPolP ) - ); - - if (bpit!=wall_owners.end()) { - - // add a Wall with the boundary_polygon to each cell - Wall *bp_wall1 = new Wall( n2, n1, c1, (*bpit) ); - bp_wall1->CopyWallContents(*this); - ((Cell *)c1)->AddWall( bp_wall1); - ((Cell *)(*bpit))->AddWall(bp_wall1); - - Wall *bp_wall2 = new Wall( n1, n2, c2, (*bpit) ); - bp_wall2->CopyWallContents(*this); - ((Cell *)c2)->AddWall( bp_wall2); - ((Cell *)(*bpit))->AddWall(bp_wall2); - - wall_owners.erase(bpit); - - }else { + + + // collect all cells to which my nodes are connected on one list + list owners; + transform(n1->owners.begin(),n1->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); + transform(n2->owners.begin(),n2->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); + + // get the list of duplicates + list wall_owners; + owners.sort(); + //transform(owners.begin(), owners.end(), ostream_iterator(cerr, ", "), mem_fun(&Cell::Index)); + duplicates_copy( owners.begin(), owners.end(), back_inserter(wall_owners) ); + + // duplicates are the cells to which the Wall belongs + // For the first division, wall finds three "owners", including the boundary_polygon. + // Remove that one from the list. + //cerr << "wall_owners.size() = " << wall_owners.size() << endl; + if (wall_owners.size() == 3 && nwalls==1 /* bug-fix 22/10/2007; confine this condition to first division only */) { + +#ifdef QDEBUG + qDebug() << "nwalls = " << nwalls << endl; +#endif + // special case for first cleavage + + // find boundary polygon in the wall owners list + list::iterator bpit = find_if ( + wall_owners.begin(), wall_owners.end(), + mem_fun( &CellBase::BoundaryPolP ) + ); + if (bpit!=wall_owners.end()) { + + // add a Wall with the boundary_polygon to each cell + Wall *bp_wall1 = new Wall( n2, n1, c1, (*bpit) ); + bp_wall1->CopyWallContents(*this); + ((Cell *)c1)->AddWall( bp_wall1); + ((Cell *)(*bpit))->AddWall(bp_wall1); + + Wall *bp_wall2 = new Wall( n1, n2, c2, (*bpit) ); + bp_wall2->CopyWallContents(*this); + ((Cell *)c2)->AddWall( bp_wall2); + ((Cell *)(*bpit))->AddWall(bp_wall2); + + wall_owners.erase(bpit); + + }else { + +#ifdef QDEBUG + qDebug() << "Wall::CorrectWall says: Wall has three owners, but none of them is the BoundaryPolygon. I have no clue what to do with this case... Sorry!" << endl; + qDebug() << "Wall: " << *this << endl; + qDebug() << "Owners are: "; + transform(wall_owners.begin(), wall_owners.end(), ostream_iterator(qDebug(), " "), mem_fun (&CellBase::Index) ); + qDebug() << endl; + qDebug() << "Owners node " << n1->Index() << ": "; - #ifdef QDEBUG - qDebug() << "Wall::CorrectWall says: Wall has three owners, but none of them is the BoundaryPolygon. I have no clue what to do with this case... Sorry!" << endl; - qDebug() << "Wall: " << *this << endl; - qDebug() << "Owners are: "; - transform(wall_owners.begin(), wall_owners.end(), ostream_iterator(qDebug(), " "), mem_fun (&CellBase::Index) ); - qDebug() << endl; - qDebug() << "Owners node " << n1->Index() << ": "; - for (list::iterator i = n1->owners.begin(); i!=n1->owners.end(); i++) { - qDebug() << i->getCell()->Index() << " "; - } - qDebug() << endl; - qDebug() << "Owners node " << n2->Index() << ": "; - - for (list::iterator i = n2->owners.begin(); i!=n2->owners.end(); i++) { - qDebug() << i->getCell()->Index() << " "; - } - qDebug() << endl; - #endif - std::exit(1); - } - - } - - #ifdef QDEBUG - if (wall_owners.size() == 1) { - qDebug() << "Corner point. Special case." << endl; - } - #endif - - CellBase *cell1 = wall_owners.front(); - CellBase *cell2 = wall_owners.back(); - - if ( (c1 == cell1 && c2==cell2) || (c1 == cell2 && c2 == cell1) ) { - - return false; + for (list::iterator i = n1->owners.begin(); i!=n1->owners.end(); i++) { + qDebug() << i->getCell()->Index() << " "; + } + + qDebug() << endl; + qDebug() << "Owners node " << n2->Index() << ": "; + + for (list::iterator i = n2->owners.begin(); i!=n2->owners.end(); i++) { + qDebug() << i->getCell()->Index() << " "; + } + qDebug() << endl; +#endif + std::exit(1); + } + } + +#ifdef QDEBUG + if (wall_owners.size() == 1) { + qDebug() << "Corner point. Special case." << endl; + } +#endif + + CellBase *cell1 = wall_owners.front(); + CellBase *cell2 = wall_owners.back(); + + if ( (c1 == cell1 && c2==cell2) || (c1 == cell2 && c2 == cell1) ) { + + return false; + } + + if ( c1 == cell1 ) { + //cerr << "Block 1\n"; + ((Cell *)c2) -> RemoveWall(this); + c2 = cell2; + ((Cell *)c2) -> AddWall(this); + } else { + if ( c1 == cell2 ) { + // cerr << "Block 2\n"; + ((Cell *)c2) -> RemoveWall(this); + c2 = cell1; + ((Cell *)c2) -> AddWall(this); + } else { + if ( c2 == cell1) { + ((Cell *)c1)->RemoveWall(this); + c1 = cell2; + ((Cell *)c1) -> AddWall(this); + // cerr << "Block 3\n"; + } else { + if ( c2 == cell2) { + ((Cell *)c1)->RemoveWall(this); + c1 = cell1; + ((Cell *)c1)->AddWall(this); + // cerr << "Block 3\n"; + } else { +#ifdef QDEBUG + qDebug() << "Warning, cell wall was not corrected." << endl; +#endif + return false; } - - if ( c1 == cell1 ) { - //cerr << "Block 1\n"; - ((Cell *)c2) -> RemoveWall(this); - c2 = cell2; - ((Cell *)c2) -> AddWall(this); - } else { - if ( c1 == cell2 ) { - // cerr << "Block 2\n"; - ((Cell *)c2) -> RemoveWall(this); - c2 = cell1; - ((Cell *)c2) -> AddWall(this); - } else { - if ( c2 == cell1) { - ((Cell *)c1)->RemoveWall(this); - c1 = cell2; - ((Cell *)c1) -> AddWall(this); - // cerr << "Block 3\n"; - } else { - if ( c2 == cell2) { - ((Cell *)c1)->RemoveWall(this); - c1 = cell1; - ((Cell *)c1)->AddWall(this); - // cerr << "Block 3\n"; - } else { - #ifdef QDEBUG - qDebug() << "Warning, cell wall was not corrected." << endl; - #endif - return false; - } - } - } - } - - return true; - - - - + } + } + } + return true; } void Wall::Draw(QGraphicsScene *c) { - - WallItem *wi1 = new WallItem(this, 1, c); - WallItem *wi2 = new WallItem(this, 2, c); - wi1->show(); - wi2->show(); - + + WallItem *wi1 = new WallItem(this, 1, c); + WallItem *wi2 = new WallItem(this, 2, c); + wi1->show(); + wi2->show(); } void Wall::DrawApoplast(QGraphicsScene *c) { - ApoplastItem *apo = new ApoplastItem(this, c); - apo->show(); - + ApoplastItem *apo = new ApoplastItem(this, c); + apo->show(); } void Wall::ShowStructure(QGraphicsScene *c) { - - Vector offset = Cell::Offset(); - double factor = Cell::Factor(); - - Vector startpoint ( ((offset.x+n1->x)*factor),((offset.y+n1->y)*factor)), + + Vector offset = Cell::Offset(); + double factor = Cell::Factor(); + + Vector startpoint ( ((offset.x+n1->x)*factor),((offset.y+n1->y)*factor)), endpoint (((offset.x+n2->x)*factor),((offset.y+n2->y)*factor)); - - Vector linevec = endpoint - startpoint; - Vector midline = startpoint + linevec/2.; - Vector perpvec = linevec.Normalised().Perp2D(); - Vector textpos1 = midline + 100 * perpvec; - Vector textpos2 = midline - 100 * perpvec; - - QGraphicsLineItem *line = new QGraphicsLineItem(0,c); - - line->setPen( QPen(QColor(par.arrowcolor),2) ); - line->setLine(startpoint.x, startpoint.y, endpoint.x, endpoint.y ); - line->setZValue(10); - line->show(); - - QGraphicsSimpleTextItem *text1 = new QGraphicsSimpleTextItem( QString("%1").arg(c2->Index()),0,c); - QGraphicsSimpleTextItem *text2 = new QGraphicsSimpleTextItem( QString("%1").arg(c1->Index()),0,c); - - text1 -> setPos( textpos1.x, textpos1.y ); - text2 -> setPos( textpos2.x, textpos2.y ); - text1->setZValue(20); text2->setZValue(20); - - text1->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); - text2->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); - - text1->setPen ( QColor(par.textcolor) ); - text2->setPen ( text1->pen() ); - text1->show(); text2->show(); - + + Vector linevec = endpoint - startpoint; + Vector midline = startpoint + linevec/2.; + Vector perpvec = linevec.Normalised().Perp2D(); + Vector textpos1 = midline + 100 * perpvec; + Vector textpos2 = midline - 100 * perpvec; + + QGraphicsLineItem *line = new QGraphicsLineItem(0,c); + + line->setPen( QPen(QColor(par.arrowcolor),2) ); + line->setLine(startpoint.x, startpoint.y, endpoint.x, endpoint.y ); + line->setZValue(10); + line->show(); + + QGraphicsSimpleTextItem *text1 = new QGraphicsSimpleTextItem( QString("%1").arg(c2->Index()),0,c); + QGraphicsSimpleTextItem *text2 = new QGraphicsSimpleTextItem( QString("%1").arg(c1->Index()),0,c); + + text1 -> setPos( textpos1.x, textpos1.y ); + text2 -> setPos( textpos2.x, textpos2.y ); + text1->setZValue(20); text2->setZValue(20); + + text1->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); + text2->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); + + text1->setPen ( QColor(par.textcolor) ); + text2->setPen ( text1->pen() ); + text1->show(); text2->show(); } string Wall::WallTypetoStr(const WallType &wt) const { - - if (wt == Normal) { - return string("normal"); - } - - if (wt == AuxSource) { - return string("aux_source"); - } - - if (wt == AuxSink) { - return string("aux_sink"); - } - - return string(""); + + if (wt == Normal) { + return string("normal"); + } + + if (wt == AuxSource) { + return string("aux_source"); + } + + if (wt == AuxSink) { + return string("aux_sink"); + } + + return string(""); } - - +/* finis */ diff --git a/src/wall.h b/src/wall.h --- a/src/wall.h +++ b/src/wall.h @@ -33,31 +33,29 @@ class Wall : public WallBase { -public: - Wall(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2) : WallBase(sn1, sn2, sc1, sc2) {} - - - void XMLAdd(xmlNodePtr parent_node) const; - bool CorrectWall(void); + public: + Wall(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2) : WallBase(sn1, sn2, sc1, sc2) {} + + + void XMLAdd(xmlNodePtr parent_node) const; + bool CorrectWall(void); + - - // Graphics: - //! Visualize transport protein concentrations - void Draw(QGraphicsScene *c); - - //! Visualize contents of the apoplast - void DrawApoplast(QGraphicsScene *c); - /*! \brief Visualize the structure of the wall (Cell ID's etc.). - Used for debugging purposes. - */ - void ShowStructure(QGraphicsScene *c); + // Graphics: + //! Visualize transport protein concentrations + void Draw(QGraphicsScene *c); -private: - string WallTypetoStr(const WallType &wt) const; - - - - + //! Visualize contents of the apoplast + void DrawApoplast(QGraphicsScene *c); + /*! \brief Visualize the structure of the wall (Cell ID's etc.). + Used for debugging purposes. + */ + void ShowStructure(QGraphicsScene *c); + + private: + string WallTypetoStr(const WallType &wt) const; }; #endif + +/* finis */ diff --git a/src/wallbase.cpp b/src/wallbase.cpp --- a/src/wallbase.cpp +++ b/src/wallbase.cpp @@ -42,235 +42,233 @@ static const std::string _module_id("$Id int WallBase::nwalls=0; ostream &WallBase::print(ostream &os) const { - os << "{ " << n1->Index() << "->" << n2->Index() - << ", " << c1->Index() << " | " << c2->Index() << "} "; - return os; + os << "{ " << n1->Index() << "->" << n2->Index() + << ", " << c1->Index() << " | " << c2->Index() << "} "; + return os; } ostream &operator<<(ostream &os, const WallBase &w) { - w.print(os); - return os; + w.print(os); + return os; } -WallBase::WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2) { - - #ifdef QDEBUG - if (sc1==sc2) { - qDebug() << "Attempting to build a wall between identical cells: " << sc1->Index() << endl; - } - #endif - - c1 = sc1; - c2 = sc2; - - n1 = sn1; - n2 = sn2; - - transporters1 = new double[CellBase::NChem()]; - transporters2 = new double[CellBase::NChem()]; - new_transporters1 = new double[CellBase::NChem()]; - new_transporters2 = new double[CellBase::NChem()]; - - for (int i=0;iIndex() << endl; + } +#endif + + c1 = sc1; + c2 = sc2; + + n1 = sn1; + n2 = sn2; + + transporters1 = new double[CellBase::NChem()]; + transporters2 = new double[CellBase::NChem()]; + new_transporters1 = new double[CellBase::NChem()]; + new_transporters2 = new double[CellBase::NChem()]; + + for (int i=0;itransporters1[i]; - src->transporters1[i]=transporters1[i]; - transporters1[i]=tmp; - - } - if (transporters2) { - double tmp; - tmp=src->transporters2[i]; - src->transporters2[i]=transporters2[i]; - transporters2[i]=tmp; - } - if (new_transporters1) { - double tmp; - tmp=src->new_transporters1[i]; - src->new_transporters1[i]=new_transporters1[i]; - new_transporters1[i]=tmp; - } - if (new_transporters2) { - double tmp; - tmp=src->new_transporters2[i]; - src->new_transporters2[i]=new_transporters2[i]; - new_transporters2[i]=tmp; - } - - if (apoplast) { - double tmp; - tmp=src->apoplast[i]; - src->apoplast[i]=apoplast[i]; - apoplast[i]=tmp; - } - } - bool tmp_bool; - tmp_bool = src->dead; - src->dead=dead; - dead = tmp_bool; - - WallType tmp_wall_type; - tmp_wall_type = src->wall_type; - src->wall_type = wall_type; - wall_type = tmp_wall_type; - +void WallBase::SwapWallContents(WallBase *src) +{ + + for (int i=0; itransporters1[i]; + src->transporters1[i]=transporters1[i]; + transporters1[i]=tmp; + + } + if (transporters2) { + double tmp; + tmp=src->transporters2[i]; + src->transporters2[i]=transporters2[i]; + transporters2[i]=tmp; + } + if (new_transporters1) { + double tmp; + tmp=src->new_transporters1[i]; + src->new_transporters1[i]=new_transporters1[i]; + new_transporters1[i]=tmp; + } + if (new_transporters2) { + double tmp; + tmp=src->new_transporters2[i]; + src->new_transporters2[i]=new_transporters2[i]; + new_transporters2[i]=tmp; + } + + if (apoplast) { + double tmp; + tmp=src->apoplast[i]; + src->apoplast[i]=apoplast[i]; + apoplast[i]=tmp; + } + } + bool tmp_bool; + tmp_bool = src->dead; + src->dead=dead; + dead = tmp_bool; + + WallType tmp_wall_type; + tmp_wall_type = src->wall_type; + src->wall_type = wall_type; + wall_type = tmp_wall_type; } -bool WallBase::SAM_P(void) { - - return N1()->sam || N2()->sam; - +bool WallBase::SAM_P(void) +{ + return N1()->sam || N2()->sam; } #include -void WallBase::SetLength(void) { - - //static bool show_nodes = true; - - //double old_length = length; - // Step 1: find the path of nodes leading along the WallBase. - // A WallBase often represents a curved cell wall: we want the total - // length _along_ the wall here... - - // Locate first and second nodes of the edge in Cell's list of nodes - list::const_iterator first_node_edge = find(c1->nodes.begin(), c1->nodes.end(), n1); - list::const_iterator second_node_edge_plus_1 = ++find(c1->nodes.begin(), c1->nodes.end(), n2); - - // wrap around - if (second_node_edge_plus_1 == c1->nodes.end()) { - second_node_edge_plus_1 = c1->nodes.begin(); - } - - - length = 0.; - - // Now, walk to the second node of the edge in the list of nodes - stringstream deb_str; - - for (list::const_iterator n= - (++first_node_edge==c1->nodes.end()?c1->nodes.begin():first_node_edge); - n!=second_node_edge_plus_1; - (++n == c1->nodes.end()) ? (n=c1->nodes.begin()):n ) { - - list::const_iterator prev_n = n; - if (prev_n==c1->nodes.begin()) prev_n=c1->nodes.end(); - --prev_n; - - //cerr << "Node: " << (Vector)(**n) << endl; - - // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h - - - deb_str << "[ " << (*prev_n)->index << " to " << (*n)->index << "]"; - - length += (*(*prev_n) - *(*n)).Norm(); - - } +void WallBase::SetLength(void) +{ + + // Step 1: find the path of nodes leading along the WallBase. + // A WallBase often represents a curved cell wall: we want the total + // length _along_ the wall here... + + // Locate first and second nodes of the edge in Cell's list of nodes + list::const_iterator first_node_edge = find(c1->nodes.begin(), c1->nodes.end(), n1); + list::const_iterator second_node_edge_plus_1 = ++find(c1->nodes.begin(), c1->nodes.end(), n2); + + // wrap around + if (second_node_edge_plus_1 == c1->nodes.end()) { + second_node_edge_plus_1 = c1->nodes.begin(); + } + + + length = 0.; + + // Now, walk to the second node of the edge in the list of nodes + stringstream deb_str; + + for (list::const_iterator n= + (++first_node_edge==c1->nodes.end()?c1->nodes.begin():first_node_edge); + n!=second_node_edge_plus_1; + (++n == c1->nodes.end()) ? (n=c1->nodes.begin()):n ) { + + list::const_iterator prev_n = n; + if (prev_n==c1->nodes.begin()) prev_n=c1->nodes.end(); + --prev_n; + + //cerr << "Node: " << (Vector)(**n) << endl; + + // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h + + deb_str << "[ " << (*prev_n)->index << " to " << (*n)->index << "]"; + length += (*(*prev_n) - *(*n)).Norm(); + } } -void WallBase::CorrectTransporters(double orig_length) { - - double length_factor = length / orig_length; +void WallBase::CorrectTransporters(double orig_length) +{ + + double length_factor = length / orig_length; - for (int ch=0;ch p2 -bool WallBase::IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2) { - - // Algorithm of http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ - double x1 = n1->x, y1 = n1->y; - double x2 = n2->x, y2 = n2->y; - double x3 = p1.x, y3 = p1.y; - double x4 = p2.x, y4 = p2.y; - - double ua = ( (x4 - x3) * (y1-y3) - (y4 - y3)*(x1-x3) ) / ( (y4 -y3) * (x2 -x1) - (x4-x3)*(y2-y1)); - - // If ua is between 0 and 1, line p1 intersects the line segment - if ( ua >=0. && ua <=1.) return true; - else return false; - +bool WallBase::IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2) +{ + + // Algorithm of http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ + double x1 = n1->x, y1 = n1->y; + double x2 = n2->x, y2 = n2->y; + double x3 = p1.x, y3 = p1.y; + double x4 = p2.x, y4 = p2.y; + + double ua = ( (x4 - x3) * (y1-y3) - (y4 - y3)*(x1-x3) ) / ( (y4 -y3) * (x2 -x1) - (x4-x3)*(y2-y1)); + + // If ua is between 0 and 1, line p1 intersects the line segment + if ( ua >=0. && ua <=1.) return true; + else return false; } +/* finis */ diff --git a/src/wallbase.h b/src/wallbase.h --- a/src/wallbase.h +++ b/src/wallbase.h @@ -28,12 +28,8 @@ #include #include - - - #include "vector.h" - class Node; class CellBase; @@ -41,161 +37,165 @@ using namespace std; // warning, touches original sequence template Out duplicates_copy(In first, In last, Out res) { - - In i = adjacent_find(first, last); - - while (i!=last) { - res++ = *i; - i = adjacent_find(++i, last); - } - - return res; + + In i = adjacent_find(first, last); + + while (i!=last) { + res++ = *i; + i = adjacent_find(++i, last); + } + + return res; } /*! \class WallBase. A cell wall, which runs between cell "corner points", - and consists of wall elements. */ + and consists of wall elements. */ class WallBase { - -protected: - friend class CellBase; - friend class Cell; - friend class Mesh; - //! Cells to which the wall belongs - CellBase *c1, *c2; - - //! A list of transporter protein concentrations associated with the wall - double *transporters1, *transporters2; - double *new_transporters1, *new_transporters2; - - bool IllegalP(void) { return c1 == c2; } - - //! The chemicals in the apoplast at this position - double *apoplast; - - //! Pointers to the wall's corner nodes - Node *n1, *n2; - - double length; - - double viz_flux; - - // bool aux_source; - - bool dead; - // disallow usage of empty constructor - WallBase(void) {} - - - enum WallType {Normal, AuxSource, AuxSink}; - static int nwalls; -protected: - int wall_index; - WallType wall_type; - + + protected: + friend class CellBase; + friend class Cell; + friend class Mesh; + //! Cells to which the wall belongs + CellBase *c1, *c2; + + //! A list of transporter protein concentrations associated with the wall + double *transporters1, *transporters2; + double *new_transporters1, *new_transporters2; + + bool IllegalP(void) { return c1 == c2; } + + //! The chemicals in the apoplast at this position + double *apoplast; + + //! Pointers to the wall's corner nodes + Node *n1, *n2; + + double length; + + double viz_flux; + + // bool aux_source; + + bool dead; + // disallow usage of empty constructor + WallBase(void) {} + + + enum WallType {Normal, AuxSource, AuxSink}; + static int nwalls; + protected: + int wall_index; + WallType wall_type; + + + public: + WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2); -public: - WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2); - - // shallow copy - WallBase(const WallBase &src) { - c1 = src.c1; - c2 = src.c2; - transporters1 = src.transporters1; - transporters2 = src.transporters2; - new_transporters1 = src.new_transporters1; - new_transporters2 = src.new_transporters2; - apoplast = src.apoplast; - n1 = src.n1; - n2 = src.n2; - length = src.length; - viz_flux = src.viz_flux; - dead = src.dead; - wall_index = src.wall_index; - } - - inline int Index(void) const { return wall_index;} - inline bool DeadP(void) const { return dead; } - inline void Kill(void) { dead = true; } - // deep copying of chemicals and transporters - void CopyWallContents(const WallBase &src); - void SwapWallContents(WallBase *src); - bool is_wall_of_cell_p ( const CellBase *c ) { - return (c1==c || c2==c); + // shallow copy + WallBase(const WallBase &src) { + c1 = src.c1; + c2 = src.c2; + transporters1 = src.transporters1; + transporters2 = src.transporters2; + new_transporters1 = src.new_transporters1; + new_transporters2 = src.new_transporters2; + apoplast = src.apoplast; + n1 = src.n1; + n2 = src.n2; + length = src.length; + viz_flux = src.viz_flux; + dead = src.dead; + wall_index = src.wall_index; + } + + inline int Index(void) const { return wall_index;} + inline bool DeadP(void) const { return dead; } + inline void Kill(void) { dead = true; } + // deep copying of chemicals and transporters + void CopyWallContents(const WallBase &src); + void SwapWallContents(WallBase *src); + bool is_wall_of_cell_p ( const CellBase *c ) { + return (c1==c || c2==c); + } + + inline CellBase *C1(void) const { return c1; } + inline CellBase *C2(void) const { return c2; } + inline Node *N1(void) const { return n1; } + inline Node *N2(void) const { return n2; } + inline void setTransporters1(int ch, double val) { transporters1[ch]=val; } + inline void setTransporters2(int ch, double val) { transporters2[ch]=val; } + inline void setNewTransporters1(int ch, double val) { new_transporters1[ch]=val; } + inline void setNewTransporters2(int ch, double val) { new_transporters2[ch]=val; } + inline double Transporters1(int ch) { return transporters1[ch]; } + inline double Transporters2(int ch) { return transporters2[ch]; } + + //! Return true if the WallBase adheres to the SAM (shoot apical meristem) + bool SAM_P(void); + // NB. Not checked. If cell is not found, it returns transporters2[ch]!! + //inline double getTransporter(int ch, Cell *c) { return c1 == c ? transporters1[ch] : transporters2[ch]; } + + //! Return true if the WallBase is a source of auxin + inline bool AuxinSource(void) const { return wall_type == AuxSource; } + inline bool AuxinSink(void) const { return wall_type == AuxSink; } + + inline void cycleWallType(void) { + + if (wall_type == Normal) + wall_type = AuxSource; + else + if (wall_type == AuxSource) + wall_type = AuxSink; + else + if (wall_type == AuxSink) { + wall_type = Normal; } - - inline CellBase *C1(void) const { return c1; } - inline CellBase *C2(void) const { return c2; } - inline Node *N1(void) const { return n1; } - inline Node *N2(void) const { return n2; } - inline void setTransporters1(int ch, double val) { transporters1[ch]=val; } - inline void setTransporters2(int ch, double val) { transporters2[ch]=val; } - inline void setNewTransporters1(int ch, double val) { new_transporters1[ch]=val; } - inline void setNewTransporters2(int ch, double val) { new_transporters2[ch]=val; } - inline double Transporters1(int ch) { return transporters1[ch]; } - inline double Transporters2(int ch) { return transporters2[ch]; } - - //! Return true if the WallBase adheres to the SAM (shoot apical meristem) - bool SAM_P(void); - // NB. Not checked. If cell is not found, it returns transporters2[ch]!! - //inline double getTransporter(int ch, Cell *c) { return c1 == c ? transporters1[ch] : transporters2[ch]; } - - //! Return true if the WallBase is a source of auxin - inline bool AuxinSource(void) const { return wall_type == AuxSource; } - inline bool AuxinSink(void) const { return wall_type == AuxSink; } - - inline void cycleWallType(void) { - - if (wall_type == Normal) - wall_type = AuxSource; - else - if (wall_type == AuxSource) - wall_type = AuxSink; - else - if (wall_type == AuxSink) { - wall_type = Normal; - } - } - // checked version. Use during debugging stage. - inline double getTransporter(CellBase *c, int ch) const { return c1 == c ? transporters1[ch] : ( c2 == c ? transporters2[ch] : throw "WallBase::getTransporter called with wrong cell") ; } - inline void setTransporter(CellBase *c, int ch, double val) { - if ( c1 == c ) { - transporters1[ch]=val; - } else - - if (c2 == c ) { - transporters2[ch]=val; - } else { - throw "WallBase::setTransporter called with wrong cell"; - } - } - inline double getApoplast(int ch) const { return apoplast[ch]; } - inline void setApoplast(int ch, double val) { apoplast[ch] = val; } - inline CellBase *getOtherCell(CellBase *c) { return c1 == c ? c2 : c1; } - Vector getInfluxVector(CellBase *c); - Vector getWallVector(CellBase *c); - void CorrectTransporters(double orig_length); - - inline double Length(void) { return length; } - //double Length(void); - - ostream &print(ostream &os) const; - - void SetLength(void); - void Transport(void); - - inline void setVizFlux( double value ) { viz_flux = value; } - - /*! Return vector containing the directional flux through the wall. - as defined by the value "viz_flux" which is supplied by the end-user - in the TransportFunction. - */ - Vector VizFlux(void); - bool IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2); - void SetTransToNewTrans( void ); - -private: - + } + // checked version. Use during debugging stage. + inline double getTransporter(CellBase *c, int ch) const + { + return c1 == c ? transporters1[ch] : ( c2 == c ? transporters2[ch] : throw "WallBase::getTransporter called with wrong cell") ; } + + inline void setTransporter(CellBase *c, int ch, double val) { + if ( c1 == c ) { + transporters1[ch]=val; + } else + + if (c2 == c ) { + transporters2[ch]=val; + } else { + throw "WallBase::setTransporter called with wrong cell"; + } + } + inline double getApoplast(int ch) const { return apoplast[ch]; } + inline void setApoplast(int ch, double val) { apoplast[ch] = val; } + inline CellBase *getOtherCell(CellBase *c) { return c1 == c ? c2 : c1; } + Vector getInfluxVector(CellBase *c); + Vector getWallVector(CellBase *c); + void CorrectTransporters(double orig_length); + + inline double Length(void) { return length; } + //double Length(void); + + ostream &print(ostream &os) const; + + void SetLength(void); + void Transport(void); + + inline void setVizFlux( double value ) { viz_flux = value; } + + /*! Return vector containing the directional flux through the wall. + as defined by the value "viz_flux" which is supplied by the end-user + in the TransportFunction. + */ + Vector VizFlux(void); + bool IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2); + void SetTransToNewTrans( void ); + + private: }; ostream &operator<<(ostream &os, const WallBase &w); #endif + +/* finis */ diff --git a/src/wallitem.cpp b/src/wallitem.cpp --- a/src/wallitem.cpp +++ b/src/wallitem.cpp @@ -38,29 +38,29 @@ WallItem::WallItem( Wall *w, int wallnum extern Parameter par; - setColor(); - - // line with "PIN1"is a bit inside the cell wall - Vector edgevec = (*(w->N2())) - (*(w->N1())); - Vector perp = edgevec.Normalised().Perp2D(); - - Vector offs = Cell::Offset(); - double factor = Cell::Factor(); - - Vector from = ( offs + *(w->N1()) ) * factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp; - Vector to = ( offs + *(w->N2()) ) *factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp; - - - Vector tmp_centroid = ( *(w->N2()) + *(w->N1()) )/2.; - Vector centroid = ( offs + tmp_centroid ) * factor; - - QString text=QString("%1").arg(w->Index()); - setLine(( from.x ), - ( from.y ), - ( to.x ), - ( to.y ) ); - setZValue(12); - } + setColor(); + + // line with "PIN1"is a bit inside the cell wall + Vector edgevec = (*(w->N2())) - (*(w->N1())); + Vector perp = edgevec.Normalised().Perp2D(); + + Vector offs = Cell::Offset(); + double factor = Cell::Factor(); + + Vector from = ( offs + *(w->N1()) ) * factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp; + Vector to = ( offs + *(w->N2()) ) *factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp; + + + Vector tmp_centroid = ( *(w->N2()) + *(w->N1()) )/2.; + Vector centroid = ( offs + tmp_centroid ) * factor; + + QString text=QString("%1").arg(w->Index()); + setLine(( from.x ), + ( from.y ), + ( to.x ), + ( to.y ) ); + setZValue(12); +} void WallItem::setColor(void) { @@ -68,7 +68,7 @@ void WallItem::setColor(void) { QColor diffcolor; static const QColor purple("Purple"); static const QColor blue("blue"); - + Wall *w=&getWall(); double tr = wn==1?w->Transporters1(1):w->Transporters2(1); CellBase *c = wn==1?w->C1():w->C2(); @@ -85,46 +85,48 @@ void WallItem::setColor(void) { } void WallItem::OnClick(QMouseEvent *e) { - + + + Wall *w=&getWall(); +#ifdef QDEBUG + qDebug() << "Wall ID = " << w->Index() << ", this = " << w << endl; + qDebug() << "Wall item = " << this << endl; + qDebug() << "C1 = " << w->C1()->Index() << ", C2 = " << w->C2()->Index() << endl; + qDebug() << "N1 = " << w->N1()->Index() << ", N2 = " << w->N2()->Index() << endl; +#endif + CellBase *c = wn==1?w->C1():w->C2(); - Wall *w=&getWall(); - #ifdef QDEBUG - qDebug() << "Wall ID = " << w->Index() << ", this = " << w << endl; - qDebug() << "Wall item = " << this << endl; - qDebug() << "C1 = " << w->C1()->Index() << ", C2 = " << w->C2()->Index() << endl; - qDebug() << "N1 = " << w->N1()->Index() << ", N2 = " << w->N2()->Index() << endl; - #endif - CellBase *c = wn==1?w->C1():w->C2(); + TransporterDialog dialog(w, c, wn); + dialog.exec(); - TransporterDialog dialog(w, c, wn); - dialog.exec(); + if (e->button() == Qt::RightButton) { + QString message; + if (wn==1) { + message=QString("Transporter 1 = %1, color = %2, length = %3\n").arg(w->Transporters1(1)).arg(pen().color().red()).arg(getWall().Length()); + } else { + message=QString("Transporter 2 = %1, color = %2, length = %3\n").arg(w->Transporters2(1)).arg(pen().color().red()).arg(getWall().Length()); + } - if (e->button() == Qt::RightButton) { - QString message; - if (wn==1) { - message=QString("Transporter 1 = %1, color = %2, length = %3\n").arg(w->Transporters1(1)).arg(pen().color().red()).arg(getWall().Length()); - } else { - message=QString("Transporter 2 = %1, color = %2, length = %3\n").arg(w->Transporters2(1)).arg(pen().color().red()).arg(getWall().Length()); - } - - //extern MainBase *main_window; - + //extern MainBase *main_window; + + } else { + if (e->button() == Qt::LeftButton) { + if (c->BoundaryPolP()) { + w->cycleWallType(); + } else { + if (e->modifiers() == Qt::ShiftModifier) { + wn==1?w->setTransporters1(1,0):w->setTransporters2(1,0); + } else { - if (e->button() == Qt::LeftButton) { - if (c->BoundaryPolP()) { - w->cycleWallType(); - } else { - if (e->modifiers() == Qt::ShiftModifier) { - wn==1?w->setTransporters1(1,0):w->setTransporters2(1,0); - - } else { - // set high amount of PIN1 - //cerr << "Setting PIN1\n"; - wn==1?w->setTransporters1(1,10):w->setTransporters2(1,10); - } - } - setColor(); - update(boundingRect()); - } + // set high amount of PIN1 + //cerr << "Setting PIN1\n"; + wn==1?w->setTransporters1(1,10):w->setTransporters2(1,10); } + } + setColor(); + update(boundingRect()); + } + } } + +/* finis */ diff --git a/src/wallitem.h b/src/wallitem.h --- a/src/wallitem.h +++ b/src/wallitem.h @@ -37,7 +37,7 @@ class WallItem : public QGraphicsLineItem, public SimItemBase { -public: + public: WallItem( Wall *n, int wallnumber, QGraphicsScene *canvas ); virtual ~WallItem() {} Wall &getWall(void) const { return *class_cast(obj); } @@ -48,3 +48,5 @@ public: }; #endif + +/* finis */ diff --git a/src/warning.cpp b/src/warning.cpp --- a/src/warning.cpp +++ b/src/warning.cpp @@ -42,14 +42,14 @@ int Quiet=0; #ifndef QTGRAPHICS void MyWarning::error(char * fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); /* invoke interface to printf */ - fprintf(stderr,"\n"); /* automatic \n by Roeland */ - fflush(stderr); /* drain std error buffer */ - va_end(ap); - exit(1); /* quit with error status */ + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); /* invoke interface to printf */ + fprintf(stderr,"\n"); /* automatic \n by Roeland */ + fflush(stderr); /* drain std error buffer */ + va_end(ap); + exit(1); /* quit with error status */ } #else //#include @@ -59,29 +59,28 @@ void MyWarning::error(const char *fmt, . va_list ap; if (Quiet) return; char *message = new char[1000]; - + va_start(ap, fmt); vsnprintf(message, 999, fmt, ap); /* invoke interface to printf */ va_end(ap); - + QString qmess(message); - + if (qApp->type()==QApplication::Tty) { // batch mode: print the message to stderr fprintf(stderr, "Fatal error: %s\n",qmess.toStdString().c_str()); exit(1); } else { // issue a dialog box /* Solve this with signal and slot...! */ - //extern MainBase *main_window; + //extern MainBase *main_window; //((Main *)main_window)->stopSimulation(); - - QMessageBox::critical( 0 , "Fatal error", qmess, QMessageBox::Abort, QMessageBox::NoButton, QMessageBox::NoButton ); + + QMessageBox::critical( 0 , "Fatal error", qmess, QMessageBox::Abort, QMessageBox::NoButton, QMessageBox::NoButton ); fprintf(stderr, "Error: %s\n",qmess.toStdString().c_str()); QCoreApplication::exit(1); std::exit(1); } delete[] message; - } #endif @@ -97,7 +96,7 @@ void MyWarning::warning(const char * fmt { va_list ap; if (Quiet) return; - + va_start(ap, fmt); vfprintf(stderr, fmt, ap); /* invoke interface to printf */ fprintf(stderr,"\n"); /* automatic \n by Roeland */ @@ -114,53 +113,52 @@ void MyWarning::warning(const char *fmt, va_list ap; if (Quiet) return; char *message = new char[1000]; - + va_start(ap, fmt); vsnprintf(message, 999, fmt, ap); /* invoke interface to printf */ va_end(ap); - + QString qmess(message); - + // bool batch = false; - + if (qApp->type()==QApplication::Tty) { // batch mode: print the message to stderr fprintf(stderr, "Warning: %s\n",qmess.toStdString().c_str()); } else { // issue a dialog box - UniqueMessageBox msgBox( QString("Warning"), qmess ); - msgBox.exec(); + UniqueMessageBox msgBox( QString("Warning"), qmess ); + msgBox.exec(); } delete[] message; - } #endif /*! Issues a warning only once, by comparing it to a list of warnings issued previously. */ void MyWarning::unique_warning(const char *fmt, ...) { - + va_list ap; if (Quiet) return; char *message = new char[1000]; - + va_start(ap, fmt); vsnprintf(message, 999, fmt, ap); /* invoke interface to printf */ va_end(ap); static vector previous_warnings; - + // search warning in list if (find( previous_warnings.begin(),previous_warnings.end(), string(message)) ==previous_warnings.end()) { - + // new warning, store in list previous_warnings.push_back(string(message)); - + // issue warning warning("%s", message); - + } else { // don't issue warning return; @@ -172,8 +170,10 @@ void MyWarning::unique_warning(const cha main(int argc, char * argv[]) { - eprintf("warning: foo=%f\tbar=%d\tfum=\"%s\"\n", 3.1415, 32768, "waldo"); - error("error: foo=%f\tbar=%d\tfum=\"%s\"\n", 3.1415, 32768, "waldo"); + eprintf("warning: foo=%f\tbar=%d\tfum=\"%s\"\n", 3.1415, 32768, "waldo"); + error("error: foo=%f\tbar=%d\tfum=\"%s\"\n", 3.1415, 32768, "waldo"); } #endif + +/* finis */ diff --git a/src/warning.h b/src/warning.h --- a/src/warning.h +++ b/src/warning.h @@ -33,15 +33,17 @@ extern "C" { #endif // namespace MyWarning needed because libxml2 also defines a warning token. - + namespace MyWarning { void error(const char *, ...); void warning(const char *, ...); void unique_warning(const char *, ...); } - + #ifdef __cplusplus } #endif #endif + +/* finis */ diff --git a/src/xmlwrite.cpp b/src/xmlwrite.cpp --- a/src/xmlwrite.cpp +++ b/src/xmlwrite.cpp @@ -42,11 +42,11 @@ static const std::string _module_id("$Id using namespace MyWarning; void ThrowStringStream(stringstream &s) { - - static char *msg = 0; - msg = (char *)malloc((1+s.str().length())*sizeof(char)); - strcpy(msg,s.str().c_str()); - throw(msg); + + static char *msg = 0; + msg = (char *)malloc((1+s.str().length())*sizeof(char)); + strcpy(msg,s.str().c_str()); + throw(msg); } @@ -56,20 +56,18 @@ void Cell::XMLAdd(xmlNodePtr cells_node) // Save the cell to a stream so we can reconstruct its state later xmlNodePtr xmlcell = xmlNewChild(cells_node, NULL, BAD_CAST "cell",NULL); XMLAddCore(xmlcell); - } void BoundaryPolygon::XMLAdd(xmlNodePtr parent_node) const { - + xmlNodePtr xmlcell = xmlNewChild(parent_node, NULL, BAD_CAST "boundary_polygon",NULL); XMLAddCore(xmlcell); - } void NodeSet::XMLAdd(xmlNode *root) const { - + xmlNode *xmlnodeset = xmlNewChild(root, NULL, BAD_CAST "nodeset", NULL); - + for (list::const_iterator i=begin();i!=end();i++) { { ostringstream text; @@ -78,14 +76,13 @@ void NodeSet::XMLAdd(xmlNode *root) cons xmlNewProp(node_xml, BAD_CAST "n", BAD_CAST text.str().c_str()); } } - } void Cell::XMLAddCore(xmlNodePtr xmlcell) const { - + // properties { @@ -98,38 +95,38 @@ void Cell::XMLAddCore(xmlNodePtr xmlcell text << area; xmlNewProp(xmlcell, BAD_CAST "area", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << target_area; xmlNewProp(xmlcell, BAD_CAST "target_area", BAD_CAST text.str().c_str()); } - - + + { ostringstream text; text << target_length; xmlNewProp(xmlcell, BAD_CAST "target_length", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << lambda_celllength; xmlNewProp(xmlcell, BAD_CAST "lambda_celllength", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << stiffness; xmlNewProp(xmlcell, BAD_CAST "stiffness", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << bool_name(fixed); xmlNewProp(xmlcell, BAD_CAST "fixed", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << bool_name(pin_fixed); @@ -141,8 +138,8 @@ void Cell::XMLAddCore(xmlNodePtr xmlcell text << bool_name(at_boundary); xmlNewProp(xmlcell, BAD_CAST "at_boundary", BAD_CAST text.str().c_str()); } - - + + { ostringstream text; text << bool_name(dead); @@ -155,25 +152,25 @@ void Cell::XMLAddCore(xmlNodePtr xmlcell xmlNewProp(xmlcell, BAD_CAST "source", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << boundary_type_names[boundary]; xmlNewProp(xmlcell, BAD_CAST "boundary", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << div_counter; xmlNewProp(xmlcell, BAD_CAST "div_counter", BAD_CAST text.str().c_str()); } - - { - ostringstream text; - text << cell_type; - xmlNewProp(xmlcell, BAD_CAST "cell_type", BAD_CAST text.str().c_str()); - } - + + { + ostringstream text; + text << cell_type; + xmlNewProp(xmlcell, BAD_CAST "cell_type", BAD_CAST text.str().c_str()); + } + for (list::const_iterator i=nodes.begin();i!=nodes.end();i++) { { ostringstream text; @@ -192,45 +189,39 @@ void Cell::XMLAddCore(xmlNodePtr xmlcell } } - - - + + + xmlNodePtr chem_xml = xmlNewChild(xmlcell, NULL, BAD_CAST "chem", NULL); { ostringstream text; text << NChem(); xmlNewProp(chem_xml, BAD_CAST "n", BAD_CAST text.str().c_str()); } - + for (int i=0;inode_sets.begin(),m->node_sets.end(),node_set); xmlNewProp(xmlnode, BAD_CAST "nodeset", BAD_CAST text.str().c_str()); } - - } void Neighbor::XMLAdd(xmlNodePtr neighbors_node) const { - + xmlNodePtr xmlnode = xmlNewChild(neighbors_node, NULL, BAD_CAST "neighbor",NULL); { ostringstream text; @@ -284,14 +273,13 @@ void Neighbor::XMLAdd(xmlNodePtr neighbo text << nb2->Index(); xmlNewProp(xmlnode, BAD_CAST "nb2", BAD_CAST text.str().c_str()); } - } // from example code on www.libxml.org: xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath){ - + xmlXPathContextPtr context; xmlXPathObjectPtr result; @@ -316,15 +304,16 @@ getnodeset (xmlDocPtr doc, xmlChar *xpat -int Cell::XMLRead(xmlNode *cur) { - +int Cell::XMLRead(xmlNode *cur) +{ + xmlNode *n = cur->xmlChildrenNode; QLocale standardlocale(QLocale::C); bool ok; vector tmp_nodes; - while(n!=NULL) { + while(n!=NULL) { if ((!xmlStrcmp(n->name, (const xmlChar *)"node"))) { xmlChar *nc = xmlGetProp(n, BAD_CAST "n"); @@ -337,79 +326,79 @@ int Cell::XMLRead(xmlNode *cur) { } n = n->next; } - + int nnodes = tmp_nodes.size(); for (int i=0;iAddNodeToCell( this, m->nodes[tmp_nodes[i]], m->nodes[tmp_nodes[(nnodes+i-1)%nnodes]], m->nodes[tmp_nodes[(i+1)%nnodes]] ); - + } n = cur->xmlChildrenNode; while(n!=NULL) { - if ((!xmlStrcmp(n->name, (const xmlChar *)"chem"))) { + if ((!xmlStrcmp(n->name, (const xmlChar *)"chem"))) { + + xmlNode *v_node = n->xmlChildrenNode; + int nv=0; + while (v_node!=NULL) { + if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) { - xmlNode *v_node = n->xmlChildrenNode; - int nv=0; - while (v_node!=NULL) { - if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) { - - - if (nv>=Cell::NChem()) { - { - stringstream text; - text << "Exception in Mesh::XMLRead: Too many chemical values given for cell(s). Ignoring remaining values."; - unique_warning(text.str().c_str()); - break; - } - } - - xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v"); - - if (nc==0) { - unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 1002"); - } - double v=standardlocale.toDouble((char *)nc, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)nc); - chem[nv++]=v; - xmlFree(nc); - } - v_node = v_node->next; + + if (nv>=Cell::NChem()) { + { + stringstream text; + text << "Exception in Mesh::XMLRead: Too many chemical values given for cell(s). Ignoring remaining values."; + unique_warning(text.str().c_str()); + break; } } - n = n->next; + + xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v"); + + if (nc==0) { + unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 1002"); + } + double v=standardlocale.toDouble((char *)nc, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)nc); + chem[nv++]=v; + xmlFree(nc); + } + v_node = v_node->next; + } + } + n = n->next; } - - // read cell properties - { - xmlChar *v_str = xmlGetProp(cur, BAD_CAST "area"); - - if (v_str==0) { - unique_warning("Token \"area\" not found in xmlwrite.cpp at or around line no. 1018"); - } - if (v_str != NULL) { - area=standardlocale.toDouble((char *)v_str, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str); - xmlFree(v_str); - } - } - - { - xmlChar *v_str = xmlGetProp(cur, BAD_CAST "target_area"); - - if (v_str==0) { - unique_warning("Token \"target_area\" not found in xmlwrite.cpp at or around line no. 1029"); - } + + // read cell properties + { + xmlChar *v_str = xmlGetProp(cur, BAD_CAST "area"); + + if (v_str==0) { + unique_warning("Token \"area\" not found in xmlwrite.cpp at or around line no. 1018"); + } if (v_str != NULL) { - target_area=standardlocale.toDouble((char *)v_str, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str); + area=standardlocale.toDouble((char *)v_str, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str); xmlFree(v_str); } } - - + + { + xmlChar *v_str = xmlGetProp(cur, BAD_CAST "target_area"); + + if (v_str==0) { + unique_warning("Token \"target_area\" not found in xmlwrite.cpp at or around line no. 1029"); + } + if (v_str != NULL) { + target_area=standardlocale.toDouble((char *)v_str, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str); + xmlFree(v_str); + } + } + + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "target_length"); @@ -449,7 +438,7 @@ int Cell::XMLRead(xmlNode *cur) { } } - + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "fixed"); @@ -473,7 +462,7 @@ int Cell::XMLRead(xmlNode *cur) { xmlFree(v_str); } } - + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "at_boundary"); @@ -485,7 +474,7 @@ int Cell::XMLRead(xmlNode *cur) { xmlFree(v_str); } } - + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "dead"); @@ -509,7 +498,7 @@ int Cell::XMLRead(xmlNode *cur) { xmlFree(v_str); } } - + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "boundary"); @@ -526,7 +515,7 @@ int Cell::XMLRead(xmlNode *cur) { xmlFree(v_str); } } - + { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "div_counter"); @@ -538,29 +527,29 @@ int Cell::XMLRead(xmlNode *cur) { xmlFree(v_str); } } - - { - xmlChar *v_str = xmlGetProp(cur, BAD_CAST "cell_type"); - - if (v_str==0) { - unique_warning("Token \"cell_type\" not found in xmlwrite.cpp at or around line no. 1237"); - } - if (v_str != NULL) { - cell_type = atoi( (char *)v_str); - xmlFree(v_str); - } - } - + + { + xmlChar *v_str = xmlGetProp(cur, BAD_CAST "cell_type"); + + if (v_str==0) { + unique_warning("Token \"cell_type\" not found in xmlwrite.cpp at or around line no. 1237"); + } + if (v_str != NULL) { + cell_type = atoi( (char *)v_str); + xmlFree(v_str); + } + } + // Recalculate moments and area SetIntegrals(); return 0; +} -} - -void NodeSet::XMLRead(xmlNode *root, Mesh *m) { - +void NodeSet::XMLRead(xmlNode *root, Mesh *m) +{ + xmlNode *n = root->xmlChildrenNode; - + vector tmp_nodes; while(n!=NULL) { if ((!xmlStrcmp(n->name, (const xmlChar *)"node"))) { @@ -574,22 +563,21 @@ void NodeSet::XMLRead(xmlNode *root, Mes } n = n->next; } - + int nnodes = tmp_nodes.size(); for (int i=0;igetNode(tmp_nodes[i])) ); } - } void Wall::XMLAdd(xmlNode *parent) const { - + // Save the node to a stream so we can reconstruct its state later xmlNodePtr xmlwall = xmlNewChild(parent, NULL, BAD_CAST "wall",NULL); - + { ostringstream text; text << Index(); @@ -601,21 +589,21 @@ void Wall::XMLAdd(xmlNode *parent) const text << c1->Index(); xmlNewProp(xmlwall, BAD_CAST "c1", BAD_CAST text.str().c_str()); } - - + + { ostringstream text; text << c2->Index(); xmlNewProp(xmlwall, BAD_CAST "c2", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << n1->Index(); xmlNewProp(xmlwall, BAD_CAST "n1", BAD_CAST text.str().c_str()); } - + { ostringstream text; text << n2->Index(); @@ -627,7 +615,7 @@ void Wall::XMLAdd(xmlNode *parent) const text << length; xmlNewProp(xmlwall, BAD_CAST "length", BAD_CAST text.str().c_str()); } - + { ostringstream text; @@ -640,8 +628,8 @@ void Wall::XMLAdd(xmlNode *parent) const text << WallTypetoStr(wall_type); xmlNewProp(xmlwall, BAD_CAST "wall_type", BAD_CAST text.str().c_str()); } - - + + xmlNodePtr tr1_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "transporters1", NULL); if (transporters1) { for (int i=0;i XMLIO::XMLReadValArray(xmlNode *cur) { - +vector XMLIO::XMLReadValArray(xmlNode *cur) +{ + vector result; QLocale standardlocale(QLocale::C); bool ok; @@ -700,7 +687,7 @@ vector XMLIO::XMLReadValArray(xm if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)vc); xmlFree(vc); } - + } valarray_node = valarray_node->next; } @@ -709,484 +696,471 @@ vector XMLIO::XMLReadValArray(xm void Mesh::XMLSave(const char *docname, xmlNode *options) const { - - // based on libxml2 example code "tree2.c" - - xmlDocPtr doc = NULL; /* document pointer */ - xmlNodePtr root_node = NULL;/* node pointers */ - //xmlDtdPtr dtd = NULL; /* DTD pointer */ - - // LIBXML_TEST_VERSION; - - /* - * Creates a new document, a node and set it as a root node - */ - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "leaf"); - xmlDocSetRootElement(doc, root_node); - - /* - * xmlNewProp() creates attributes, which is "attached" to an node. - * It returns xmlAttrPtr, which isn't used here. - */ - xmlNewProp(root_node, BAD_CAST "name", BAD_CAST docname); - - time_t t; - std::time(&t); + + // based on libxml2 example code "tree2.c" + + xmlDocPtr doc = NULL; /* document pointer */ + xmlNodePtr root_node = NULL;/* node pointers */ + //xmlDtdPtr dtd = NULL; /* DTD pointer */ + + // LIBXML_TEST_VERSION; + + /* + * Creates a new document, a node and set it as a root node + */ + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "leaf"); + xmlDocSetRootElement(doc, root_node); + + /* + * xmlNewProp() creates attributes, which is "attached" to an node. + * It returns xmlAttrPtr, which isn't used here. + */ + xmlNewProp(root_node, BAD_CAST "name", BAD_CAST docname); + + time_t t; + std::time(&t); + + char *tstring = strdup(asctime(localtime(&t))); // but this does + // replace "end of line character by '\0' + char *eol=strchr(tstring,'\n'); + if (eol!=NULL) + *eol='\0'; + + xmlNewProp(root_node, BAD_CAST "date", BAD_CAST tstring); + free(tstring); + - char *tstring = strdup(asctime(localtime(&t))); // but this does - // replace "end of line character by '\0' - char *eol=strchr(tstring,'\n'); - if (eol!=NULL) - *eol='\0'; - - xmlNewProp(root_node, BAD_CAST "date", BAD_CAST tstring); - free(tstring); - - - QString simtime = QString("%1").arg(time); - xmlNewProp(root_node, BAD_CAST "simtime", BAD_CAST simtime.toStdString().c_str()); - /* - * Creates a DTD declaration. Isn't mandatory. - */ + QString simtime = QString("%1").arg(time); + xmlNewProp(root_node, BAD_CAST "simtime", BAD_CAST simtime.toStdString().c_str()); + /* + * Creates a DTD declaration. Isn't mandatory. + */ + + par.XMLAdd(root_node); + + xmlNodePtr xmlnodes = xmlNewChild(root_node, NULL, BAD_CAST "nodes",NULL); + { ostringstream text; + text << NNodes(); + xmlNewProp(xmlnodes, BAD_CAST "n", BAD_CAST text.str().c_str()); + } + + { ostringstream text; + text << Node::target_length; + xmlNewProp(xmlnodes, BAD_CAST "target_length", BAD_CAST text.str().c_str()); + } - par.XMLAdd(root_node); + for (vector::const_iterator i=nodes.begin(); + i!=nodes.end(); + i++) { + (*i)->XMLAdd(xmlnodes) ; + } + + + /* + * xmlNewChild() creates a new node, which is "attached" as child node + * of root_node node. + */ + xmlNodePtr xmlcells = xmlNewChild(root_node, NULL, BAD_CAST "cells",NULL); + { + ostringstream text; + text << NCells(); + xmlNewProp(xmlcells, BAD_CAST "n", BAD_CAST text.str().c_str()); + } + { + ostringstream text; + text << Cell::offset[0]; + xmlNewProp(xmlcells, BAD_CAST "offsetx", BAD_CAST text.str().c_str()); + } - xmlNodePtr xmlnodes = xmlNewChild(root_node, NULL, BAD_CAST "nodes",NULL); - { ostringstream text; - text << NNodes(); - xmlNewProp(xmlnodes, BAD_CAST "n", BAD_CAST text.str().c_str()); - } - - { ostringstream text; - text << Node::target_length; - xmlNewProp(xmlnodes, BAD_CAST "target_length", BAD_CAST text.str().c_str()); - } - - - - for (vector::const_iterator i=nodes.begin(); - i!=nodes.end(); - i++) { - (*i)->XMLAdd(xmlnodes) ; - } - - - /* - * xmlNewChild() creates a new node, which is "attached" as child node - * of root_node node. - */ - xmlNodePtr xmlcells = xmlNewChild(root_node, NULL, BAD_CAST "cells",NULL); - { - ostringstream text; - text << NCells(); - xmlNewProp(xmlcells, BAD_CAST "n", BAD_CAST text.str().c_str()); - } - { - ostringstream text; - text << Cell::offset[0]; - xmlNewProp(xmlcells, BAD_CAST "offsetx", BAD_CAST text.str().c_str()); - } - - { - ostringstream text; - text << Cell::offset[1]; - xmlNewProp(xmlcells, BAD_CAST "offsety", BAD_CAST text.str().c_str()); - } - - { - ostringstream text; - text << Cell::factor; - xmlNewProp(xmlcells, BAD_CAST "magnification", BAD_CAST text.str().c_str()); - } - - { - ostringstream text; - text << cells.front()->BaseArea(); - xmlNewProp(xmlcells, BAD_CAST "base_area", BAD_CAST text.str().c_str()); - } - - { - ostringstream text; - text << Cell::NChem(); - xmlNewProp(xmlcells, BAD_CAST "nchem", BAD_CAST text.str().c_str()); - } - - for (vector::const_iterator i=cells.begin(); - i!=cells.end(); - i++) { - (*i)->XMLAdd(xmlcells) ; - } - - boundary_polygon->XMLAdd(xmlcells); - - xmlNodePtr xmlwalls = xmlNewChild(root_node, NULL, BAD_CAST "walls",NULL); - { - ostringstream text; - text << walls.size(); - xmlNewProp(xmlwalls, BAD_CAST "n", BAD_CAST text.str().c_str()); - } - - - for (list::const_iterator i=walls.begin(); - i!=walls.end(); - i++) { - (*i)->XMLAdd(xmlwalls) ; - } - - - xmlNodePtr xmlnodesets = xmlNewChild(root_node, NULL, BAD_CAST "nodesets",NULL); - { - ostringstream text; - text << node_sets.size(); - xmlNewProp(xmlnodesets, BAD_CAST "n", BAD_CAST text.str().c_str()); - } - - - for_each( node_sets.begin(), node_sets.end(), - bind2nd ( - mem_fun( &NodeSet::XMLAdd ), - xmlnodesets - ) ); - - - // Add option tree for interactive application - if (options) { - xmlAddChild(root_node, options); - } - - - - - /* - * Dumping document to stdio or file - */ - xmlSetDocCompressMode(doc,9); - xmlSaveFormatFileEnc(docname, doc, "UTF-8", 1); - - /*free the document */ - xmlFreeDoc(doc); - - /* - *Free the global variables that may - *have been allocated by the parser. - */ - xmlCleanupParser(); - - /* - * this is to debug memory for regression tests - */ + { + ostringstream text; + text << Cell::offset[1]; + xmlNewProp(xmlcells, BAD_CAST "offsety", BAD_CAST text.str().c_str()); + } + + { + ostringstream text; + text << Cell::factor; + xmlNewProp(xmlcells, BAD_CAST "magnification", BAD_CAST text.str().c_str()); + } + + { + ostringstream text; + text << cells.front()->BaseArea(); + xmlNewProp(xmlcells, BAD_CAST "base_area", BAD_CAST text.str().c_str()); + } + + { + ostringstream text; + text << Cell::NChem(); + xmlNewProp(xmlcells, BAD_CAST "nchem", BAD_CAST text.str().c_str()); + } + + for (vector::const_iterator i=cells.begin(); + i!=cells.end(); + i++) { + (*i)->XMLAdd(xmlcells) ; + } + + boundary_polygon->XMLAdd(xmlcells); + + xmlNodePtr xmlwalls = xmlNewChild(root_node, NULL, BAD_CAST "walls",NULL); + { + ostringstream text; + text << walls.size(); + xmlNewProp(xmlwalls, BAD_CAST "n", BAD_CAST text.str().c_str()); + } + + + for (list::const_iterator i=walls.begin(); + i!=walls.end(); + i++) { + (*i)->XMLAdd(xmlwalls) ; + } + + + xmlNodePtr xmlnodesets = xmlNewChild(root_node, NULL, BAD_CAST "nodesets",NULL); + { + ostringstream text; + text << node_sets.size(); + xmlNewProp(xmlnodesets, BAD_CAST "n", BAD_CAST text.str().c_str()); + } + + for_each( node_sets.begin(), node_sets.end(), bind2nd ( mem_fun( &NodeSet::XMLAdd ), xmlnodesets ) ); + + // Add option tree for interactive application + if (options) { + xmlAddChild(root_node, options); + } + + + /* + * Dumping document to stdio or file + */ + xmlSetDocCompressMode(doc,9); + xmlSaveFormatFileEnc(docname, doc, "UTF-8", 1); + + /*free the document */ + xmlFreeDoc(doc); + + /* + *Free the global variables that may + *have been allocated by the parser. + */ + xmlCleanupParser(); + + /* + * this is to debug memory for regression tests + */ } -void Mesh::XMLReadSimtime(const xmlNode *a_node) { - +void Mesh::XMLReadSimtime(const xmlNode *a_node) +{ + xmlNode *root_node; root_node = (xmlNode *)a_node; xmlChar *strsimtime = xmlGetProp(root_node, BAD_CAST "simtime"); - - + + if (strsimtime) { QLocale standardlocale(QLocale::C); bool ok; - + double simtime=standardlocale.toDouble((char *)strsimtime, &ok); if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)strsimtime); - time = simtime; + time = simtime; #ifdef QDEBUG - qDebug() << "Simtime = " << strsimtime << endl; + qDebug() << "Simtime = " << strsimtime << endl; #endif - } else { + } else { #ifdef QDEBUG qDebug() << "No simtime found in file." << endl; #endif - time =0; - } + time =0; + } } -void Mesh::XMLReadPars(const xmlNode * a_node) { - xmlNode *root_node; - root_node = (xmlNode *)a_node; - par.XMLRead(root_node); - Seed(par.rseed); - MakeDir(par.datadir); +void Mesh::XMLReadPars(const xmlNode * a_node) +{ + xmlNode *root_node; + root_node = (xmlNode *)a_node; + par.XMLRead(root_node); + Seed(par.rseed); + MakeDir(par.datadir); } void Mesh::XMLReadGeometry(const xmlNode * a_node) { - - xmlNode *root_node; - root_node = (xmlNode *)a_node; - xmlNode *cur; - QLocale standardlocale(QLocale::C); - bool ok; - // allocate Nodes - cur = root_node->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))){ - XMLReadNodes(cur); - } - cur=cur->next; - } - - cur = root_node->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodesets"))) { - XMLReadNodeSets(cur); - } - cur=cur->next; - } - - cur=root_node->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))) { - XMLReadNodeSetsToNodes(cur); - } - cur = cur->next; - } - - - // allocate Cells - cur = root_node; - - // allocate Cells - cur = cur->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))){ - xmlChar *offsetxc = xmlGetProp(cur, BAD_CAST "offsetx"); - xmlChar *offsetyc = xmlGetProp(cur, BAD_CAST "offsety"); + + xmlNode *root_node; + root_node = (xmlNode *)a_node; + xmlNode *cur; + QLocale standardlocale(QLocale::C); + bool ok; + // allocate Nodes + cur = root_node->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))){ + XMLReadNodes(cur); + } + cur=cur->next; + } + + cur = root_node->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodesets"))) { + XMLReadNodeSets(cur); + } + cur=cur->next; + } - double ox=standardlocale.toDouble((const char *)offsetxc, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetxc); + cur=root_node->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))) { + XMLReadNodeSetsToNodes(cur); + } + cur = cur->next; + } + + + // allocate Cells + cur = root_node; - double oy=standardlocale.toDouble((const char *)offsetyc, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetyc); - Cell::setOffset(ox, oy); - xmlFree(offsetxc); - xmlFree(offsetyc); - - xmlChar *magnificationc = xmlGetProp(cur, BAD_CAST "magnification"); + // allocate Cells + cur = cur->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))){ + xmlChar *offsetxc = xmlGetProp(cur, BAD_CAST "offsetx"); + xmlChar *offsetyc = xmlGetProp(cur, BAD_CAST "offsety"); + + double ox=standardlocale.toDouble((const char *)offsetxc, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetxc); + + double oy=standardlocale.toDouble((const char *)offsetyc, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetyc); + Cell::setOffset(ox, oy); + xmlFree(offsetxc); + xmlFree(offsetyc); - Cell::SetMagnification(standardlocale.toDouble((const char *)magnificationc, &ok)); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)magnificationc); - xmlFree(magnificationc); - - xmlChar *baseareac = xmlGetProp(cur, BAD_CAST "base_area"); + xmlChar *magnificationc = xmlGetProp(cur, BAD_CAST "magnification"); + + Cell::SetMagnification(standardlocale.toDouble((const char *)magnificationc, &ok)); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)magnificationc); + xmlFree(magnificationc); + + xmlChar *baseareac = xmlGetProp(cur, BAD_CAST "base_area"); + + Cell::BaseArea() = standardlocale.toDouble((const char *)baseareac, &ok); + if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)baseareac); + xmlFree(baseareac); + + XMLReadCells(cur); + } + cur=cur->next; + } + + // allocate Walls (we need to have read the cells before constructing walls) + vector tmp_walls; + cur = root_node->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"walls"))){ + XMLReadWalls(cur, &tmp_walls); + } + cur=cur->next; + } - Cell::BaseArea() = standardlocale.toDouble((const char *)baseareac, &ok); - if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)baseareac); - xmlFree(baseareac); - - - XMLReadCells(cur); - } - cur=cur->next; - } - - // allocate Walls (we need to have read the cells before constructing walls) - vector tmp_walls; - cur = root_node->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"walls"))){ - XMLReadWalls(cur, &tmp_walls); - } - cur=cur->next; - } - - // read walls to cells and boundary_polygon - cur = root_node->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))) { - XMLReadWallsToCells(cur, &tmp_walls); - } - cur=cur->next; - } - - boundary_polygon->ConstructNeighborList(); - boundary_polygon->ConstructConnections(); - - for (vector::iterator c=cells.begin(); - c!=cells.end(); - c++) { - - (*c)->ConstructNeighborList(); - (*c)->ConstructConnections(); - - } - - shuffled_cells.clear(); - shuffled_cells = cells; - - MyUrand r(shuffled_cells.size()); - random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r); - + // read walls to cells and boundary_polygon + cur = root_node->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))) { + XMLReadWallsToCells(cur, &tmp_walls); + } + cur=cur->next; + } + + boundary_polygon->ConstructNeighborList(); + boundary_polygon->ConstructConnections(); + + for (vector::iterator c=cells.begin(); + c!=cells.end(); + c++) { + + (*c)->ConstructNeighborList(); + (*c)->ConstructConnections(); + + } + + shuffled_cells.clear(); + shuffled_cells = cells; + + MyUrand r(shuffled_cells.size()); + random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r); } -void Mesh::XMLParseTree(const xmlNode *root_node) { - - XMLReadSimtime(root_node); - XMLReadPars(root_node); - XMLReadGeometry(root_node); - +void Mesh::XMLParseTree(const xmlNode *root_node) +{ + XMLReadSimtime(root_node); + XMLReadPars(root_node); + XMLReadGeometry(root_node); } -void Mesh::XMLReadNodes(xmlNode *root) { - +void Mesh::XMLReadNodes(xmlNode *root) +{ + QLocale standardlocale(QLocale::C); bool ok; xmlNode *cur = root; cur = cur->xmlChildrenNode; - + for (vector::iterator i=nodes.begin(); i!=nodes.end(); i++) { delete *i; } - + nodes.clear(); Node::nnodes=0; - + xmlChar *tlc = xmlGetProp(root, BAD_CAST "target_length"); - + if (tlc != 0) { - Node::target_length = standardlocale.toDouble((const char *)tlc, &ok); if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)tlc); - + xmlFree(tlc); } else { // note that libxml2 also defines a token "warning" MyWarning::unique_warning("Warning: value found in XML file for Node::target_length."); } - + while (cur!=NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"node"))){ - + xmlChar *xc = xmlGetProp(cur, BAD_CAST "x"); - + if (xc==0) { unique_warning("Token \"x\" not found in xmlwrite.cpp at or around line no. 722"); } - + xmlChar *yc = xmlGetProp(cur, BAD_CAST "y"); - + if (yc==0) { unique_warning("Token \"y\" not found in xmlwrite.cpp at or around line no. 727"); } - + xmlChar *fixedc = xmlGetProp(cur, BAD_CAST "fixed"); if (fixedc==0) { unique_warning("Token \"fixed\" not found in xmlwrite.cpp at or around line."); } - + xmlChar *boundaryc = xmlGetProp(cur, BAD_CAST "boundary"); if (boundaryc==0) { unique_warning("Token \"boundary\" not found in xmlwrite.cpp at or around line."); } - + xmlChar *samc = xmlGetProp(cur, BAD_CAST "sam"); if (samc==0) { unique_warning("Token \"sam\" not found in xmlwrite.cpp at or around line."); } - + double x = standardlocale.toDouble((const char *)xc, &ok); if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)xc); - + double y = standardlocale.toDouble((const char *)yc, &ok); if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)yc); - + Node *new_node = new Node(x,y); nodes.push_back(new_node); - + new_node->m = this; new_node->fixed = strtobool( (char *)fixedc); new_node->boundary = strtobool( (char *)boundaryc ); new_node->sam = strtobool ( (char *)samc); new_node->node_set = 0; - + xmlFree(xc); xmlFree(yc); xmlFree(boundaryc); xmlFree(fixedc); xmlFree(samc); - - } cur=cur->next; } - + shuffled_nodes.clear(); shuffled_nodes = nodes; - + MyUrand r(shuffled_nodes.size()); random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r); - } -void Mesh::XMLReadWalls(xmlNode *root, vector *tmp_walls) { - +void Mesh::XMLReadWalls(xmlNode *root, vector *tmp_walls) +{ + xmlNode *cur = root; cur = cur->xmlChildrenNode; - + for (list::iterator i=walls.begin(); i!=walls.end(); i++) { delete *i; } - + walls.clear(); Wall::nwalls = 0; tmp_walls->clear(); - + QLocale standardlocale(QLocale::C); bool ok; while (cur!=NULL) { - + vector tmp_nodes; while(cur!=NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"wall"))) { - + xmlChar *nc = xmlGetProp(cur, BAD_CAST "c1"); - + if (nc==0) { unique_warning("Token \"c1\" not found in xmlwrite.cpp at or around line no. 777"); } int c1 = atoi( (char *)nc); xmlFree(nc); - + nc = xmlGetProp(cur, BAD_CAST "c2"); - + if ( nc==0) { unique_warning("Token \"c2\" not found in xmlwrite.cpp at or around line no. 785"); } int c2 = atoi( (char *)nc); xmlFree(nc); - + nc = xmlGetProp(cur, BAD_CAST "n1"); - + if ( nc==0) { unique_warning("Token \"n1\" not found in xmlwrite.cpp at or around line no. 793"); } int n1 = atoi( (char *)nc); xmlFree(nc); - + nc = xmlGetProp(cur, BAD_CAST "n2"); - + if ( nc==0) { unique_warning("Token \"n2\" not found in xmlwrite.cpp at or around line no. 801"); } int n2 = atoi( (char *)nc); xmlFree(nc); - + nc = xmlGetProp(cur, BAD_CAST "length"); - + if ( nc==0) { unique_warning("Token \"length\" not found in xmlwrite.cpp at or around line no. 809"); } @@ -1195,10 +1169,10 @@ void Mesh::XMLReadWalls(xmlNode *root, v if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc); xmlFree(nc); - - + + nc = xmlGetProp(cur, BAD_CAST "viz_flux"); - + double viz_flux = 0.0; if (nc!=0) { @@ -1206,13 +1180,13 @@ void Mesh::XMLReadWalls(xmlNode *root, v if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc); } xmlFree(nc); - + Wall::WallType wall_type; { xmlChar *v_str = xmlGetProp(cur, BAD_CAST "wall_type"); - + if (v_str != 0) { - + if (!xmlStrcmp(v_str, (const xmlChar *)"aux_source")) { wall_type = Wall::AuxSource; } else { @@ -1223,29 +1197,28 @@ void Mesh::XMLReadWalls(xmlNode *root, v } } xmlFree(v_str); - + } else { wall_type = Wall::Normal; } } - + bool dead = false; { // Note: property "delete" is used to manually clean up wall lists in XML files // Simply add property 'delete="true"' to the wall and it will be removed from // the mesh. (This saves us from manually reindexing the file). Otherwise do not use it. xmlChar *v_str = xmlGetProp(cur, BAD_CAST "delete"); - + if (v_str != 0) { dead = strtobool( (char *)v_str); xmlFree(v_str); } - } - + Cell *cc1 = c1 != -1 ? cells[c1] : boundary_polygon; Cell *cc2 = c2 != -1 ? cells[c2] : boundary_polygon; - + Wall *w = new Wall( nodes[n1], nodes[n2], cc1, cc2); w->length = length; w->viz_flux = viz_flux; @@ -1253,15 +1226,15 @@ void Mesh::XMLReadWalls(xmlNode *root, v w->dead = dead; tmp_walls->push_back(w); walls.push_back(w); - + xmlNode *w_node = cur->xmlChildrenNode; while (w_node!=NULL) { if ((!xmlStrcmp(w_node->name, (const xmlChar *)"transporters1"))) { - + xmlNode *v_node = w_node->xmlChildrenNode; int nv=0; while (v_node!=NULL) { - + if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) { if (nv>=Cell::NChem()) { { @@ -1273,7 +1246,7 @@ void Mesh::XMLReadWalls(xmlNode *root, v } } xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v"); - + if (nc==0) { unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 835"); } @@ -1283,16 +1256,14 @@ void Mesh::XMLReadWalls(xmlNode *root, v w->transporters1[nv++]=v; xmlFree(nc); - + } v_node = v_node->next; } - } - - + if ((!xmlStrcmp(w_node->name, (const xmlChar *)"transporters2"))) { - + xmlNode *v_node = w_node->xmlChildrenNode; int nv=0; while (v_node!=NULL) { @@ -1303,12 +1274,11 @@ void Mesh::XMLReadWalls(xmlNode *root, v text << "Exception in Mesh::XMLRead: Too many transporter values given for wall(s). Ignoring remaining values."; unique_warning(text.str().c_str()); break; - } } - + xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v"); - + if (nc==0) { unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 861"); } @@ -1321,15 +1291,14 @@ void Mesh::XMLReadWalls(xmlNode *root, v } v_node = v_node->next; } - } - + if ((!xmlStrcmp(w_node->name, (const xmlChar *)"apoplast"))) { - + xmlNode *v_node = w_node->xmlChildrenNode; int nv=0; while (v_node!=NULL) { - + if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) { if (nv>=Cell::NChem()) { { @@ -1341,7 +1310,7 @@ void Mesh::XMLReadWalls(xmlNode *root, v } } xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v"); - + if (nc==0) { unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 887"); } @@ -1364,263 +1333,257 @@ void Mesh::XMLReadWalls(xmlNode *root, v } -void Mesh::XMLReadWallsToCells(xmlNode *root, vector *tmp_walls) { - - // Add the walls to the cells (do this after reading the walls; read walls after reading cells...) - // 1. Read Nodes - // 2. Read Cells - // 3. Read Walls - // 4. Read Walls into Cells - - xmlNode *cur = root->xmlChildrenNode; - int ci=0; // cell index - - while (cur!=NULL) { - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"cell")) || - (!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon" ))) { - - vector tmp_walls_ind; - xmlNode *n = cur->xmlChildrenNode; - - while(n!=NULL) { - - if ((!xmlStrcmp(n->name, (const xmlChar *)"wall"))) { - xmlChar *nc = xmlGetProp(n, BAD_CAST "w"); - - if (nc==0) { - unique_warning("Token \"w\" not found in xmlwrite.cpp at or around line no. 931"); - } - tmp_walls_ind.push_back(atoi( (char *)nc)); - xmlFree(nc); - } - n = n->next; - } - - if (!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon")) { - - int nwalls = tmp_walls_ind.size(); - for (int i=0;iwalls.push_back((*tmp_walls)[tmp_walls_ind[i]]); - } - } else { - - int nwalls = tmp_walls_ind.size(); - for (int i=0;iwalls.push_back((*tmp_walls)[tmp_walls_ind[i]]); - } - - ci++; - } - - } - cur=cur->next; +void Mesh::XMLReadWallsToCells(xmlNode *root, vector *tmp_walls) +{ + + // Add the walls to the cells (do this after reading the walls; read walls after reading cells...) + // 1. Read Nodes + // 2. Read Cells + // 3. Read Walls + // 4. Read Walls into Cells + + xmlNode *cur = root->xmlChildrenNode; + int ci=0; // cell index + + while (cur!=NULL) { + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"cell")) || + (!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon" ))) { + + vector tmp_walls_ind; + xmlNode *n = cur->xmlChildrenNode; + + while(n!=NULL) { + + if ((!xmlStrcmp(n->name, (const xmlChar *)"wall"))) { + xmlChar *nc = xmlGetProp(n, BAD_CAST "w"); + + if (nc==0) { + unique_warning("Token \"w\" not found in xmlwrite.cpp at or around line no. 931"); + } + tmp_walls_ind.push_back(atoi( (char *)nc)); + xmlFree(nc); } - - + n = n->next; + } + + if (!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon")) { + + int nwalls = tmp_walls_ind.size(); + for (int i=0;iwalls.push_back((*tmp_walls)[tmp_walls_ind[i]]); + } + } else { + + int nwalls = tmp_walls_ind.size(); + for (int i=0;iwalls.push_back((*tmp_walls)[tmp_walls_ind[i]]); + } + ci++; + } + } + cur=cur->next; + } } -void Mesh::XMLReadNodeSetsToNodes(xmlNode *root) { - - xmlNode *cur = root->xmlChildrenNode; - int ci=0; // cell index - - while (cur!=NULL) { - - - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"node"))) { - - xmlNode *n = cur->xmlChildrenNode; - - while(n!=NULL) { - - xmlChar *nc = xmlGetProp(n, BAD_CAST "nodeset"); - - if (nc!=0) { - int nodeset_n = atoi( (char *)nc); - nodes[ci]->node_set = node_sets[nodeset_n]; - xmlFree(nc); - } else { - nodes[ci]->node_set = 0; - } - - n = n->next; - } - - ci++; - - } - cur=cur->next; +void Mesh::XMLReadNodeSetsToNodes(xmlNode *root) +{ + + xmlNode *cur = root->xmlChildrenNode; + int ci=0; // cell index + + while (cur!=NULL) { + + + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"node"))) { + + xmlNode *n = cur->xmlChildrenNode; + + while(n!=NULL) { + + xmlChar *nc = xmlGetProp(n, BAD_CAST "nodeset"); + + if (nc!=0) { + int nodeset_n = atoi( (char *)nc); + nodes[ci]->node_set = node_sets[nodeset_n]; + xmlFree(nc); + } else { + nodes[ci]->node_set = 0; } - - + + n = n->next; + } + ci++; + } + cur=cur->next; + } } -void Mesh::XMLReadNodeSets(xmlNode *root) { - - for (vector::iterator i=node_sets.begin(); - i!=node_sets.end(); - i++) { - delete *i; - } - - node_sets.clear(); - - xmlNode *cur = root->xmlChildrenNode; - - while (cur!=NULL) { - - NodeSet *new_nodeset=0; - - if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodeset"))){ - new_nodeset = new NodeSet(); - node_sets.push_back(new_nodeset); - } - - if (new_nodeset == 0) { - cur = cur->next; - continue; - } - new_nodeset->XMLRead(cur, this); - cur=cur->next; - } - +void Mesh::XMLReadNodeSets(xmlNode *root) +{ + + for (vector::iterator i=node_sets.begin(); + i!=node_sets.end(); + i++) { + delete *i; + } + + node_sets.clear(); + + xmlNode *cur = root->xmlChildrenNode; + + while (cur!=NULL) { + + NodeSet *new_nodeset=0; + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodeset"))){ + new_nodeset = new NodeSet(); + node_sets.push_back(new_nodeset); + } + + if (new_nodeset == 0) { + cur = cur->next; + continue; + } + new_nodeset->XMLRead(cur, this); + cur=cur->next; + } } -void Mesh::XMLReadCells(xmlNode *root) { - - for (vector::iterator i=cells.begin(); - i!=cells.end(); - i++) { - delete *i; - } - - cells.clear(); - Cell::NCells() = 0; - - delete boundary_polygon; - - - xmlNode *cur = root->xmlChildrenNode; - - while (cur!=NULL) { - - Cell *new_cell=0; +void Mesh::XMLReadCells(xmlNode *root) +{ + + for (vector::iterator i=cells.begin(); + i!=cells.end(); + i++) { + delete *i; + } + + cells.clear(); + Cell::NCells() = 0; + + delete boundary_polygon; + + + xmlNode *cur = root->xmlChildrenNode; + + while (cur!=NULL) { + + Cell *new_cell=0; - if ((!xmlStrcmp(cur->name, (const xmlChar *)"cell"))){ - - new_cell = new Cell(0,0); - new_cell->m = this; - cells.push_back(new_cell); - } else { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon"))) { - new_cell = boundary_polygon = new BoundaryPolygon(0,0); - boundary_polygon->m = this; - } - } - - if (new_cell == 0) { - cur = cur->next; - continue; - } - - new_cell->XMLRead(cur); - cur=cur->next; - } - + if ((!xmlStrcmp(cur->name, (const xmlChar *)"cell"))){ + + new_cell = new Cell(0,0); + new_cell->m = this; + cells.push_back(new_cell); + } else { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon"))) { + new_cell = boundary_polygon = new BoundaryPolygon(0,0); + boundary_polygon->m = this; + } + } + + if (new_cell == 0) { + cur = cur->next; + continue; + } + + new_cell->XMLRead(cur); + cur=cur->next; + } } -void Mesh::XMLRead(const char *docname, xmlNode **settings, bool geometry, bool pars, bool simtime) { - - xmlDocPtr doc = xmlParseFile(docname); - if (doc == NULL ) { - throw("Document not parsed successfully."); - return; - } - - xmlNodePtr cur = xmlDocGetRootElement(doc); - - if (cur == NULL) { - throw("Document is empty"); - xmlFreeDoc(doc); - return; - } - - if (xmlStrcmp(cur->name, (const xmlChar *) "leaf")) { - throw("XML file of the wrong type, it is not a leaf."); - xmlFreeDoc(doc); - return; - } - - /*Get the root element node */ - xmlNode *root_element = xmlDocGetRootElement(doc); +void Mesh::XMLRead(const char *docname, xmlNode **settings, bool geometry, bool pars, bool simtime) +{ + + xmlDocPtr doc = xmlParseFile(docname); + if (doc == NULL ) { + throw("Document not parsed successfully."); + return; + } + + xmlNodePtr cur = xmlDocGetRootElement(doc); + + if (cur == NULL) { + throw("Document is empty"); + xmlFreeDoc(doc); + return; + } + + if (xmlStrcmp(cur->name, (const xmlChar *) "leaf")) { + throw("XML file of the wrong type, it is not a leaf."); + xmlFreeDoc(doc); + return; + } + + /*Get the root element node */ + xmlNode *root_element = xmlDocGetRootElement(doc); - if (geometry) XMLReadGeometry(root_element); - if (pars) XMLReadPars(root_element); - if (simtime) XMLReadSimtime(root_element); - - // If pointer settings defined, return a copy of the settings tree - if (settings) { - xmlNode *cur = root_element->xmlChildrenNode; - // if settings field is not found, *settings will be returned 0. - *settings = 0; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"settings"))){ - *settings = xmlCopyNode(cur,1); - } - cur=cur->next; - } - } - xmlFreeDoc(doc); - - /* - *Free the global variables that may - *have been allocated by the parser. - */ - xmlCleanupParser(); - - // We're doing this so we can manually delete walls with by adding the 'delete="true"' property - CleanUpCellNodeLists(); - + if (geometry) XMLReadGeometry(root_element); + if (pars) XMLReadPars(root_element); + if (simtime) XMLReadSimtime(root_element); + + // If pointer settings defined, return a copy of the settings tree + if (settings) { + xmlNode *cur = root_element->xmlChildrenNode; + // if settings field is not found, *settings will be returned 0. + *settings = 0; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"settings"))){ + *settings = xmlCopyNode(cur,1); + } + cur=cur->next; + } + } + xmlFreeDoc(doc); + + /* + *Free the global variables that may + *have been allocated by the parser. + */ + xmlCleanupParser(); + + // We're doing this so we can manually delete walls with by adding the 'delete="true"' property + CleanUpCellNodeLists(); } -void Parameter::XMLRead(xmlNode *root) { - - xmlNode *cur = root->xmlChildrenNode; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ - xmlNode *par_node = cur->xmlChildrenNode; - while (par_node!=NULL) { - { - if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { - xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); - xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); - if (valc) { - AssignValToPar((const char*)namec,(const char*)valc); - } else { - /* Probably a valarray */ - xmlNode *sub_par_node = par_node->xmlChildrenNode; - vector valarray; - while (sub_par_node != NULL) { - if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { - valarray = XMLIO::XMLReadValArray(sub_par_node); - } - sub_par_node = sub_par_node->next; - } - AssignValArrayToPar((const char*)namec, valarray); - } - } - } - par_node = par_node->next; - } - +void Parameter::XMLRead(xmlNode *root) +{ + + xmlNode *cur = root->xmlChildrenNode; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"parameter"))){ + xmlNode *par_node = cur->xmlChildrenNode; + while (par_node!=NULL) { + { + if (!xmlStrcmp(par_node->name, (const xmlChar *)"par")) { + xmlChar *namec = xmlGetProp(par_node, BAD_CAST "name"); + xmlChar *valc = xmlGetProp(par_node, BAD_CAST "val"); + if (valc) { + AssignValToPar((const char*)namec,(const char*)valc); + } else { + /* Probably a valarray */ + xmlNode *sub_par_node = par_node->xmlChildrenNode; + vector valarray; + while (sub_par_node != NULL) { + if (!xmlStrcmp(sub_par_node->name, (const xmlChar *)"valarray")) { + valarray = XMLIO::XMLReadValArray(sub_par_node); } - cur=cur->next; - } - + sub_par_node = sub_par_node->next; + } + AssignValArrayToPar((const char*)namec, valarray); + } + } + } + par_node = par_node->next; + } + } + cur=cur->next; + } } +/* finis */ diff --git a/src/xmlwrite.h b/src/xmlwrite.h --- a/src/xmlwrite.h +++ b/src/xmlwrite.h @@ -31,9 +31,9 @@ namespace XMLIO { - std::vector XMLReadValArray(xmlNode *cur); + std::vector XMLReadValArray(xmlNode *cur); template long list_index (For beg, For end, E *elem) { - + long n = 0; for (For i=beg; i!=end; @@ -45,7 +45,6 @@ namespace XMLIO { } return -1; } - } @@ -66,3 +65,5 @@ inline bool strtobool(const char *str) { } #endif + +/* finis */