Changeset - 137d9d3a313a
[Not reviewed]
default
0 19 0
Michael Guravage - 15 years ago 2010-06-15 13:44:36
michael.guravage@cwi.nl
Removed most compilation warnings; see ChangeLogs for details.

--
user: Michael Guravage <michael.guravage@cwi.nl>
branch 'default'

changed .hgignore
changed src/ChangeLog
changed src/VirtualLeaf.cpp
changed src/apoplastitem.cpp
changed src/build_models/ChangeLog
changed src/build_models/auxingrowthplugin.cpp
changed src/build_models/meinhardtplugin.cpp
changed src/build_models/testplugin.cpp
changed src/canvas.cpp
changed src/cell.cpp
changed src/cellbase.h
changed src/forwardeuler.cpp
changed src/mainbase.h
changed src/mesh.cpp
changed src/nodeitem.cpp
changed src/output.cpp
changed src/qcanvasarrow.h
changed src/simitembase.cpp
changed src/xmlwrite.cpp
19 files changed with 101 insertions and 33 deletions:
0 comments (0 inline, 0 general)
.hgignore
Show inline comments
 
# use glob syntax.
 
syntax: glob
 

	
 
*~
 
*.a
 
*.exe
 
*.cache
 
*.Debug
 
*.o
 
*.orig
 
*.out
 
*.Release
 
*.so
 
*.vars
 
*Makefile.*
 
*make.out
 
*moc_*.cpp
 
src/default.par
 
bin*
 
TAGS
 
BROWSE
 

	
 
# switch to regexp syntax.
 
syntax: regexp
 

	
 
# finis
src/ChangeLog
Show inline comments
 
2010-06-15    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* mesh.cpp (findNextBoundaryNode): Initialize Node *next_boundary_node = NULL;
 

	
 
	* xmlwrite.cpp (XMLReadSimtime): Removed unused variable cur
 
	(XMLReadWalls): viz_flux need not be declared twice; default value of 0.0.
 
	(XMLReadCells): Removed unused count variable.
 
	(XMLReadSimtime): Removed unused cur variable.
 
	(XMLRead): Removed unused v_str variable.
 

	
 
	* simitembase.cpp (userMove): Use assignment merely to obviate compilation warning.
 
	(SimItemBase) Ditto.
 

	
 
	* qcanvasarrow.h (QGraphicsLineItem): Use assignment merely to obviate compilation warning.
 

	
 
	* output.cpp (OpenWriteFile): Removed unused par variable.
 

	
 
	* nodeitem.cpp (paint): Use assignment merely to obviate compilation warning.
 

	
 
	* forwardeuler.cpp (odeint): Use assignment merely to obviate compilation warning.
 

	
 
	* cell.cpp (DivideOverGivenLine): Use assignment merely to obviate compilation warning.
 

	
 
	* canvas.cpp (FigureEditor): Use assignments merely to obviate compilation errors.
 
	(mousePressEvent): Removed unused item variable.
 

	
 
	* apoplastitem.cpp
 
	(ApoplastItem): Removed unused par variable.
 
	(OnClick): Use NULL assignment merely to obviate compilation warning.
 

	
 
	* mainbase.h (MainBase): Use assignment merely to obviate compilation warning.
 

	
 
	* cellbase.h (CellsStaticDatamembers): Use assignment merely to obviate compilation warning.
 

	
 

	
 
	* cell.cpp: Wrapped diagnostic output in QDEBUG blocks.
 
	* VirtualLeaf.cpp ditto.
 
	* canvas.cpp ditto.
 
	* cell.cpp ditto.
 
	* cellbase.h
 
	* data_plot.cpp ditto.
 
	* forwardeuler.cpp ditto.
 
	* mesh.cpp ditto.
 
	* mesh.h
 
	* random.cpp ditto.
 
	* wall.cpp ditto.
 
	* wallbase.cpp ditto.
 
	* wallitem.cpp ditto.
 

	
 

	
 
2010-06-07    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeaf.pro: Removed explicit perl invocation to regerenerate parameter files.
 
	* libplugin.pro: ditto.
 

	
 
2010-06-03    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* pardialog.h: Added default versions of this automatically generated file.
 
	* pardialog.cpp: ditto.
 
	* parameter.h: ditto.
 
	* parameter.cpp: ditto.
 

	
 
	* VirtualLeaf.pro: delete/generate  parameter.{h,cpp}and pardialog.{h,cpp} only if perl is installed.
 
 	* libplugin.pro: dito.
 

	
 
	* Makefile: Added top-level Makefile
 

	
 
2010-05-10    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeaf.pro: Added -fPIC option to QMAKE_CXXFLAGS.
 

	
src/VirtualLeaf.cpp
Show inline comments
 
@@ -77,111 +77,114 @@ MainBase *main_window = 0;
 
class PrintNode {
 
public:
 
  void operator() (const Node &n) const 
 
  {
 
    cerr << n.Index() << ": " << n <<  endl;
 
  }
 
};
 

	
 

	
 
class EdgeSource {
 
	
 
public:
 
  void operator() (Cell &c) {
 
		
 
    if (c.AtBoundaryP()) {
 
      cerr << "Cell " << c.Index() << " is a source cell.\n";
 
      c.SetSource(0,par.source);
 
    } else {
 
      cerr << "Cell " << c.Index() << " is _not_ a source cell.\n";
 
    }
 
  }
 
};
 

	
 

	
 

	
 
class CellInfo {
 
public:
 
  void operator() (Cell &c,std::ostream &os) const {
 
    os << "Cell " << c.index << " says: " << endl;
 
    os << "c.nodes.size() = " << c.nodes.size() << endl;
 
    for (list<Node *>::iterator i=c.nodes.begin();
 
	 i!=c.nodes.end();
 
	 i++) {
 
      cerr << (*i)->Index() << " ";
 
    }
 
    cerr << endl;
 
  }
 
};
 

	
 
double PINSum(Cell &c) {
 
  return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj );
 
}
 

	
 

	
 
class DrawCell {
 
public:
 
  void operator() (Cell &c,QGraphicsScene &canvas, MainBase &m) const {
 
    if (m.ShowBorderCellsP() || c.Boundary()==Cell::None) {
 
      if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) 
 
      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 {
 
	  c.Draw(&canvas);
 
	}
 
      if (m.ShowCentersP())
 
      }
 
      if (m.ShowCentersP()){
 
	c.DrawCenter(&canvas);
 
      if (m.ShowFluxesP())
 
      }
 
      if (m.ShowFluxesP()){
 
	c.DrawFluxes(&canvas, par.arrowsize);
 
    }
 
  }
 
  }
 
};
 

	
 
Mesh mesh;
 
bool batch=false;
 

	
 
void MainBase::Plot(int resize_stride) {
 
	
 
  clear();
 
	
 
  static int count=0;
 
  if (resize_stride) {
 
    if ( !((++count)%resize_stride) ) {
 
      FitLeafToCanvas();
 
    }
 
  }
 
  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;
 
@@ -274,96 +277,99 @@ TIMESTEP {
 
      //mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division
 
				
 
      // Reaction diffusion	
 
      /*CelltoCellTransport *transport_f = &TestPlugin::CelltoCellTransport;
 
	CellReaction *cellreaction_f = new plugin->CellDynamics();
 
	WallReaction *wall_f = new WallDynamics();*/
 
				
 
      mesh.ReactDiffuse(par.rd_dt);
 
				
 
      t++;
 
				
 
      Plot(par.resize_stride);
 
		
 
      /*QVector< QPair<double, int> > angles=mesh.VertexAnglesValues();
 
	QString afname=QString("Angles/anglesvalues%1.dat").arg(t,6,10,QChar('0'));
 
	ofstream af(afname.toStdString().c_str());
 
      */
 
		
 
      /*for (QVector< QPair<qreal, int> >::const_iterator v=angles.begin();
 
	v!=angles.end();
 
	v++) {
 
	af << v->first << " " << v->second << endl;
 
	}
 
      */
 
    }
 
		
 
  } else {
 
			
 
    /*  TransportFunction *transport_f = new CelltoCellTransport();
 
	CellReaction *cellreaction_f = new CellDynamics();
 
	WallReaction *wall_f = new WallDynamics();
 
			
 
	mesh.ReactDiffuse_New(transport_f, cellreaction_f, wall_f, par.rd_dt);*/
 
    mesh.ReactDiffuse(par.rd_dt);
 
		
 
    Plot(par.resize_stride);
 
			
 
  }
 
		
 
  i++;
 
  return mesh.getTime();
 
		
 
}
 
		
 
		
 
				
 
/* Called if a cell is clicked */
 
void Cell::OnClick(QMouseEvent *e) {
 

	
 
  e = NULL; // use assignment merely to obviate compilation warning
 

	
 
  /* #ifdef HAVE_QWT
 
  // Launch DataPlot window
 
  QStringList curvenames;
 
  for (int i=0;i<NChem();i++) {
 
  curvenames += QString("Chem #%1").arg(i);
 
  }
 
  PlotDialog *plot = new PlotDialog((Main *)main_window, QString("Monitor for Cell %1").arg(Index()), curvenames);
 
  QObject::connect(this, SIGNAL(ChemMonValue(double, double *)),
 
  plot, SLOT(AddValue(double,double *)));
 
  #endif
 
  */
 
  //getMesh().plugin->OnClick(*this);
 
}
 
				
 

	
 
/* Custom message handler - Default appends a newline character to the end of each line. */ 
 
void vlMessageOutput(QtMsgType type, const char *msg)
 
{
 
  switch (type) {
 
  case QtDebugMsg:
 
    //fprintf(stderr, "Debug: %s\n", msg);
 
    cerr << msg << flush;
 
    break;
 
  case QtWarningMsg:
 
    //fprintf(stderr, "Warning: %s\n", msg);
 
    cerr << "Warning: " << msg << flush;
 
    break;
 
  case QtCriticalMsg:
 
    fprintf(stderr, "Critical: %s\n", msg);
 
    cerr << "Critical: " << msg << flush;
 
    break;
 
  case QtFatalMsg:
 
    //fprintf(stderr, "Fatal: %s\n", msg);
 
    cerr << "Fatal: " << msg << flush;
 
    abort();
 
  }
 
}
 
				
 

	
 
Parameter par;
 
				
 
int main(int argc,char **argv) {
 
					
 
  try {
 
						
 

	
 
    int c;
 

	
src/apoplastitem.cpp
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#include <string>
 
#include <QGraphicsScene>
 
#include "canvas.h"
 
#include "parameter.h"
 
#include "node.h"
 
#include "apoplastitem.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
ApoplastItem::ApoplastItem( Wall *w, QGraphicsScene *canvas )
 
: QGraphicsLineItem( 0, canvas ), SimItemBase( w, canvas){
 
		
 
	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.2 * factor * perp;
 
	Vector to = ( offs + *(w->N2()) ) *factor;// + (wn==1?-1:1) * par.outlinewidth;// * 0.2 * factor * perp;
 
	
 
	
 
	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);
 

	
 
	diffcolor.setRgb( 0,0,(int)( ( val / (1 + val) )*255.));
 
	setPen (QPen(diffcolor, 20) );
 

	
 
}
 

	
 
void ApoplastItem::OnClick(QMouseEvent *e) {
 
	
 
	
 
  e = NULL; // merely to obviate compile time warning
 
}
 

	
src/build_models/ChangeLog
Show inline comments
 
2010-06-15    <guravage@caterpie.sen.cwi.nl>
 

	
 

	
 
	* testplugin.cpp (CelltoCellTransport) Use NULL assignment merely to obviate compilation warnings.
 
	(WallDynamics): Ditto.
 
	(CellDynamics): Ditto.
 
	(OnDivide): Ditto.
 

	
 
	* meinhardtplugin.cpp (OnDivide): Use NULL assignment merely to obviate compilation warnings.
 
	* (WallDynamics): Ditto.
 

	
 
	* auxingrowthplugin.cpp (OnDivide): Use NULL assignment merely to obviate compilation warnings.
 

	
 
2010-06-03    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* Makefile: Added top-level Makefile.
 

	
 
2010-05-10    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* plugin_test.pro: Added -fPIC option to QMAKE_CXXFLAGS.
 
	* plugin_meinhardt.pro: ditto
 
	* plugin_auxingrowth.pro: ditto
 

	
 

	
src/build_models/auxingrowthplugin.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QObject>
 
#include <QtGui>
 
#include "../simplugin.h"
 

	
 
#include "parameter.h"
 

	
 
#include "wallbase.h"
 
#include "cellbase.h"
 
#include "auxingrowthplugin.h"
 

	
 
#include "far_mem_5.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
bool batch = false;
 

	
 

	
 
// To be executed after cell division
 
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;
 
	
 
	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]);
 
	
 
	
 
	// Reset transporter values of parent and daughter
 
	QList<WallBase *> walls;
 
	foreach(WallBase *w, walls) { 
 
		w->setTransporter(daughter1, 1, 0.);
 
	}
 
	
 
	//daughter1.LoopWalls(Wall::setTransporter(&daughter1, 1, 0.));
 
	
 
	
 
	/* for (list<Wall *>::const_iterator w=daughter2.walls.begin();
 
		 w!=daughter2.walls.end();
 
		 w++) {
 
		// reset transporter value
 
		(*w)->setTransporter(&daughter2, 1, 0.);
 
	}
 
	*/
 
}
 

	
 
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);
 
	
 
}
 

	
 

	
 

	
 
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();
 
        }		
src/build_models/meinhardtplugin.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QObject>
 
#include <QtGui>
 
#include "../simplugin.h"
 

	
 
#include "parameter.h"
 
#include "warning.h"
 
#include "wallbase.h"
 
#include "cellbase.h"
 
#include "meinhardtplugin.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
bool batch = false;
 

	
 
// To be executed after cell division
 
void MeinhardtPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
	
 
  parent_info = NULL;
 
  daughter1 = daughter2 = NULL;
 
}
 

	
 
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)<range_min) {
 
			MyWarning::warning("Whoops! Numerical instability!!");
 
			color->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();
 
	}
 
	
 
    // cell expansion is inhibited by substrate (chem 3)
 
	if (!par->constituous_expansion_limit || c->NCells()<par->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
 
  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;
 
		}
 
	
 

	
 
    // Passive fluxes (Fick's law)
 
    for (int c=0;c<NChem();c++) {
 
		double phi = w->Length() * ( 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;c<NChem();c++) {
 
		dw1[c] = 0.; dw2[c] = 0.;
 
    }
 
}
 

	
 
void MeinhardtPlugin::CellDynamics(CellBase *c, double *dchem) {
 

	
 
	double Y = c->Chemical(0);
 
	double A = c->Chemical(1);
 
	double H = c->Chemical(2);
 
	double S = c->Chemical(3);
 
	//double expansin = c->Chemical(4);
 
	
 
	
 
    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[4] = ( -par->expansindecay * expansin );
 
	//for (int i=0;i<4;i++) { cerr << "[ " << dchem[i] << " ]"; } cerr << endl;
 
	 
 
//	cerr << "Chemicals: "; for (int i=0;i<NChem();i++) { cerr << c->Chemical(i) << " "; } cerr << endl; 
 
	
 
// test:	dchem[0] = 0.01 * c->Chemical(0) * ( 1. - c->Chemical(0));
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(meinhardtplugin, MeinhardtPlugin)
src/build_models/testplugin.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QObject>
 
#include <QtGui>
 

	
 
#include "simplugin.h"
 

	
 
#include "parameter.h"
 

	
 
#include "wallbase.h"
 
#include "cellbase.h"
 
#include "testplugin.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
bool batch = false;
 

	
 
// To be executed after cell division
 
void TestPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
	
 
  parent_info = NULL;
 
  daughter1 = daughter2 = NULL;
 
}
 

	
 
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()]);
 
}
 

	
 

	
 

	
 
void TestPlugin::CellHouseKeeping(CellBase *c) {
 
	
 
	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) {}
 
void TestPlugin::WallDynamics(Wall *w, double *dw1, double *dw2) {}
 
void TestPlugin::CellDynamics(CellBase *c, double *dchem) { }
 
void TestPlugin::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  w = NULL;
 
  dchem_c1 = dchem_c2 = NULL;
 
}
 

	
 
void TestPlugin::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  w = NULL;
 
  dw1 = dw2 = NULL;
 
}
 

	
 
void TestPlugin::CellDynamics(CellBase *c, double *dchem) {
 
  c = NULL;
 
  dchem=NULL;
 
}
 

	
 
Q_EXPORT_PLUGIN2(testplugin, TestPlugin)
src/canvas.cpp
Show inline comments
 
@@ -56,227 +56,228 @@
 
#include <q3process.h>
 
#include <qlayout.h>
 
#include <qspinbox.h>
 
#include <fstream>
 
#include <sstream>
 
#include "pardialog.h"
 
#include "parameter.h"
 
#include "canvas.h"
 
#include "node.h"
 
#include "nodeset.h"
 
#include "nodeitem.h"
 
#include "cellitem.h"
 
#include "wallitem.h"
 
#include "mesh.h"
 
#include "xmlwrite.h"
 
#include "miscq.h"
 
#include "OptionFileDialog.h"
 
#include <cstdlib>
 
#include <cstdio>
 
#include "modelcatalogue.h"
 

	
 
#include <algorithm>
 

	
 
// Include VIB and PSB logos
 
#include "psb.xpm"
 
#include "cwi.xpm"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
// We use a global variable to save memory - all the brushes and pens in
 
// the mesh are shared.
 

	
 
#define QUOTE_ME(s) QUOTE_ME_2NDLEV(s)
 
#define QUOTE_ME_2NDLEV(s) #s
 

	
 
static QColor dark_red("darkRed");
 

	
 

	
 
static const int imageRTTI = 984376;
 
extern Parameter par;
 
const QString Main::caption("Virtual leaf");
 
const QString Main::caption_with_file("Virtual leaf: %1");
 

	
 
FigureEditor::FigureEditor(
 
			   QGraphicsScene& c, Mesh &m, QWidget* parent,
 
			   const char* name, Qt::WindowFlags f) :
 
  QGraphicsView(&c,parent), mesh(m)
 
{
 
  name = NULL; // use these two assignments merely to obviate compile time warnings
 
  f = Qt::Widget;
 

	
 
  intersection_line = 0;
 
  //angle_line = 0;
 
  setInteractive(true);
 
  moving = 0;  
 
  rotation_mode = false;
 
}
 

	
 

	
 
void FigureEditor::clear()
 
{
 
  QList<QGraphicsItem *> list = scene()->items();
 
  QList<QGraphicsItem *>::Iterator it = list.begin();
 
  for (; it != list.end(); ++it) {
 
    delete *it;
 
  }
 
}
 

	
 
 void FigureEditor::wheelEvent(QWheelEvent *event)
 
 {
 
   scaleView(pow((double)2, -event->delta() / 240.0));
 
 }
 

	
 

	
 
void FigureEditor::scaleView (qreal scaleFactor)
 
{
 
  qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)). width();
 
  if (factor < 0.07 || factor > 100) return;
 
  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::contentsMousePressEvent(QMouseEvent* e)
 
void FigureEditor::mousePressEvent(QMouseEvent* e)
 
{
 
  static QList<Node*> selected;
 
  emit MousePressed();
 

	
 
  //QPointF p = matrix().inverted().map(e->pos());
 
  QPointF p = mapToScene(e->pos());
 

	
 
  NodeItem *item;
 

	
 
#ifdef QDEBUG  
 
  qDebug() << endl << "MousePressEvent location: (" << p.x() << "," << p.y() << ")." << endl;
 
  qDebug() << "Magnification:  " << Cell::Magnification() << endl;
 
  qDebug() << "Offsets:  " << Cell::Offset() << endl;
 
#endif
 
  
 

	
 
  /*  if (dynamic_cast<Main *>(parent())->RotationModeP()) {
 
  // if in rotation mode, exit it upon a mouse click
 
  dynamic_cast<Main *>(parent())->ExitRotationMode();
 
  }*/
 
  
 
  QList<QGraphicsItem *> l=scene()->items(p);
 

	
 
#ifdef QDEBUG  
 
  qDebug() << "MousePressEvents, items: " << l.size() << endl;
 
  qDebug() << "Mouse button modifier: " << e->modifiers() << endl;
 
#endif
 

	
 

	
 
    /*  if (rotation_mid_point) {
 
    
 
    // calculate rotation angle alpha
 
    QPointF q_v1 = intersection_line->line().p2();
 
    - intersection_line->line().p1();
 
    QPointF q_v2 = angle_line->line().p2();
 
    - angle_line->line().p1();
 
    
 
    Vector v1(q_v1.x(),q_v1.y());
 
    Vector v2(q_v2.x(),q_v2.y());
 
    
 
    cerr << "v1 = " << v1 << endl;
 
    cerr << "v2 = " << v2 << endl;
 
    
 
    
 
    rot_angle = v1.SignedAngle(v2);
 
    cerr << "Angle is " << rot_angle << endl;
 
    
 
    const QPointF &q_c(angle_line->line().p1());
 
    Vector center = Vector(q_c.x(), q_c.y()) / Cell::Factor() - Cell::Offset();
 
    
 
    cerr << "Center is " << center << endl;
 
    
 
    mesh.Rotate(rot_angle, center);
 
    delete angle_line;
 
    angle_line=0;
 
    delete intersection_line;
 
    intersection_line=0;
 
    
 
    viewport()->setMouseTracking( FALSE );
 
    dynamic_cast<Main *>(parent())->Plot();
 
    
 
    
 
    return;
 
    
 
    }*/
 
  
 
   
 
    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<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) {
 
      /*if ( (*it)->rtti() == imageRTTI ) {
 
	ImageItem *item= (ImageItem*)(*it);
 
	if ( !item->hit( p ) )
 
	continue;
 
	}*/
 
      #ifdef QDEBUG
 
      qDebug() << typeid(**it).name() << endl;
 
      #endif QDEBUG
 
      #endif
 

	
 
      if ( !strcmp(typeid(**it).name(),"8NodeItem")) {
 
	//moving = dynamic_cast<NodeItem*>(*it);
 
	//moving = *it;
 
	//moving_start = p;
 
      
 
	stringstream data_strstream;
 
	data_strstream << (dynamic_cast<NodeItem*>(*it))->getNode();
 
	dynamic_cast<Main *>(parent())->UserMessage(QString(data_strstream.str().c_str()));
 
      
 
	(dynamic_cast<NodeItem*>(*it))->OnClick(e->button());
 
      }
 
      else 
 
	if ( !strcmp(typeid(**it).name(),"8CellItem") ) {
 
      
 
	  Cell &c=((dynamic_cast<CellItem *>(*it))->getCell());      
 
	  //static int old_stride=100;
 
	  //if (!c.Source()) {
 
	  /* if (!c.Source()) {
 
	     c.SetChemical(0,par.cellsource);
 
	     //flag=true;
 
	     //c.SetSource(0,par.cellsource);
 
	     //c.Fix();
 
	     //cerr << "Setting source\n";
 
			
 
	     } else { 
 
	     //c.UnsetSource();
 
	     cerr << "Unsetting source\n";
 
	     } */
 
	  // OnClick to be defined in end-user code
 
	  c.OnClick(e);
 
	} else {
 
	  if ( !strcmp(typeid(**it).name(),"8WallItem") ) {
 
	    (dynamic_cast<WallItem *>(*it))->OnClick(e);
 
	  } 
 
	}
 
    }
 

	
 
  FullRedraw();
 
  moving = 0;
 
}
 
  
 
//void FigureEditor::contentsMouseMoveEvent(QMouseEvent* e)
 
void FigureEditor::mouseMoveEvent(QMouseEvent* e)
 
{
 

	
 
  // User choose "rotation mode" and we can rotate the object around its center of mass
 
  if (dynamic_cast<Main *>(parent())->RotationModeP()) {
src/cell.cpp
Show inline comments
 
@@ -1768,97 +1768,97 @@ void Cell::DrawIndex(QGraphicsScene *c) 
 
}
 

	
 
// 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->setTextFlags(Qt::AlignCenter);
 
	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 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();
 
	
 
}
 

	
 
void Cell::DrawStrain(QGraphicsScene *c) const {
 
	></i>
 
  c = NULL; // assignment merely to obviate compilation warning
 
	MyWarning::warning("Sorry, Cell::DrawStrain temporarily not implemented.");
 
	/* Vector long_axis;
 
	double width;
 
	Length(&long_axis, &width);
 
	
 
	//cerr << "Length is "  << length << endl;
 
	long_axis.Normalise();
 
	Vector short_axis=long_axis.Perp2D();
 
    
 
	//  To test method "Strain" temporarily substitute "short_axis" for "strain" 
 
	Vector strain = Strain();
 
	//strain.Normalise();
 
	//static ofstream strainf("strain.dat");
 
	//strainf << strain.Norm() << endl;
 
	Vector centroid = Centroid();
 
	// Vector from = centroid - 0.5 * width * short_axis;
 
    // Vector to = centroid + 0.5 * width *short_axis;
 
	Vector from = centroid - 0.5 * strain;
 
	Vector to = centroid + 0.5 * strain;
 
	
 
	QGraphicsArrowItem *arrow = new QGraphicsArrowItem(0, c);
 
	arrow->setPen( QPen(QColor(par.arrowcolor),100) );
 
    
 
	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();
 
	*/
 
}
 

	
 
// Draw connecting lines to neighbors
 
/*void Cell::DrawTriangles(QCanvas &c) {
 
 
 
 for (list<Neighbor>::const_iterator nb=nb_list.begin();
 
 nb!=nb_list.end();
 
 nb++) {
 
 QCanvasLine *line = new QCanvasLine(&c);
 
 line->setPen( QPen(QColor("black"),2) );
 
 line->setZ(2);
 
 
 
 line->setPoints((offset[0]+x)*factor,(offset[1]+y)*factor, 
 
 (offset[0]+nb->c->x)*factor,(offset[1]+nb->c->y)*factor);
 
 line->setZ(10);
 
 line->show();
 
 }
 
 
src/cellbase.h
Show inline comments
 
@@ -445,58 +445,59 @@ protected:
 
    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;
 
	
 
    //double length;
 
    //Vector meanflux;
 
    //int valence;
 
    
 
    // 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);
 
}
 

	
 

	
 
#endif
 

	
 

	
 

	
 

	
 

	
src/forwardeuler.cpp
Show inline comments
 
@@ -22,96 +22,100 @@
 
#include <cmath>
 
#include <iostream> 
 
#include "forwardeuler.h"
 
#include "warning.h"
 
#include "maxmin.h"
 
#include <string>
 

	
 
using namespace std;
 

	
 
static const 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))
 
*/
 

	
 

	
 
const double ForwardEuler::Safety  = 0.9;
 
const double ForwardEuler::PGrow = -0.2;
 
const double ForwardEuler::Pshrnk = -0.25;
 
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 =
 
   0 results are stored at approximate intervals dxsav in the arrays xp[1..kount], yp[1..nvar]
 
   [1..kount], where kount is output by odeint. Defining declarations for these variables, with
 
   memoryallo cations xp[1..kmax] and yp[1..nvar][1..kmax] for the arrays, should be in
 
   the calling program.*/
 

	
 
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. */
 
{
 
  static bool warning_issued = false;
 

	
 
  eps = hmin = 0.0; // use assignment merely to obviate compilation warning
 
  nbad = nok = NULL;
 

	
 
  if (!warning_issued) {
 
    cerr << "Using inaccurate method ForwardEuler\n";
 
    warning_issued=true;
 
    //MyWarning::warning("Using inaccurate method ForwardEuler");
 
  }
 
  // 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<nvar;i++) y[i]=ystart[i];
 

	
 
  //if (kmax > 0) xsav=x-dxsav*2.0; //Assures storage of first step.
 

	
 
  dydx=new double[nvar];
 

	
 
  for (int nstp=0;nstp<Maxstp;nstp++) {
 
    
 
    derivs(x,y,dydx);
 
    
 
    if (kmax > 0 && kount < kmax-1) {
 
      xp[kount]=x; //Store intermediate results.
 
      for (int i=0;i<nvar;i++) yp[i][kount]=y[i];
 
      kount++;
 
      //xsav=x;
 
    }
 

	
 

	
 
    for (int i=0;i<nvar;i++) {
 
      y[i]=y[i] + h1 * dydx[i];
 
    }
 
      
 
    x = x + h1;
 

	
 
    if ((x-x2)*(x2-x1) >= 0.0) { //Are we done?
 
      goto done;
 
    }
 

	
 

	
 
  }
 

	
 
 done:
 
  for (int i=0;i<nvar;i++) ystart[i]=y[i];
 
  if (kmax) {
 
    xp[kount]=x; //Save final step.
src/mainbase.h
Show inline comments
 
@@ -75,79 +75,80 @@ class MainBase  {
 
    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<QGraphicsItem *> list = canvas.items();
 
      QList<QGraphicsItem *>::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 width=640) {
 
      
 
    //cerr << "Initializing Pixmap\n";
 
      
 
    cerr << "Saving to file " << fname << endl;
 
    QPixmap *image=new QPixmap(width, (int) (((double)canvas.height()/
 
    (double)canvas.width())*((double)width)));
 

	
 
    //QPicture *image = new QPicture();
 
      
 
    //cerr << "Done initializing QPixmap image(640, " << (((double)canvas.height()/(double)canvas.width())*640.) << ")\n";
 
    QPainter im(image);
 
    //cerr << "Done initializing image\n";
 
    im.scale((double)width/canvas.width(),(double)width/canvas.width());
 
    canvas.render(&im, QRectF(0,0,canvas.width(),canvas.height()) );
 
    //im.end();      
 
    image->save(QString(fname), format);
 
    }*/
 
    
 

	
 
    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:
 
    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 <qapplication.h>
 
#define TIMESTEP double MainBase::TimeStep(void)
 
#define INIT void MainBase::Init(char *leaffile)
 

	
 
#endif
src/mesh.cpp
Show inline comments
 
@@ -1613,97 +1613,97 @@ void Mesh::RepairBoundaryPolygon(void) {
 
    if (!internal_node) throw("Found a null Node pointer.");
 
    internal_node->UnsetBoundary();
 
  }
 

	
 
  boundary_polygon->ConstructConnections();
 
  for (list<Wall *>::iterator w=boundary_polygon->walls.begin();
 
       w!=boundary_polygon->walls.end();
 
       w++) {
 
    if ((*w)->DeadP()) {
 
      (*w)=0;
 
    }
 
  }
 
  boundary_polygon->walls.remove(0);
 
  boundary_polygon->ConstructNeighborList();
 
  
 
#ifdef QDEBUG
 
  qDebug() << "Repaired Boundary Polygon node indices: ";
 
  foreach (Node* node, boundary_polygon->nodes){
 
    qDebug() << node->Index() << " " ;
 
  }
 
  qDebug() << endl ;
 

	
 
  #ifdef _undefined_
 
  qDebug() << "NODES:" << endl;
 
  foreach(Node* node, nodes) {
 
    qDebug() << *node;
 
  }
 
  qDebug() << endl;
 

	
 
  qDebug() << "WALLS:" << endl;
 
  foreach(Wall* wall, walls) {
 
    qDebug() << *wall;
 
  }
 
  qDebug() << endl;
 

	
 
  qDebug() << "CELLS:" << endl;
 
  foreach(Cell* cell, cells) {
 
    qDebug() << *cell;
 
  }
 
  qDebug() << endl;
 
  #endif
 
#endif
 

	
 
}
 

	
 

	
 
Node* Mesh::findNextBoundaryNode(Node* boundary_node) {
 
  bool found_next_boundary_node = false;
 
  Node *next_boundary_node;
 
  Node *next_boundary_node = NULL;
 
  set<int> boundary_node_owners; // This is a list of the current boundary node's owners' Ids
 
  vector<int> neighborIds; // A list of the current boundary node's owners' 2nd neighbor Ids
 
  vector<set<int> *>  nodeOwners; // A vector of set pointers where each set contains the owner Ids of the nodes in the neighborIds list.
 
  vector<int> intersection; // set intersection result
 

	
 
  // The next boundary node is that which has only one owner in common with the current boundary node
 
  for (list<Neighbor>::iterator it=boundary_node->owners.begin(); it!=boundary_node->owners.end(); ++it) {
 
    if (it->cell->Index() != -1) boundary_node_owners.insert(it->cell->Index()); // Save each of the current boundary node's owners' Ids - except the boundary polygon 
 
    set<int> *owners = new set<int>; // create a set to hold a 2nd neighbor's owners' Ids
 
    nodeOwners.push_back(owners);
 
    neighborIds.push_back(it->nb2->Index());
 
    foreach(Neighbor neighbor, it->nb2->owners){
 
      if (neighbor.cell->Index() != -1) owners->insert(neighbor.cell->Index()); // Save second neighbors' owners' Ids - except the boundary polygon 
 
    }
 
  }
 
  vector<int>::iterator itt = neighborIds.begin();
 
  vector<set<int> *>::iterator it = nodeOwners.begin();
 

	
 
  #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
 

	
 
  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  
 
    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
 

	
 
    if (intersection.size() == 1){
 
      found_next_boundary_node = true;
 
      vector<Node *>::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  
 
      qDebug() << "The Current boundary node is: " << boundary_node->Index()
 
	       << ". The Next boundary node is: " << *itt << ((next_boundary_node->Marked()) ? " Marked" : " Unmarked") << endl << endl;
 
      #endif
 

	
src/nodeitem.cpp
Show inline comments
 
@@ -27,96 +27,97 @@
 
#include <Qt>
 
#include "nodeitem.h"
 
#include "parameter.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
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) {
 
  QGraphicsItem::moveBy( dx, dy );
 
  
 
  class_cast<Node *>(obj)->x += (dx/Cell::Magnification());
 
  class_cast<Node *>(obj)->y += (dy/Cell::Magnification());
 
}
 

	
 

	
 

	
 
void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
 
{
 

	
 
  // from Qt4.2 example: "elastic nodes"
 
  //painter->setPen(Qt::NoPen);
 
  //painter->setBrush(Qt::darkGray);
 
  //painter->drawEllipse(-70, -70, 200, 200);
 
  
 
  /* QRadialGradient gradient(-30, -30, 100);
 
     
 
  if (option->state & QStyle::State_Sunken) {
 
  gradient.setCenter(30, 30);
 
  gradient.setFocalPoint(30, 30);
 
  gradient.setColorAt(1, QColor(Qt::yellow).light(120));
 
  gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
 
  } else {
 
  gradient.setColorAt(0, Qt::yellow);
 
  gradient.setColorAt(1, Qt::darkYellow);
 
  }
 
  
 
  painter->setBrush(gradient); */
 
  option = NULL; // use assignment merely to obviate compilation warning
 
  
 
  painter->setBrush(brush);
 
  painter->setPen(Qt::NoPen);
 
  // const static double mag=20.;
 
  painter->drawEllipse(ellipsesize);
 
}
 

	
 

	
 
QPainterPath NodeItem::shape() const
 
{
 
    QPainterPath path;
 
    path.addEllipse(ellipsesize);
 
    return path;
 
}
 

	
 
QRectF NodeItem::boundingRect() const
 
{
 
  qreal penwidth = 0;// painter->pen()->widthF();
 
  return QRectF(ellipsesize.x()-penwidth/2.,ellipsesize.y()-penwidth/2.,
 
		ellipsesize.width()+penwidth, ellipsesize.height()+penwidth);
 
}
 

	
 
// polymorphic OnClick functions
 
void NodeItem::OnClick(void) {
 
  Node *n = &getNode();
 
  n->toggleBoundary();
 
  setColor();
 
  update();
 
}
 

	
 
void NodeItem::OnClick(const Qt::MouseButton &mb) {
 
  if (mb == Qt::LeftButton) {
 
    Node *n = &getNode();
 
    n->toggleBoundary();
 
    setColor();
 
    update();
 

	
 
  }
 
}
 

	
 
void NodeItem::setColor(void) {
 

	
 
  static QColor indian_red("IndianRed");
 
  static QColor deep_sky_blue("DeepSkyBlue");
 
  static QColor purple("Purple");
 
  
 
  Node &n=getNode();
 

	
src/output.cpp
Show inline comments
 
@@ -72,193 +72,190 @@ int YesNoP(const char *message) {
 
  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(char *filename) 
 
// {
 
//   FILE *fp;
 
//   fprintf(stderr,"Opening %s for writing\n",filename);
 
	
 
//   if((OpenFileAndCheckExistance(&fp,filename,"r"))==TRUE) {
 
// 	if (!YesNoP("File exists, overwrite?")) {
 
// 	  fprintf(stderr," Could not open file %s for writing, exiting... \n"
 
// 			  ,filename);
 
// 	  exit(0);
 
// 	}
 
//   }
 
  
 
//   if (fp!=NULL) // file existed, but user wants to overwrite
 
// 	fclose(fp);
 
  
 
//   if ((fp=fopen(filename,"w"))==NULL) {
 
// 	fprintf(stderr," Could not open file %s for writing, exiting... \n"
 
// 			,filename);
 
// 	exit(0);
 
//   }
 
	
 
//   return fp;
 
// }
 
*/
 
 
FILE *OpenWriteFile(const char *filename) 
 
{
 
 
  char fname[FNAMESIZE];
 
 
  FILE *fp;
 
  extern Parameter par;
 
 
  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?")) {
 
	sprintf(message," Could not open file %s for writing, exiting... \n"
 
		,filename);
 
	//exit(0);
 
	throw(message);
 
      }
 
    } else {
 
      /* 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: "
 
	    ,fname);
 
    perror("");
 
    throw(message);
 
  }
 
	
 
  return fp;
 
}
 
 
/*FILE *OpenGZippedWriteFile(const char *filename) 
 
{
 
 
  // Open file that is zipped while it is written
 
  // uses a pipe
 
    
 
  char fname[FNAMESIZE];
 
  char gzname[FNAMESIZE];
 
 
  FILE *fp;
 
  extern Parameter par;
 
 
  // step 1, add ".gz" to the filename
 
  sprintf(gzname, "%s.gz", filename);
 
  
 
  // and check whether it already exists
 
  fprintf(stderr,"Opening %s for writing\n",gzname);
 
	
 
  if(FileExistsP(gzname)==TRUE) {
 
  
 
    if (par.interactive) {
 
      if (!YesNoP("File exists, overwrite?")) {
 
	fprintf(stderr," Could not open file %s for writing, exiting... \n"
 
		,gzname);
 
	exit(0);
 
      }
 
    } else {
 
      // Rename old file 
 
      snprintf(fname, FNAMESIZE-1, "%s~",gzname);
 
      rename(gzname, fname);
 
      
 
    }
 
  }
 
  
 
  //  strncpy(fname, gzname, FNAMESIZE-1);
 
  char *command=new char[20+sizeof(gzname)];
 
  sprintf(command, "gzip -c > %s", gzname);
 
  
 
  if ((fp=popen(command,"w"))==NULL) {
 
    fprintf(stderr," Could not open file %s for writing: "
 
	    ,fname);
 
    perror("");
 
    exit(-1);
 
  }
 
	
 
  delete[] command;
 
  return fp;
 
}
 
*/
 
 
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);
 
    sprintf(message," File %s not found or empty, exiting... \n" ,filename);
 
    throw(message);
 
	  
 
  }
 
  return fp;
 
}
 
 
 
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. */
 
 
  /* 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 */
 
  
 
#define INITIAL_BUFSIZE 100
 
  
 
  char *tmpstring;
 
  int character;
 
  long bufsize;
 
  char *line;
 
  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)++;
 
 
	if (pos >= bufsize) {
 
	  /* line is longer than initial_bufsize, reallocate space */
 
	  bufsize+=INITIAL_BUFSIZE;
 
	  MEMORYCHECK(tmpstring=(char *)realloc(tmpstring,bufsize*sizeof(char)));
 
	  
 
	}
 
		   
 
  }
 
 
src/qcanvasarrow.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _QCANVASARROW_H_
 
#define _QCANVASARROW_H_
 

	
 
#include <QGraphicsScene>
 

	
 
class QGraphicsArrowItem : public QGraphicsLineItem {
 

	
 
 public:
 
  QGraphicsArrowItem(QGraphicsItem *parent, QGraphicsScene *c) : QGraphicsLineItem(parent, c) {
 
  };
 
    
 
    void paint ( QPainter *p, const QStyleOptionGraphicsItem *option,
 
		 QWidget *widget ) {
 
      
 
      widget = NULL; //use assignment merely to obviate compilation warning
 
      option = NULL;
 

	
 
      // construct arrow head
 
      QPointF start=line().p1();
 
      QPointF end=line().p2();
 
      QPointF mid=start + (3./4.)*(end-start);
 
      
 
      double vx=end.x()-start.x();
 
      double vy=end.y()-start.y();
 

	
 
      double length = sqrt(vx*vx+vy*vy);
 
      if (length==0) return;
 
      
 
      // perpendicular vector
 
      double px=-vy/length;
 
      double py=vx/length;
 
      
 
      // Arrow head lines go from end point
 
      // to points about 3/4 of the total arrow, extending sideways about 1/4
 
      // of the arrow length.
 
      
 
      
 
      QPointF arwp1 = mid + QPointF( (int)( (length/4.)*px ),
 
				   (int)( (length/4.)*py ) );
 
      QPointF arwp2 = mid - QPointF( (int)( (length/4.)*px ),
 
				   (int)( (length/4.)*py ) );
 
      
 
      p->setPen(pen());
 
      // Draw arrow head
 
      p->drawLine( end, arwp1 );
 
      p->drawLine( end, arwp2 );
 
      // Draw arrow line
 
      p->drawLine( start, end);
 
    }
 
};
 

	
 
#endif
src/simitembase.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QBrush>
 
#include "simitembase.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
SimItemBase::SimItemBase( void *v, QGraphicsScene *canvas ) {
 
  canvas = NULL; // use assignment merely to obviate compilation warning
 
    obj=v;
 
};
 

	
 
SimItemBase::~SimItemBase(void) {};
 

	
 

	
 
void SimItemBase::userMove(double dx, double dy) {
 

	
 
  dx = dy = 0.0; // use assignment merely to obviate compilation warning
 
};
src/xmlwrite.cpp
Show inline comments
 
@@ -306,97 +306,97 @@ getnodeset (xmlDocPtr doc, xmlChar *xpat
 
  if (result == NULL) {
 
    //printf("Error in xmlXPathEvalExpression\n");
 
    return NULL;
 
  }
 
  if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
 
    xmlXPathFreeObject(result);
 
    // printf("No result\n");
 
    return NULL;
 
  }
 
  return result;
 
}
 

	
 

	
 

	
 
int Cell::XMLRead(xmlNode *cur)  {
 
  
 
  xmlNode *n = cur->xmlChildrenNode;
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 

	
 
  vector<int> tmp_nodes;
 

	
 
	while(n!=NULL) {
 
    if ((!xmlStrcmp(n->name, (const xmlChar *)"node"))) {
 
      xmlChar *nc = xmlGetProp(n, BAD_CAST "n");
 

	
 
      if (nc==0) {
 
	unique_warning("Token \"n\" not found in xmlwrite.cpp at or around line no. 966");
 
      }
 
      tmp_nodes.push_back(atoi( (char *)nc));
 
      xmlFree(nc);
 

	
 
    }
 
    n = n->next;
 
  }
 
      
 
  int nnodes = tmp_nodes.size();
 
  for (int i=0;i<nnodes;i++) {
 
    m->AddNodeToCell( 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"))) {
 
	    xmlChar *v_str = xmlGetProp(n, BAD_CAST "n");
 

	
 
	    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.";
 
		    //ThrowStringStream(text);
 
		    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 = strtod( (char *)nc, 0 );
 
		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 = strtod( (char *)v_str, 0);
 
			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);
 
		}
 
	}
 
	
 
@@ -862,97 +862,96 @@ void Mesh::XMLSave(const char *docname, 
 
		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
 
	 */
 
	//xmlMemoryDump();
 
}
 

	
 

	
 

	
 
void Mesh::XMLReadSimtime(const xmlNode *a_node) {
 
	
 
  xmlNode *root_node;
 
  root_node = (xmlNode *)a_node;
 
  xmlNode *cur;
 
  xmlChar *strsimtime = xmlGetProp(root_node, BAD_CAST "simtime");
 
  
 
  
 
  if (strsimtime) {
 
    //double simtime = strtod((const char *)strsimtime, 0);
 
    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;
 
		cerr << "Simtime = " << strsimtime << endl;
 
	} else {
 
		cerr << "No simtime found in file \n";
 
		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::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);
 
		}
 
@@ -1178,106 +1177,101 @@ void Mesh::XMLReadWalls(xmlNode *root, v
 
      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");
 
	}
 
	//double length = strtod( (char *)nc, 0);
 
	double length = standardlocale.toDouble((const char *)nc, &ok);
 
	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;
 
	double viz_flux = 0.0;
 
	if (nc!=0) {
 
	  //viz_flux = strtod( (char *)nc, 0);
 
	  double viz_flux = standardlocale.toDouble((const char *)nc, &ok);
 
	  viz_flux = standardlocale.toDouble((const char *)nc, &ok);
 
	  if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc);
 

	
 
	} else {
 
	  // if the info is not there, we really don't care.
 
	  // It is just for visualization anyhow.
 
	  viz_flux = 0.;
 
	}
 
	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 {
 
	      if (!xmlStrcmp(v_str, (const xmlChar *)"aux_sink")) {
 
		wall_type = Wall::AuxSink;
 
	      } else {
 
		wall_type = Wall::Normal;
 
	      }
 
	    }
 
	    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;
 
	w->wall_type = wall_type;
 
	w->dead = dead;
 
	tmp_walls->push_back(w);
 
@@ -1499,97 +1493,97 @@ void Mesh::XMLReadNodeSets(xmlNode *root
 
	for (vector<NodeSet *>::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<Cell *>::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;
 
		static int count=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;
 
	}
 
	
 
}
 

	
 
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);
 
	
0 comments (0 inline, 0 general)