Changeset - 311dea91a9b6
[Not reviewed]
Merge default
1 23 19
Michael Guravage - 15 years ago 2010-06-04 16:05:21
michael.guravage@cwi.nl
Merged Roeland's latest changes with my project file changes (16:3f0977faba37).

--
user: Michael Guravage <michael.guravage@cwi.nl>
branch merge
branch 'default'
changed src/Makefile
changed src/TutorialCode/Tutorial0/mymodel.cpp
changed src/TutorialCode/Tutorial0/mymodel.h
changed src/TutorialCode/Tutorial0/mymodel.pro
changed src/TutorialCode/Tutorial1/mymodel.cpp
changed src/TutorialCode/Tutorial1/mymodel.h
changed src/TutorialCode/Tutorial1/mymodel.pro
changed src/TutorialCode/Tutorial2/mymodel.cpp
changed src/TutorialCode/Tutorial2/mymodel.h
changed src/TutorialCode/Tutorial2/mymodel.pro
changed src/TutorialCode/Tutorial3/mymodel.cpp
changed src/TutorialCode/Tutorial3/mymodel.h
changed src/TutorialCode/Tutorial3/mymodel.pro
changed src/TutorialCode/Tutorial4/mymodel.cpp
changed src/TutorialCode/Tutorial4/mymodel.h
changed src/TutorialCode/Tutorial4/mymodel.pro
changed src/TutorialCode/Tutorial5/mymodel.cpp
changed src/TutorialCode/Tutorial5/mymodel.h
changed src/TutorialCode/Tutorial5/mymodel.pro
changed src/VirtualLeaf.pro
changed src/VirtualLeafpar.tmpl
changed src/build_models/Makefile
changed src/build_models/auxingrowthplugin.cpp
changed src/build_models/auxingrowthplugin.h
changed src/build_models/leafplugin.cpp
changed src/build_models/leafplugin.h
changed src/build_models/meinhardtplugin.cpp
changed src/build_models/meinhardtplugin.h
changed src/build_models/plugin_auxingrowth.pro
changed src/build_models/plugin_leaf.pro
changed src/build_models/plugin_meinhardt.pro
changed src/build_models/plugin_test.pro
changed src/build_models/testplugin.cpp
changed src/build_models/testplugin.h
changed src/build_models/translate_plugin.pl
changed src/cell.cpp
changed src/cellbase.h
changed src/libplugin.pro
changed src/mesh.cpp
changed src/mesh.h
changed src/modelcatalogue.cpp
changed src/simplugin.h
removed src/build_models/simplugin.h
42 files changed with 1422 insertions and 207 deletions:
0 comments (0 inline, 0 general)
src/Makefile
Show inline comments
 
# $Id$
 

	
 
QMAKE = qmake
 

	
 
all: VirtualLeaf libplugin plugins
 

	
 
VirtualLeaf: Makefile.VirtualLeaf
 
	make -f Makefile.VirtualLeaf
 

	
 
Makefile.VirtualLeaf: VirtualLeaf.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
libplugin: Makefile.libplugin
 
	make -f Makefile.libplugin
 

	
 
Makefile.libplugin: libplugin.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugins:
 
	make -C build_models
 

	
 
clean:
 
	make -f Makefile.libplugin clean
 
	make -f Makefile.VirtualLeaf clean
 
	make -C build_models clean
 

	
 
#finis
src/TutorialCode/Tutorial0/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "My first model in VirtualLeaf" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 0; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 

	
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
}
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial0/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial0/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/TutorialCode/Tutorial1/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "Cell growth" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 0; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 

	
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
	c->EnlargeTargetArea(par->cell_expansion_rate);
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
}
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial1/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial1/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/TutorialCode/Tutorial2/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "Cell growth and cell division" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 0; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 

	
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
	c->EnlargeTargetArea(par->cell_expansion_rate);
 
	if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) {
 
		c->Divide();
 
	}
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
}
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial2/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial2/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/TutorialCode/Tutorial3/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "Cell growth and cell division" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 0; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
	c->EnlargeTargetArea(par->cell_expansion_rate);
 
	if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) {
 
		c->DivideOverAxis(Vector(1,0,0));
 
	}
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
}
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial3/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial3/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/TutorialCode/Tutorial4/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "Growth, division, coloring" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 0; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 
	if (c->Area()/c->BaseArea()>1.8) { color->setNamedColor("blue"); }
 
	else { color->setNamedColor("green"); }
 

	
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
	c->EnlargeTargetArea(par->cell_expansion_rate);
 
	if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) {
 
		c->Divide();
 
	}
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
}
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial4/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial4/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/TutorialCode/Tutorial5/mymodel.cpp
Show inline comments
 
new file 100644
 
/*
 
 *
 
 *  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 "mymodel.h"
 

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

	
 
QString MyModel::ModelID(void) {
 
  // specify the name of your model here
 
  return QString( "Growth hormones" );
 
}
 

	
 
// return the number of chemicals your model uses
 
int MyModel::NChem(void) { return 1; }
 

	
 
// To be executed after cell division
 
void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
  // rules to be executed after cell division go here
 
  // (e.g., cell differentiation rules)
 
	
 
	// set one cell to source after first division
 
	if (CellBase::NCells()==2) {
 
		daughter1->SetCellType(1);
 
		daughter2->SetCellType(0);
 
	}
 
	
 
	// if a source cells has divided, one of the daughters becomes the new source
 
	if (daughter1->CellType()==1) {
 
		
 
		// if both cells are at the tissue perimeter, choose at random
 
		if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) {
 
		
 
			if (qrand()%2){
 
				daughter1->SetCellType(1);
 
				daughter2->SetCellType(0);
 
			} else {
 
				daughter1->SetCellType(0);
 
				daughter2->SetCellType(1);
 
			}
 
		} else {
 
			// otherwise choose the one that is still at the perimeter
 
			if (daughter1->AtBoundaryP()) {
 
				daughter1->SetCellType(1);
 
				daughter2->SetCellType(0);
 
			} else {
 
				daughter1->SetCellType(0);
 
				daughter2->SetCellType(1);
 
			}
 
		}
 
	}
 
	
 
}
 

	
 
void MyModel::SetCellColor(CellBase *c, QColor *color) { 
 
  // add cell coloring rules here
 
	
 
	// white: high concentration of growth hormone, black low concentration
 
	double val = c->Chemical(0)/(1.+c->Chemical(0));
 
	color->setRgbF(val, val, val);
 
}
 

	
 
void MyModel::CellHouseKeeping(CellBase *c) {
 
  // add cell behavioral rules here
 
	if (CellBase::NCells()==1)
 
		// first cell expands unconditionally 
 
		c->EnlargeTargetArea(par->cell_expansion_rate);
 
	else 
 
		c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate);
 
	
 
	if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) {
 
		c->Divide();
 
	}
 
}
 

	
 
void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) {
 
  // add biochemical transport rules here
 
	double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) );
 
	dchem_c1[0]+=phi;
 
	dchem_c2[0]-=phi;
 
}
 

	
 
void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) {
 
  // add biochemical networks for reactions occuring at walls here
 
}
 
void MyModel::CellDynamics(CellBase *c, double *dchem) { 
 
  // add biochemical networks for intracellular reactions here
 
	if (c->CellType()==1) {
 
		dchem[0] = par->leaf_tip_source;
 
	}
 
}
 

	
 

	
 
Q_EXPORT_PLUGIN2(mymodel, MyModel)
src/TutorialCode/Tutorial5/mymodel.h
Show inline comments
 
new file 100644
 
/*
 
 *  $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 <QObject>
 
#include <QtGui>
 
#include <QString>
 
#include "simplugin.h"
 

	
 

	
 
class MyModel : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void);
 
	
 
	// 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 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 for coloring a cell
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void);
 
};
 

	
 

	
 

	
 

	
src/TutorialCode/Tutorial5/mymodel.pro
Show inline comments
 
new file 100644
 
#
 
# $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.
 
#
 

	
 

	
 
TARGET = mymodel
 
VLEAFHOME = ../../..
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
 
SOURCES = $${TARGET}.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finish
src/VirtualLeaf.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += qt
 

	
 
QMAKE_CXXFLAGS += -fexceptions
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
#REACTIONS = reactions_auxin_growth.h 
 
#REACTIONS = reactions_meinhardt.h
 
#REACTIONS = reactions_pce_growth.h
 
DEFINES += QTGRAPHICS
 
DEFINES += REACTIONS_HEADER=$${REACTIONS}
 
DEFINES += REACTIONS_HEADER_STRING=\"$${REACTIONS}\"
 
DEFINES += FLEMING
 

	
 
PERLDIR = ./perl
 
BINDIR = ../bin
 
DESTDIR = $$BINDIR
 
TARGET = VirtualLeaf
 
TEMPLATE = app
 
PARTMPL = $${TARGET}par.tmpl
 
MAINSRC = $${TARGET}.cpp
 
QT -= network sql xml
 
QT += qt3support
 

	
 
!win32 {
 
 GRAPHICS = qt #qwt
 
}
 

	
 
win32 {
 
 system(WHERE /Q perl && IF errorlevel 0 (DEL parameter.cpp parameter.h pardialog.cpp pardialog.h)
 
 system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_parameter_source.pl $$PARTMPL)
 
 system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_pardialog_source.pl $$PARTMPL)
 
#system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_xmlwritecode.pl -h $$REACTIONS)
 

	
 
 CONFIG += console
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 system(DEL parameter.cpp parameter.h) 
 
 GRAPHICS = qt 
 
 RC_FILE = VirtualLeaf.rc
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
 QMAKE_POST_LINK = "\
 
  C:\Bin\cp release\VirtualLeaf.exe \
 
  C:\Qt\4.5.3\bin\Qt3Support4.dll \
 
  C:\Qt\4.5.3\bin\QtGui4.dll \
 
  C:\Qt\4.5.3\bin\QtSql4.dll \
 
  C:\Qt\4.5.3\bin\QtXml4.dll \
 
  C:\Qt\4.5.3\bin\QtCore4.dll \
 
  C:\Qt\4.5.3\bin\QtNetwork4.dll \
 
  C:\Qt\4.5.3\bin\QtSvg4.dll \
 
  C:\bin\iconv.dll \
 
  C:\bin\libxml2.dll \
 
  C:\bin\zlib1.dll \
 
  C:\MinGW\bin\mingwm10.dll \
 
  $${DESTDIR}"
 
 LIBS += -L$${LIBXML2DIR}\lib -lxml2 -L$${LIBICONVDIR}\lib -L$${LIBZDIR}\lib  -lz -lm -lwsock32 -liconv
 
}
 

	
 
# Application icons
 
macx {
 
 ICON = leaficon.icns
 
 # make sure that the executable can find the libqwt share library
 
 QMAKE_POST_LINK = "mkdir $${DESTDIR}/$${TARGET}.app/Contents/Frameworks; \
 
  cp /usr/local/qwt/lib/libqwt.dylib $${DESTDIR}/$${TARGET}.app/Contents/Frameworks/.; \
 
  #install_name_tool -change libqwt.5.dylib $$QWTDIR/lib/libqwt.dylib $${DESTDIR}/$${TARGET}.app/Contents/MacOS/$${TARGET}; \
 
  install_name_tool -id @executable_path/../Frameworks/libqwt.dylib $${DESTDIR}/$${TARGET}.app/Contents/Frameworks/libqwt.dylib; \
 
  install_name_tool -change libqwt.5.dylib @executable_path/../Frameworks/libqwt.dylib $${DESTDIR}/$${TARGET}.app/Contents/MacOS/$${TARGET};\
 
  cp leaficon.icns $${DESTDIR}/$${TARGET}.app; "
 
}
 

	
 
macx:release {
 
 LIBS+= -dead_strip
 
}
 

	
 
unix {
 
 system(if `which perl > /dev/null 2>&1` ; then rm -f parameter.cpp parameter.h pardialog.cpp pardialog.h; fi)
 
 system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_parameter_source.pl $$PARTMPL; fi)
 
 system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_pardialog_source.pl $$PARTMPL; fi)
 
#system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_xmlwritecode.pl -h $$REACTIONS; fi)
 
 CC = /usr/bin/gcc 
 
 QWTDIR = /ufs/guravage/opt/qwt-5.2.1-svn
 
 QMAKE_LIBDIR += $$QWTDIR/lib 
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
 LIBS += -lxml2 -lz -lm 
 
}
 

	
 
# Input
 
HEADERS += \
 
 apoplastitem.h \
 
 canvas.h \
 
 cellbase.h \
 
 cell.h \
 
 cellitem.h \
 
 forwardeuler.h \
 
# forwardeuler.h \
 
 infobar.h \
 
 mainbase.h \
 
 mainbase.h \
 
 matrix.h \
 
 mesh.h \
 
 miscq.h \
 
 modelcatalogue.h \
 
 Neighbor.h \
 
 node.h \
 
 nodeitem.h \
 
 nodeset.h \
 
 OptionFileDialog.h \
 
 output.h \
 
 parameter.h \
 
 pardialog.h \
 
 parse.h \
 
 pi.h \
 
 qcanvasarrow.h \
 
 random.h \
 
 rungekutta.h \
 
 simitembase.h \
 
 simplugin.h \
 
 sqr.h \
 
 tiny.h \
 
 transporterdialog.h \
 
 UniqueMessage.h \
 
 vector.h \
 
 wallbase.h \
 
 wall.h \
 
 wallitem.h \
 
 warning.h \
 
 xmlwrite.h \
 
 $${PARTMPL}
 

	
 
SOURCES += \
 
 apoplastitem.cpp \
 
 canvas.cpp \
 
 cellbase.cpp \
 
 cell.cpp \
 
 cellitem.cpp \
 
 forwardeuler.cpp \
 
# forwardeuler.cpp \
 
 mainbase.cpp \
 
 matrix.cpp \
 
 mesh.cpp \
 
 miscq.cpp \
 
 modelcatalogue.cpp \
 
 Neighbor.cpp \
 
 node.cpp \
 
 nodeitem.cpp \
 
 nodeset.cpp \
 
 OptionFileDialog.cpp \
 
 output.cpp \
 
 parameter.cpp \
 
 pardialog.cpp \
 
 parse.cpp \
 
 random.cpp \
 
 rungekutta.cpp \
 
 simitembase.cpp \
 
 transporterdialog.cpp \
 
 UniqueMessage.cpp \
 
 vector.cpp \
 
 wallbase.cpp \
 
 wall.cpp \
 
 wallitem.cpp \
 
 warning.cpp \
 
 xmlwritecode.cpp \
 
 xmlwrite.cpp \
 
 $$MAINSRC
 

	
 
contains( TARGET, leaf_fleming ) {
 
 DEFINES += FLEMING	
 
}
 

	
 
contains(GRAPHICS, qwt) {
 
 #macx:LIBS += -L$$QWTDIR/lib -lqwt
 
 #win32:LIBS += -L$$QWTDIR/lib -lqwt5
 
 #LIBS += -L$$QWTDIR/lib -lqwt
 
 INCLUDEPATH += $$QWTDIR/include
 
 DEFINES += HAVE_QWT
 
 HEADERS += data_plot.h
 
 SOURCES += data_plot.cpp
 
}
 

	
 
contains( GRAPHICS, qt ) {
 
 message( "Building Qt executable" )
 
 QMAKE_CXXFLAGS += -DQTGRAPHICS # -fpermissive
 
}
 

	
 
contains( GRAPHICS, xfig ) {
 
 message("Building Xfig executable (background runnable).")
 
 QMAKE_CXXFLAGS += -DXFIGGRAPHICS
 
}
 

	
 
contains( GRAPHICS, x11 ) {
 
 !unix {
 
  error("X11 graphics only available on Unix systems.")
 
 }
 
 message("Building X11 executable")
 
 SOURCES += x11graph.cpp
 
 HEADERS += x11graph.h
 
 QMAKE_CXXFLAGS += -DX11GRAPHICS
 
 CONFIG -= qt
 
 CONFIG += x11
 
 unix:LIBS += -lpng
 
}
 

	
 
# finis
src/VirtualLeafpar.tmpl
Show inline comments
 
title = Parameter values for The Virtual Leaf / title
 
label = <b>Visualization</b> / label
 
arrowcolor = white / string
 
arrowsize = 100 / double
 
textcolor = red / string
 
cellnumsize = 1 / int
 
nodenumsize = 1 / int
 
node_mag = 1.0 / double 
 
outlinewidth = 1.0 / double
 
cell_outline_color = forestgreen / string
 
resize_stride = 10 / int
 
resize_stride = 0 / int
 
label = / label
 
label = <b>Cell mechanics</b> / label
 
T = 1.0 / double
 
lambda_length = 100. / double
 
lambda_celllength = 0. / double
 
target_length = 60. / double 
 
cell_expansion_rate = 1. / double
 
cell_div_expansion_rate = 0. / double
 
auxin_dependent_growth = true / bool
 
ode_accuracy = 1e-4 / double
 
mc_stepsize = 0.4 / double
 
mc_cell_stepsize = 0.2 / double
 
energy_threshold = 1000. / double
 
bend_lambda = 0. / double
 
alignment_lambda = 0. / double
 
rel_cell_div_threshold = 2. / double
 
rel_perimeter_stiffness = 2 / double
 
collapse_node_threshold = 0.05 / double
 
morphogen_div_threshold = 0.2 / double
 
morphogen_expansion_threshold = 0.01 / double
 
copy_wall = true / bool
 
label = / label
 
label = <b>Auxin transport and PIN1 dynamics</b> / label
 
source = 0. / double
 
D = 0., 0.0, 0.0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
initval = 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
k1 = 1. / double
 
k2 = 0.3 / double
 
r = 1. / double
 
kr = 1. / double
 
#k3 = 1 / double
 
#k4 = 0.3 / double
 
km = 1. / double
 
Pi_tot = 1. / double
 
transport = 0.036 / double
 
ka = 1 / double
 
# d = 1e-06 / double
 
# e = 0.01 / double
 
# f = 10 / double
 
pin_prod = 0.001 / double
 
pin_prod_in_epidermis = 0.1 / double
 
pin_breakdown = 0.001 / double
 
pin_breakdown_internal = 0.001 / double
 
aux1prod = 0.001 / double
 
aux1prodmeso = 0. / double
 
aux1decay = 0.001 / double
 
aux1decaymeso = 0.1 / double
 
aux1transport = 0.036 / double
 
aux_cons = 0. / double
 
aux_breakdown = 0. / double
 
kaux1 = 1 / double
 
kap = 1 / double
 
leaf_tip_source = 0.001 / double
 
sam_efflux = 0.0001 / double
 
sam_auxin = 10. / double
 
# gf_prod = 1e-3 / double
 
# gf_decay = 1e-3 / double
 
sam_auxin_breakdown = 0 / double
 
#label = / label
 
#label = <b>miscellaneous</b> / label
 
van3prod = 0.002 / double
 
van3autokat = 0.1 / double
 
van3sat = 10 / double
 
k2van3 = 0.3 / double
 
#glvprod = 0.0 / double
 
#glvbreakdown = 0. / double
 
label = / label
 
label = <b>Integration parameters</b> / label
 
dt = 0.1 / double 
 
rd_dt = 1.0 / double
 
datadir = . / directory 
 
movie = false / bool
 
nit = 100000 / int
 
maxt = 1000. / double
 
storage_stride = 10 / int
 
xml_storage_stride = 500 / int
 
rseed = -1 / int
 
#label = / label
 
#label = <b>Parameters for new chemical</b> / label
 
#glvproduction = 0. / double
 
#glvdecay = 0. / double
 
#glvdiffthreshold = 0. / double
 
label = / label
 
label = <b>Meinhardt leaf venation model</b> / label
 
constituous_expansion_limit = 16 / int
 
vessel_inh_level = 1 / double
 
vessel_expansion_rate = 0.25 / double
 
d = 0. / double
 
e = 0. / double
 
f = 0. / double
 
c = 0. / double
 
mu = 0. / double
 
nu = 0. / double
 
rho0 = 0. / double
 
rho1 = 0. / double
 
c0 = 0. / double
 
gamma = 0. / double
 
eps = 0. / double
 
label = / label
 
label = <b>User-defined parameters</b> / label
 
k = 0., 0.0, 0.0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
i1 = 0 / int
 
i2 = 0 / int
 
i3 = 0 / int
 
i4 = 0 / int
 
i5 = 0 / int
 
s1 =  / string
 
s2 =  / string
 
s3 =  / string
 
b1 = false / bool
 
b2 = false / bool
 
b3 = false / bool
 
b4 = false / bool
 
dir1 = . / directory
 
dir2 = . / directory
src/build_models/Makefile
Show inline comments
 
# $Id$
 

	
 
QMAKE = qmake
 

	
 
all: plugin_auxingrowth plugin_leaf plugin_meinhardt plugin_test
 

	
 
plugin_auxingrowth: Makefile.plugin_auxingrowth
 
	make -f Makefile.plugin_auxingrowth
 

	
 
Makefile.plugin_auxingrowth: plugin_auxingrowth.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_leaf: Makefile.plugin_leaf
 
	make -f Makefile.plugin_leaf
 

	
 
Makefile.plugin_leaf: plugin_leaf.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_meinhardt: Makefile.plugin_meinhardt
 
	make -f Makefile.plugin_meinhardt
 

	
 
Makefile.plugin_meinhardt: plugin_meinhardt.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_test: Makefile.plugin_test
 
	make -f Makefile.plugin_test
 

	
 
Makefile.plugin_test: plugin_test.pro
 
	qmake -makefile -o $@ $< 
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
clean:
 
	make -f Makefile.plugin_auxingrowth clean
 
	make -f Makefile.plugin_leaf clean
 
	make -f Makefile.plugin_meinhardt clean
 
	make -f Makefile.plugin_test clean
 

	
 
#finis
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) {
 
void AuxinGrowthPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
	// Auxin distributes between parent and daughter according to area
 
	double area1 = daughter1.Area(), area2 = daughter2.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]);
 
	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.);
 
		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) { 
 
void AuxinGrowthPlugin::SetCellColor(CellBase *c, QColor *color) { 
 

	
 
	// Red: PIN1
 
	// Green: Auxin
 
	if (c.CellType()==1) color = QColor("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);
 
	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) {
 
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->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);
 
		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);
 
   		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) {
 

	
 
	// 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;
 
			// dchem_c2 is undefined..!
 
			return;
 
		} else {
 
			return;
 
		}
 
	}
 
	
 
	
 
	if (w->C1()->BoundaryPolP()) {
 
		
 
		if (w->AuxinSource()) {
 
			double aux_flux = par->leaf_tip_source * w->Length();
 
			dchem_c2[0] += aux_flux;
 
			// dchem_c1 is undefined...!
 
			return;
 
		} else {
 
			
 
			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));
 
				
 
				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;
 
	
 
    // 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)) );
 
	
 
    // 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;
 
	
 
}
 

	
 
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[2] = 0.; dw2[2] = 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);
 
			
 
			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;
 
			
 
		} else {
 
			dw1[0]=dw2[0]=dw1[1]=dw2[1];//=dw1[2]=dw2[2];
 
			return;
 
		}
 
    }
 
    
 
    if (w->C1()->BoundaryPolP()) {
 
		if (w->AuxinSink())  {
 
			
 
			dw1[0] = 0.; dw2[0] = 0.;
 
			//dw1[2] = 0.; dw2[2] = 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);
 
			
 
			dw1[1] = 0.;
 
			return;
 
			
 
		}  else {
 
			dw1[0]=dw2[0]=dw1[1]=dw2[1];//=dw1[2]=dw2[2];
 
			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)
 
	
 
    double dPijdt1=0., dPijdt2=0.;
 
    
 
    // normal cell
 
    double  auxin2 = w->C2()->Chemical(0);
 
    double receptor_level1 = auxin2 * par->r / (par->kr + auxin2);
 
    
 
    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);
 
    
 
    // normal cell
 
    dPijdt2 = 
 
	
 
	// 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 */
 
    
 
    dw1[0] = 0.; dw2[0] = 0.;
 
    //dw1[2] = 0.; dw2[2] = 0.;
 
    
 
    dw1[1] = dPijdt1;
 
    dw2[1] = dPijdt2;
 
}
 

	
 
double AuxinGrowthPlugin::complex_PijAj(CellBase &here, CellBase &nb, Wall &w) { 
 
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 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));
 
	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<double>( far_3_arg_mem_fun( *this, &AuxinGrowthPlugin::complex_PijAj ) ) + par->k2 * sum_Pij;
 
	/*for ( list<Wall *>::const_iterator w = c->walls.begin();
 
		 w!=walls.end();
 
		 w++) {
 
		if ((*w)->C1() == c)
 
			dPidt +=  complex_PijAj( (*w)->C1(), (*w)->C2(), *w );
 
		else
 
			dPidt +=  complex_PijAj( (*w)->C2(), (*w)->C1(), *w );
 
	}*/
 
	
 
	// 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)
src/build_models/auxingrowthplugin.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 _AUXINGROWTHPLUGIN_H_
 
#define _AUXINGROWTHPLUGIN_H_
 

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

	
 

	
 
class AuxinGrowthPlugin : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void) { return QString( "Auxin accumulation and growth" ); }
 
	
 
	// Executed after the cellular mechanics steps have equillibrized
 
	virtual void CellHouseKeeping (CellBase &c);
 
	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 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);
 
	virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2);
 
	
 
	// to be executed for coloring a cell
 
	virtual void SetCellColor(CellBase &c, QColor &color);	
 
	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);
 
	double complex_PijAj(CellBase *here, CellBase *nb, Wall *w);
 
};
 

	
 
#endif
src/build_models/leafplugin.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 "leafplugin.h"
 

	
 
#include "far_mem_5.h"
 

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

	
 
bool batch = false;
 

	
 
// To be executed after cell division
 
void LeafPlugin::OnDivide(ParentInfo &parent_info, CellBase &daughter1, CellBase &daughter2) {
 
void LeafPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
		// PIN1 distributes between parent and daughter according to area
 
  double area = daughter1.Area(), daughter_area = daughter2.Area();
 
  double area = daughter1->Area(), daughter_area = daughter2->Area();
 
  double tot_area = area + daughter_area;
 
  
 
  //chem[1]*=(area/tot_area);
 
  //daughter.chem[1]*=(daughter_area/tot_area);
 
	
 
  // For lack of detailed data, or a better rule, we assume that cells remain polarized
 
  // after division
 
  
 
  // So the PIN1 is redistributed according to the original polarization over the walls
 
  
 
  // parent_info contains info about the parent 
 
  // redistribute the PIN in the endosome according to area
 
  
 
	// "Fudge" rule: if one of the cells is at the boundary, remove all AUX1 in the other cell
 
  if (daughter1.AtBoundaryP() && !daughter2.AtBoundaryP()) {
 
    //daughter2.new_chem[2]=daughter2.chem[2]=0.;
 
		daughter2.SetNewChem(2,0);
 
		daughter2.SetChemical(2,0);
 
  if (daughter1->AtBoundaryP() && !daughter2->AtBoundaryP()) {
 
    //daughter2->new_chem[2]=daughter2->chem[2]=0.;
 
		daughter2->SetNewChem(2,0);
 
		daughter2->SetChemical(2,0);
 
		//daughter.new_chem[0]=daughter.chem[0]=0.;
 
		//cerr << "Clearing daughter\n";
 
		//for (list<Wall *>::const_iterator w=daughter.walls.begin();
 
		//	 w!=daughter.walls.end();
 
		//	 w++) {
 
			
 
		//	(*w)->setTransporter(&daughter, 1, 0.);
 
		
 
		//}
 
		//new_chem[2]=chem[2]=parent_info.PINendosome;
 
		daughter1.SetNewChem(2,parent_info.PINendosome);
 
		daughter1.SetChemical(2,parent_info.PINendosome);
 
		//new_chem[2]=chem[2]=parent_info->PINendosome;
 
		daughter1->SetNewChem(2,parent_info->PINendosome);
 
		daughter1->SetChemical(2,parent_info->PINendosome);
 
 
 
	} else {
 
		if (daughter2.AtBoundaryP() && !daughter1.AtBoundaryP()) {
 
		if (daughter2->AtBoundaryP() && !daughter1->AtBoundaryP()) {
 
		  
 
		  //new_chem[2]=chem[2]=0.;
 
		  daughter1.SetNewChem(2,0);
 
		  daughter1.SetChemical(2,0);
 
		  daughter1->SetNewChem(2,0);
 
		  daughter1->SetChemical(2,0);
 
		  
 
			/*new_chem[0]=chem[0]=0.;
 
			for (list<Wall *>::const_iterator w=walls.begin();
 
				 w!=walls.end();
 
				 w++) {
 
				
 
				(*w)->setTransporter(this, 1, 0.);
 
			}*/
 
		  //daughter2.chem[2]=parent_info.PINendosome;
 
		  daughter2.SetChemical(2,parent_info.PINendosome);
 
		  //daughter2->chem[2]=parent_info->PINendosome;
 
		  daughter2->SetChemical(2,parent_info->PINendosome);
 
		  //cerr << "Clearing parent\n";
 
		  
 
		} else {
 
		  //daughter1.new_chem[2]=daughter1.chem[2] = parent_info.PINendosome*(area/tot_area);
 
		  daughter1.SetNewChem(2,parent_info.PINendosome*(area/tot_area));
 
		  daughter1.SetChemical(2, parent_info.PINendosome*(area/tot_area));
 
		  //daughter2.new_chem[2]=daughter2.chem[2] = parent_info.PINendosome*(daughter_area/tot_area);
 
		  daughter2.SetNewChem(2,parent_info.PINendosome*(daughter_area/tot_area));
 
		  daughter2.SetChemical(2,parent_info.PINendosome*(daughter_area/tot_area));
 
		  //daughter1->new_chem[2]=daughter1->chem[2] = parent_info->PINendosome*(area/tot_area);
 
		  daughter1->SetNewChem(2,parent_info->PINendosome*(area/tot_area));
 
		  daughter1->SetChemical(2, parent_info->PINendosome*(area/tot_area));
 
		  //daughter2->new_chem[2]=daughter2->chem[2] = parent_info->PINendosome*(daughter_area/tot_area);
 
		  daughter2->SetNewChem(2,parent_info->PINendosome*(daughter_area/tot_area));
 
		  daughter2->SetChemical(2,parent_info->PINendosome*(daughter_area/tot_area));
 
		  
 
		}
 
	}
 
	
 
	/*
 
	  // NB: Code commented out; not yet adapted to plugin format... RM 18/12/2009
 
	// Now redistribute the membrane PINs according to the original polarization in the parent
 
	// mmm... I'd like to have a better, biologically motivated rule for this, 
 
	// but for lack of something better... I hope I'm excused :-). Let's say the overall
 
	// organization of the actin fibres is not completely destroyed after division...
 
	
 
	// distribute wallPINs according to the circumference of the parent and daughter
 
	double circ = Circumference( );
 
	double daughter_circ = daughter.Circumference();
 
	double tot_circ = circ + daughter_circ;
 
	
 
	double wallPINs = (circ / tot_circ) * parent_info.PINmembrane;
 
	double daughter_wallPINs = (daughter_circ / tot_circ) * parent_info.PINmembrane;
 
	double wallPINs = (circ / tot_circ) * parent_info->PINmembrane;
 
	double daughter_wallPINs = (daughter_circ / tot_circ) * parent_info->PINmembrane;
 
	
 
     	//cerr << "wallPINs = " << wallPINs <<  ", daughter_wallPINs =  " << daughter_wallPINs << "sum = " << wallPINs + daughter_wallPINs << ", PINmembrane = " << parent_info.PINmembrane << endl;
 
     	//cerr << "wallPINs = " << wallPINs <<  ", daughter_wallPINs =  " << daughter_wallPINs << "sum = " << wallPINs + daughter_wallPINs << ", PINmembrane = " << parent_info->PINmembrane << endl;
 
	// distrubute it according to the overall polarity
 
	Vector polarization = parent_info.polarization.Normalised().Perp2D();
 
	Vector polarization = parent_info->polarization.Normalised().Perp2D();
 
	
 
	double sum=0.;
 
	for (list<Wall *>::const_iterator w=walls.begin();
 
		 w!=walls.end();
 
		 w++) {
 
		
 
		// distribute according to angle (0 degrees: maximum, 180 degrees minimum)
 
		double tmp=InnerProduct((*w)->getWallVector(this),polarization); // move domain from [-1,1] to [0,1]
 
		
 
		cerr << "[" << tmp << "]";
 
		sum+=tmp;
 
		//(*w)->setTransporter(this, 1, 
 
	}
 
	
 
	//cerr << "Sum is " << sum << endl;
 
	//double sum_wall_Pi = SumTransporters(1);
 
	
 
	// After division, cells produce PIN1 (in intracellular storage) until total amount becomes Pi_tot
 
	//SetChemical(1, par.Pi_tot - sum_wall_Pi  );
 
	//SetNewChem(1, Chemical(1));
 
	
 
	//cerr << "[ "  << sum_wall_Pi + Chemical(1) << "]";
 
	*/
 
}
 

	
 
void LeafPlugin::SetCellColor(CellBase &c, QColor &color) { 
 
void LeafPlugin::SetCellColor(CellBase *c, QColor *color) { 
 

	
 
	// Red: AUX1
 
	// Green: Auxin
 
	// Blue: van-3
 
  //  color.setRgb(chem[2]/(1+chem[2]) * 255.,(chem[0]/(1+chem[0]) * 255.),(chem[3]/(1+chem[3]) *255.) );
 
  color.setRgb(c.Chemical(2)/(1+c.Chemical(2)) * 255.,(c.Chemical(0)/(1+c.Chemical(0)) * 255.),(c.Chemical(3)/(1+c.Chemical(3)) *255.) );
 
  //  color->setRgb(chem[2]/(1+chem[2]) * 255.,(chem[0]/(1+chem[0]) * 255.),(chem[3]/(1+chem[3]) *255.) );
 
  color->setRgb(c->Chemical(2)/(1+c->Chemical(2)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.),(c->Chemical(3)/(1+c->Chemical(3)) *255.) );
 
  
 

	
 
}
 

	
 

	
 

	
 
void LeafPlugin::CellHouseKeeping(CellBase &c) {
 
void LeafPlugin::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->Boundary()==CellBase::None) {
 
    if (c->Area() > par->rel_cell_div_threshold * c->BaseArea() ) {
 
      //c->SetChemical(0,0);
 
      c->Divide();
 
    }		
 
    
 
    // expand if this is not a provascular cell
 
    if (c.Chemical(3) < 0.7 ) {
 
      c.EnlargeTargetArea(par->cell_expansion_rate);
 
    if (c->Chemical(3) < 0.7 ) {
 
      c->EnlargeTargetArea(par->cell_expansion_rate);
 
    } 
 
  }  
 
  
 
}
 

	
 
void LeafPlugin::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;
 
      
 
      // dchem_c2 is undefined..!
 
      return;
 
    } else {
 
      if (w->AuxinSink()) {
 
	
 
	// efflux into Shoot Apical meristem
 
	// we assume all PINs are directed towards shoot apical meristem
 
	dchem_c1[0] -= par->sam_efflux * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0));
 
	
 
	return;
 
      } else {
 
	
 
	// Active fluxes (PIN1 and AUX1 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)) 
 
			   + par->aux1transport * w->C2()->Chemical(2) * w->C1()->Chemical(0) / (par->kaux1 + 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)) 
 
			   + par->aux1transport * w->C1()->Chemical(2) * w->C2()->Chemical(0) / (par->kaux1 + w->C2()->Chemical(0)) );
 
	
 
	dchem_c1[0] += trans21 - trans12;
 
	dchem_c2[0] += trans12 - trans21;
 
	return;
 
      }
 
      
 
    }
 
  }
 
  
 
  
 
  if (w->C1()->BoundaryPolP()) {
 
		  
 
    if (w->AuxinSource()) {
 
      double aux_flux = par->leaf_tip_source * w->Length();
 
      dchem_c2[0] += aux_flux;
 
      // dchem_c1 is undefined...!
 
      return;
 
    } else {
 
			  
 
      if (w->AuxinSink()) {
 
				  
 
				  
 
	// efflux into Shoot Apical meristem
 
	// we assume all PINs are directed towards shoot apical meristem
 
				  
 
	// no passive fluxes: outside is impermeable
 
				  
 
	// Active fluxes (PIN1 and AUX1 mediated transport)
 
				  
 
	// (Transporters measured in moles, here)
 
	// efflux from cell 1 to cell 2
 
	// assumption: no AUX1 in shoot apical meristem
 
	double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)));
 
	dchem_c1[0] +=  - trans12;
 
				  
 
	return;
 
				  
 
	//dchem_c2[0] -= par->sam_efflux * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0));
 
				  
 
	// return;
 
      }  else {
 

	
 
      }
 
    }
 
  }
 
	  
 
	  
 
  // Passive fluxes (Fick's law)
 
  // only auxin flux now
 
  // flux depends on edge length and concentration difference
 
  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;
 
  }
 
  // Active fluxes (PIN1 and AUX1 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)) 
 
		     + par->aux1transport * w->C2()->Chemical(2) * w->C1()->Chemical(0) / (par->kaux1 + 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)) 
 
		     + par->aux1transport * w->C1()->Chemical(2) * w->C2()->Chemical(0) / (par->kaux1 + w->C2()->Chemical(0)) );
 
	  
 
  dchem_c1[0] += trans21 - trans12;
 
  dchem_c2[0] += trans12 - trans21;
 
	  
 
   
 

	
 
}
 
void LeafPlugin::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[2] = 0.; dw2[2] = 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);
 
	
 
      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;
 
     
 
    } else {
 
      dw1[0]=dw2[0]=dw1[1]=dw2[1]=dw1[2]=dw2[2];
 
      return;
 
    }
 
  }
 
    
 
  if (w->C1()->BoundaryPolP()) {
 
    if (w->AuxinSink())  {
 
      
 
      dw1[0] = 0.; dw2[0] = 0.;
 
      dw1[2] = 0.; dw2[2] = 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);
 
	
 
      dw1[1] = 0.;
 
      return;
 
      
 
    }  else {
 
      dw1[0]=dw2[0]=dw1[1]=dw2[1]=dw1[2]=dw2[2];
 
      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)
 

	
 
  double dPijdt1=0., dPijdt2=0.;
 
    
 
  // normal cell
 
  double  auxin2 = w->C2()->Chemical(0);
 
  double receptor_level1 = auxin2 * par->r / (par->kr + auxin2);
 
    
 
  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);
 
    
 
  // normal cell
 
  dPijdt2 = 
 
       
 
    // 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 */
 
    
 
  dw1[0] = 0.; dw2[0] = 0.;
 
  dw1[2] = 0.; dw2[2] = 0.;
 
    
 
  dw1[1] = dPijdt1;
 
  dw2[1] = dPijdt2;
 
  
 
}
 

	
 
double LeafPlugin::complex_PijAj(CellBase &here, CellBase &nb, Wall &w) { 
 
double LeafPlugin::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 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));
 
  return here->Chemical(1) * receptor_level / ( par->km + here->Chemical(1));
 
  
 
}
 

	
 

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

	
 
  double dPidt = 0.;
 
    
 
  double sum_Pij = c->SumTransporters( 1 );
 

	
 
  // exocytosis regulated: 
 
  // van3 expression reduces rate of PIN1 endocytosis 
 
  dPidt = -par->k1 * c->ReduceCellAndWalls<double>( far_3_arg_mem_fun( *this, &LeafPlugin::complex_PijAj ) ) + 
 
    (c->Chemical(3) < 0.5 ? par->k2 : par->k2van3) * 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;
 
    
 
  /*if (c->AtBoundaryP()) {
 
    dchem[2] = 0.01;
 
    //cerr << "Making cell blue.\n";
 
    } else {
 
    dchem[2] = -0.1 * c->Chemical(2);
 
    }*/
 

	
 
  // no PIN production in SAM
 
  if (c->Boundary() == CellBase::SAM) {
 
    dchem[1]=0.;
 
    dchem[0]= - par->sam_auxin_breakdown * c->Chemical(0);
 
    dchem[2]=0.;
 
  } else {
 
      
 
    dchem[1] = dPidt;
 
      
 
      
 
    // source of auxin
 
    dchem[0] = par->aux_cons;
 
	  
 
    // auxin-induced AUX1 production, in the epidermis
 
    dchem[2] = ( c->AtBoundaryP() ? par->aux1prod : par->aux1prodmeso ) * ( c->Chemical(0)  / ( 1. + par->kap * c->Chemical(0) ) ) - ( par->aux1decay ) * c->Chemical(2) ;//: 0.;
 
  
 
    // auxin-induced production of VAN-3? Autokatalysis?
 
    //dchem[3] = par->van3prod * (c->Chemical(0) / (1. + par->kvp * c-> Chemical(0) ) )
 
    double A = c->Chemical(0);
 
    double van3 = c->Chemical(3);
 
    dchem[3] = par->van3prod * A - par->van3autokat * van3 + van3*van3/(1 + par->van3sat * van3*van3 ); 
 
  }
 
}
 

	
 

	
 

	
 

	
 

	
 

	
 
Q_EXPORT_PLUGIN2(leafplugin, LeafPlugin)
src/build_models/leafplugin.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 _LEAFPLUGIN_H_
 
#define _LEAFPLUGIN_H_
 

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

	
 

	
 
class LeafPlugin : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void) { return QString( "Traveling wave model with influx carriers - Merks and Beemster, 2006-2008" ); }
 
	
 
	// Executed after the cellular mechanics steps have equillibrized
 
	virtual void CellHouseKeeping (CellBase &c);
 
	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 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);
 
	virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2);
 
	
 
	// to be executed for coloring a cell
 
	virtual void SetCellColor(CellBase &c, QColor &color);	
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void) { return 4; }
 

	
 
 private:
 
	double complex_PijAj(CellBase &here, CellBase &nb, Wall &w);
 
	double complex_PijAj(CellBase *here, CellBase *nb, Wall *w);
 
	
 
};
 

	
 
#endif
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 "../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) {
 
void MeinhardtPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
	
 
}
 

	
 
void MeinhardtPlugin::SetCellColor(CellBase &c, QColor &color) { 
 
void MeinhardtPlugin::SetCellColor(CellBase *c, QColor *color) { 
 

	
 
	if (fpclassify(c.Chemical(0))==FP_NAN) {
 
	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");
 
		color->setNamedColor("red");
 
	} else {
 
		double range_min = 0.;//, range_max = 1.;
 
		if (c.Chemical(0)<range_min) {
 
		if (c->Chemical(0)<range_min) {
 
			MyWarning::warning("Whoops! Numerical instability!!");
 
			color.setNamedColor("blue");
 
			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.) );
 
			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) {
 
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()<par->constituous_expansion_limit) {
 
		c.EnlargeTargetArea(par->cell_expansion_rate );
 
	if (!par->constituous_expansion_limit || c->NCells()<par->constituous_expansion_limit) {
 
		c->EnlargeTargetArea(par->cell_expansion_rate );
 
	} else {
 
		if (c.Chemical(0)<0.5) {
 
		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); 
 
			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);
 
			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) {
 
	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/meinhardtplugin.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 _MEINHARDTPLUGIN_H_
 
#define _MEINHARDTPLUGIN_H_
 

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

	
 

	
 
class MeinhardtPlugin : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void) { return QString( "Meinhardt 1976, with growth" ); }
 
	
 
	// Executed after the cellular mechanics steps have equillibrized
 
	virtual void CellHouseKeeping (CellBase &c);
 
	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 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);
 
	virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2);
 
	
 
	// to be executed for coloring a cell
 
	virtual void SetCellColor(CellBase &c, QColor &color);	
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void) { return 4; }
 
};
 

	
 
#endif
src/build_models/plugin_auxingrowth.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = auxingrowth
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
# finis
src/build_models/plugin_leaf.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = leaf
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
# finis
src/build_models/plugin_meinhardt.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = meinhardt
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
# finis
 

	
src/build_models/plugin_test.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = test
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 LIBS += -Llib -lvleaf
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finis
src/build_models/simplugin.h
Show inline comments
 
deleted file
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) {
 
void TestPlugin::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) {
 
	
 
}
 

	
 
void TestPlugin::SetCellColor(CellBase &c, QColor &color) { 
 
void TestPlugin::SetCellColor(CellBase *c, QColor *color) { 
 

	
 
	static QStringList colors;
 
	if (colors.size()==0) {
 
		colors << "red" << "green" << "blue";
 
	}
 
	color = colors[c.Index()%colors.size()];
 
	color->setNamedColor(colors[c->Index()%colors.size()]);
 
}
 

	
 

	
 

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

	
 

	
 
Q_EXPORT_PLUGIN2(testplugin, TestPlugin)
src/build_models/testplugin.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.
 
 *
 
 */
 

	
 

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

	
 

	
 
class TestPlugin : public QObject, SimPluginInterface {
 
	Q_OBJECT
 
	Q_INTERFACES(SimPluginInterface);
 

	
 
public:
 
	virtual QString ModelID(void) { return QString( "Test model" ); }
 
	
 
	// Executed after the cellular mechanics steps have equillibrized
 
	virtual void CellHouseKeeping (CellBase &c);
 
	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 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);
 
	virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2);
 
	
 
	// to be executed for coloring a cell
 
	virtual void SetCellColor(CellBase &c, QColor &color);	
 
	virtual void SetCellColor(CellBase *c, QColor *color);	
 
	// return number of chemicals
 
	virtual int NChem(void) { return 0; }
 
};
 

	
 

	
 

	
 

	
src/build_models/translate_plugin.pl
Show inline comments
 
new file 100755
 
#!/usr/bin/perl
 

	
 
$cfilename = shift(@ARGV) || die "Usage: translate_plugin.pl [cfile] [hfile] [profile]\n";
 
$hfilename = shift(@ARGV) || die "Usage: translate_plugin.pl [cfile] [hfile] [profile]\n";
 
$pfilename = shift(@ARGV) || die "Usage: translate_plugin.pl [cfile] [hfile] [profile]\n";
 

	
 
$ocfname = $cfilename; $ocfname =~ s/\.cpp/_tl.cpp/g;
 
$ohfname = $hfilename; $ohfname =~ s/\.h/_tl.h/g;
 
$opfname = $pfilename; $opfname =~ s/\.pro/_tl.pro/g;
 

	
 
print STDERR "Translating '$cfilename' to '$ocfname', '$hfilename' to '$ohfname', and '$pfilename' to '$opfname'\n";
 

	
 
open cfile,"<$cfilename";
 
open ocfile,">$ocfname";
 

	
 
while (<cfile>) {
 
	
 
	#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;
 
	}
 
	
 
	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 (<hfile>) {
 
	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 (<pfile>) {
 
	
 
	s/\bplugin\b\.h/plugin_tl\.h/g;
 
	s/\bplugin\b\.cpp/plugin_tl\.cpp/g;
 
	
 
	print opfile;
 
	
 
}
 
\ No newline at end of file
src/cell.cpp
Show inline comments
 
@@ -905,385 +905,385 @@ void Cell::DivideWalls(ItList new_node_l
 
			
 
			
 
			i++;
 
			if (i==nodes.end())
 
				i=nodes.begin();
 
		};
 
	}
 
	
 
	// new node list of parent
 
	list<Node *> new_nodes_parent;
 
	
 
	// half of the nodes stay with the parent
 
	{
 
		list<Node *>::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<Node *>::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<Node *>::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 { // if fix_cellwall is true, that is if we are cutting off
 
			// part of a leaf to make a nice initial condition, we also want to make it part of the boundary
 
			//node->boundary = true;
 
			node->fixed = true;
 
			//node->sam = 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<CellBase *> 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 <Wall *> copy_walls = walls;
 
	for (list<Wall *>::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]);
 
		}
 
	}
 
	
 
	//neighbors.push_back( daughter );
 
	//daughter->neighbors.push_back( this );
 
	
 
	
 
	//cerr << "Cell " << index << " has been dividing, and gave birth to Cell " << daughter->index << endl;
 
	
 
	// now reconstruct neighbor list for all "broken" neighbors
 
	
 
	for (list<CellBase *>::iterator i=broken_neighbors.begin();
 
		 i!=broken_neighbors.end();i++) {
 
		((Cell *)(*i))->ConstructNeighborList();
 
	}
 
	
 
	
 
	ConstructNeighborList();
 
	daughter->ConstructNeighborList();
 
	
 
	m->plugin->OnDivide(parent_info,*daughter, *this);
 
	m->plugin->OnDivide(&parent_info, daughter, this);
 
	// wall->OnWallInsert();
 
	//daughter->OnDivide();
 
	
 
	daughter->div_counter=(++div_counter);
 
	
 
	
 
}
 

	
 
// Move the whole cell
 
void Cell::Move(const Vector T) {
 
	
 
    for (list<Node *>::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<Node *, Node *> > length_edges;
 
	vector<double> 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<Node *>::const_iterator i=nodes.begin();
 
		 i!=nodes.end();
 
		 i++) {
 
		
 
		//if ((*i)->Fixed()) return; // commented out 01/12/05
 
		for (list<Neighbor>::const_iterator n=(*i)->owners.begin();
 
			 n!=(*i)->owners.end();
 
			 n++) {
 
			
 
			if (n->getCell()!=this) {
 
				//if (!(m->getNode(n->nb1).Fixed() && m->getNode(n->nb2).Fixed())) {
 
				length_edges.push_back( pair <Node *,Node *> (*i, n->nb1) );
 
				length_edges.push_back( pair <Node *,Node *> (*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<CellBase *>::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<CellBase *>::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()<exp(-dh/par.T)) {
 
		
 
		// update areas of cells
 
		//cerr << "neighbors: ";
 
		list<CellBase *>::const_iterator nb_it = neighbors.begin();
 
		for (vector<double>::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;
 
		
 
		/*vector<double> area1;
 
		 vector<double> area2;
 
		 m->ExtractFromCells( mem_fun_ref(&Cell::Area), back_inserter(area1) );
 
		 m->ExtractFromCells( mem_fun_ref(&Cell::CalcArea), back_inserter(area2));
 
		 vector<double>::iterator i=area1.begin();
 
		 vector<double>::iterator j=area2.begin();
 
		 int c=0;
 
		 for (;
 
		 i!=area1.end();
 
		 (i++, j++)) {
 
		 if ( (*i-*j) > 1e-10) {
 
		 cerr << c++ << " " << *i << " " << *j << endl;
 
		 abort();
 
		 }
 
		 }*/
 
		
 
	} 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);
 
}
 

	
 
// Get energy level of whole cell (excluding length constraint?)
 
double Cell::Energy(void) const {
 
	
 
	double energy = 0.;
 
	double length_contribution = 0.;
 
	
 
	for (list<Node *>::const_iterator i=nodes.begin();
 
		 i!=nodes.end();
 
		 i++) {
 
		
 
		for (list<Neighbor>::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;
 
@@ -1472,385 +1472,385 @@ bool Cell::IntersectsWithLineP(const Vec
 
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<Node *> corner_points;
 
	
 
	for (list<Node *>::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<Node *>::const_iterator nb = (--corner_points.end());
 
	
 
	// loop over list, 
 
	for (list<Node *>::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<Cell *> owning_cells;
 
		Node &n(*(*i));
 
		
 
		for (list<Neighbor>::const_iterator j=n.owners.begin();
 
			 j!=n.owners.end();
 
			 j++) {
 
			owning_cells.push_back(j->cell);
 
		}
 
		
 
		Node &n2(*(*nb));
 
		for (list<Neighbor>::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<Cell *> duplicates;
 
		list<Cell *>::const_iterator prevj = (--owning_cells.end());
 
		for (list<Cell *>::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<Cell *>::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) {
 
			//walls. new Wall(*nb,*i,duplicates[0],duplicates[1]) );
 
			AddWall(  new Wall(*nb,*i,duplicates[0],duplicates[1]) );
 
			if (!duplicates[1]->BoundaryPolP()) {
 
				
 
				neighbors.push_back(duplicates[1]);
 
			}
 
		} else {
 
			//walls.push_back( new Wall(*nb,*i,duplicates[1],duplicates[0]) ); 
 
			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<Node *>::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<NChem();c++) flux[c]=0.;
 
	
 
	for (list<Wall *>::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;c<NChem();c++) {
 
			double phi = (*i)->length * ( D[c] ) * ( ((Cell *)(*i)->c2)->chem[c] - chem[c] );
 
			
 
			if ((*i)->c1!=this) {
 
				cerr << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl;
 
			}
 
			
 
			flux[c] += phi;
 
		}    
 
	}
 
	
 
}
 

	
 

	
 
// graphics stuff, not compiled for batch versions
 
#ifdef QTGRAPHICS
 

	
 
#include "canvas.h"
 

	
 
void Cell::Draw(QGraphicsScene *c, QString tooltip) {
 
	
 
	// Draw the cell on a QCanvas object
 
	
 
	if (DeadP()) { 
 
		cerr << "Cell " << index << " not drawn, because dead.\n";
 
		return;
 
	}
 
	
 
	CellItem* p = new CellItem(this, c);
 
	
 
	QPolygonF pa(nodes.size());
 
	int cc=0;
 
	
 
	for (list<Node *>::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);
 
	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::DrawCenter(QGraphicsScene *c) const {
 
  // Maginfication derived similarly to that in nodeitem.cpp
 
  // Why not use Cell::Magnification()?
 
  const double mag = par.node_mag;
 
	
 
	// 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);
 
}
 

	
 
void Cell::DrawNodes(QGraphicsScene *c) const {
 
	
 
	for (list<Node *>::const_iterator n=nodes.begin();
 
		 n!=nodes.end();
 
		 n++) {
 
		Node *i=*n;
 
		
 
		//QCanvasEllipse *item = new QCanvasEllipse( 10, 10, c);
 
		NodeItem *item = new NodeItem ( &(*i), c );
 
		//QGraphicsRectItem *item = new QGraphicsRectItem(-50, -50, 50, 50, 0, c);
 
		//disk->setBrush( QColor("IndianRed") );
 
		
 
		/*if (i->sam) {
 
		 item->setBrush( purple );
 
		 } else {
 
		 if (i->boundary) {
 
		 item->setBrush( deep_sky_blue );
 
		 } 
 
		 else {
 
		 item->setBrush( indian_red );
 
		 }
 
		 }*/
 
		item->setColor();
 
		
 
		/*(if (item->getNode().DeadP()) {
 
		 item->setBrush( QBrush (Qt::Dense6Pattern) );
 
		 }*/
 
		item->setZValue(5);
 
		item->show();
 
		item ->setPos(((offset[0]+i->x)*factor),
 
					  ((offset[1]+i->y)*factor) );
 
	}
 
	
 
}
 

	
 
void Cell::DrawIndex(QGraphicsScene *c) const {
 
	
 
	//  stringstream text;
 
	//     text << index;
 
	//     Vector centroid = Centroid();
 
	//     QCanvasText *number = new QCanvasText ( QString (text.str()), c );
 
	//     number->setColor( QColor(par.textcolor) );
 
	//     number->setZ(20);
 
	//     number->setFont( QFont( "Helvetica", par.cellnumsize, QFont::Bold) );
 
	//     number->show();
 
	//     number -> move((int)((offset[0]+centroid.x)*factor),
 
	// 		   (int)((offset[1]+centroid.y)*factor) );
 
	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->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 {
 
	
 
	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();
 
 }
 
 
 
 }*/
 

	
 

	
 

	
 
void Cell::DrawFluxes(QGraphicsScene *c, double arrowsize)  {
 
	
 
	// get the mean flux through this cell
 
	//Vector vec_flux = ReduceWalls( mem_fun_ref( &Wall::VizFlux ), Vector() );
 
	Vector vec_flux = ReduceCellAndWalls<Vector>( 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.;
src/cellbase.h
Show inline comments
 
@@ -142,356 +142,356 @@ class CellBase :  public QObject, public
 

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

	
 
    boundary_type SetBoundary(boundary_type bound) {
 
      if (bound!=None) {
 
	//area=0.;
 
	//length=0.;
 
      }
 
      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();
 
    }
 
    
 
    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 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;
 
    }
 

	
 
    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;
 
	}
 
	
 
	//Vector Strain(void) const;
 

	
 
    inline double Circumference(void) const {
 
      double sum=0.;
 
      for (list<Wall *>::const_iterator w=walls.begin();
 
	   w!=walls.end();
 
	   w++) {
 
	sum +=  (*w)->Length();
 
      }
 
      
 
      return sum;
 
    }
 

	
 
	QList<WallBase *> getWalls(void) {
 
		QList<WallBase *> wall_list;
 
		for (list<Wall *>::iterator i=walls.begin();
 
			 i!=walls.end();
 
			 i++) {
 
			wall_list << *i;
 
		}
 
		return wall_list;
 
	}
 
  //  void XFigPrint(std::ostream &os) const;
 
    
 
    void Dump(ostream &os) const;
 
   	
 
	QString printednodelist(void);
 
 
 
   // void OnDivide(ParentInfo &parent_info, CellBase &daughter);
 

	
 
    
 
    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<Wall *>::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<class P, class Op> P ReduceNeighbors(Op f) {
 
      P sum=0;
 
      for (list<Wall *>::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<class P, class Op> P ReduceWalls(Op f, P sum) {
 
      for (list<Wall *>::const_iterator w=walls.begin();
 
	   w!=walls.end();
 
	   w++) {
 
	sum += f( **w ); 
 
      }
 
      return sum;
 
    }
 
	
 
	
 
    
 
    
 
    //! The same, but now for the walls AND neighbors
 
    template<class P, class Op> P ReduceCellAndWalls(Op f) {
 
      P sum = 0;
 
      for (list<Wall *>::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 );
 
	sum += ((*w)->c1 == this) ? 
 
	  f( ((*w)->c1), ((*w)->c2), *w ) :  
 
	  f( ((*w)->c2), ((*w)->c1), *w );
 
      }
 
      return sum;
 
    }
 
    
 
	/* template<class Op> void LoopWalls(Op f) {
 
		for (list<Wall *>::const_iterator w=walls.begin();
 
			 w!=walls.end();
 
			 w++) {
 
			( **w)->f;
 
		}
 
	}*/
 
	
 
    //! Sum transporters at this CellBase's side of the walls
 
    double SumTransporters(int ch) {
 
      double sum=0.;
 
      for (list<Wall *>::const_iterator w=walls.begin();
 
	   w!=walls.end();
 
	   w++) {
 
	sum += (*w)->getTransporter(this, ch);
 
      
 
      }
 
      
 
      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<Wall *>::const_iterator w=walls.begin();
 
	   w!=walls.end();
 
	   w++) {
 
	sum += (*w)->getTransporter(this, ch) * (*w)->Length();
 
      
 
      }
 
      
 
      return sum;
 
    }
 
    
 
	
 
    
 
    double SumLengthTransportersChemical(int trch, int ch) {
 
      double sum=0.;
 
      for (list<Wall *>::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 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; } 
 

	
 
	static inline CellsStaticDatamembers *GetStaticDataMemberPointer(void) { return static_data_members; }
 
	
 
protected:
 
	// (define a list of Node* iterators)
 
	typedef list < list<Node *>::iterator > ItList;
 

	
 
    int index;
 

	
 
	inline void SetChemToNewchem(void) {
 
		for (int c=0;c<CellBase::NChem();c++) {
 
			chem[c]=new_chem[c];
 
		}
 
    }
 
    inline void SetNewChemToChem(void) {
 
		for (int c=0;c<CellBase::NChem();c++) {
 
			new_chem[c]=chem[c];
 
		}
 
    }
 
	inline double NewChem(int c) const { return new_chem[c]; }
 
	
 
 protected:
 
    list<Node *> 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<CellBase *> neighbors;
 

	
 
    list<Wall *> walls;
 
  
 
    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) {
 
	return w.getTransporter( &here, 1)  *  w.getInfluxVector(&here);
 
inline Vector PINdir(CellBase *here, CellBase *nb, Wall *w) {
 
	return w->getTransporter( here, 1)  *  w->getInfluxVector(here);
 
}
 

	
 

	
 
#endif
 

	
 

	
 

	
 

	
 

	
src/libplugin.pro
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.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += staticlib
 

	
 
QMAKE_CXXFLAGS += -fexceptions
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QMAKE_CXXFLAGS_DEBUG -= -finstrument-functions
 

	
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = build_models/lib 
 
DESTDIR = ../lib 
 
PERLDIR = ./perl
 
PARTMPL = VirtualLeafpar.tmpl
 
QT += qt3support
 
TARGET = vleaf
 
TEMPLATE = lib
 

	
 
HEADERS = \
 
 cellbase.h \
 
 matrix.h \
 
 output.h \
 
 parameter.h \
 
 parse.h \
 
 random.h \
 
 simplugin.h \
 
 UniqueMessage.h \
 
 vector.h \
 
 wallbase.h \
 
 warning.h
 

	
 
SOURCES = \
 
 cellbase.cpp \
 
 matrix.cpp \
 
 output.cpp \
 
 parameter.cpp \
 
 parse.cpp \
 
 random.cpp \
 
 simplugin.cpp \
 
 UniqueMessage.cpp \
 
 vector.cpp \
 
 wallbase.cpp \
 
 warning.cpp
 

	
 
unix {
 
 system(if `which perl > /dev/null 2>&1` ; then rm -f parameter.cpp parameter.h pardialog.cpp pardialog.h; fi)
 
 system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_parameter_source.pl $$PARTMPL; fi)
 
 system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_pardialog_source.pl $$PARTMPL; fi)
 
#system(if `which perl > /dev/null 2>&1` ; then perl $$PERLDIR/make_xmlwritecode.pl -h $$REACTIONS; fi)
 

	
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
 LIBS += -lxml2 -lz -lm 
 
}
 

	
 
win32 {
 
 system(WHERE /Q perl && IF errorlevel 0 (DEL parameter.cpp parameter.h pardialog.cpp pardialog.h)
 
 system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_parameter_source.pl $$PARTMPL)
 
 system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_pardialog_source.pl $$PARTMPL)
 
#system(WHERE /Q perl && IF errorlevel 0 (perl $$PERLDIR\make_xmlwritecode.pl -h $$REACTIONS)
 

	
 
 LIBXML2DIR = C:\libxml2
 
 LIBICONVDIR = C:\libiconv
 
 LIBZDIR = C:\libz
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
#
src/mesh.h
Show inline comments
 
@@ -49,385 +49,385 @@ 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<T,C>::c.begin(),queue<T,C>::c.end(),x)==queue<T,C>::c.end()) {
 
			queue<T,C>::c.push_back(x);
 
		}
 
	}
 
	void clear(void) {
 
		queue<T,C>::c.clear();
 
	}
 
};
 

	
 
//template<class P> P& deref_ptr<P>( P *obj) { return *obj; }
 
template<class P> 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);
 
		
 
		//boundary_polygon = new BoundaryPolygon();
 
		
 
		time = 0.;
 
		plugin = 0;
 
	};
 
	~Mesh(void) {
 
		delete boundary_polygon;
 
		/* if (plugin)
 
			delete plugin;*/
 
	};
 
	
 
	void Clean(void);
 
	//void Plane(int xwidth, int ywidth, int nx, int ny, bool randomP=false);
 
	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);
 
	
 
	/*  void GMVoutput(ostream &os, 
 
	 const char *codename=0, const char *codever=0,
 
	 const char *comments=0);*/
 
	//void RandPoints(int npoints);
 
	
 
	inline Cell &getCell(int i) {
 
		if ((unsigned)i<cells.size())
 
			return *cells[i];
 
		else {
 
			cerr << i << endl;
 
			cerr << "size is " << cells.size() << endl;
 
			abort();
 
			//	throw("Index out of range in Mesh::getCell");
 
		}
 
	}
 
	
 
	inline Node &getNode(int i) {
 
		//if (i >= nodes.size() || i < 0) {
 
		//  cerr << "Mesh::getNode: Warning. Index " << i << " out of range.\n";
 
		// }
 
		return *nodes[i];    
 
	}
 
	
 
	//double Diffusion(void);
 
	inline int size(void) {
 
		return cells.size();
 
	}
 
	inline int nnodes(void) {
 
		return nodes.size();
 
	}
 
	//void SortNBLists(void);
 
	
 
	/*template<class Op> void LoopCells(Op f) {
 
	 for (vector<Cell>::iterator i=cells.begin();
 
	 i!=cells.end();
 
	 i++) {
 
	 f(*i); 
 
	 }
 
	 }*/
 
	
 
	/*! \brief Calls function f for all Cells f.
 
	 
 
	 Using this template requires some fiddling with function adaptors bind2nd and mem_fun_ref.
 
	 
 
	 Example usage for calling a member function on each cell:
 
	 
 
	 mesh.LoopCells( bind2nd (mem_fun_ref( &Cell::DrawDiffEdges), &canvas ) );
 
	 
 
	 This calls Cell's member function DrawDiffEdges, taking one
 
	 argument canvas, on all Cell objects in the current Mesh.
 
	 
 
	 */
 
	template<class Op> void LoopCells(Op f) {
 
		for (vector <Cell *>::iterator i=cells.begin();
 
			 i!=cells.end();
 
			 i++) {
 
			f(**i);
 
		}
 
		//for_each(cells.begin(),cells.end(),f);
 
	}
 
	
 
	template<class Op> void LoopWalls(Op f) {
 
		for (list <Wall *>::iterator i=walls.begin();
 
			 i!=walls.end();
 
			 i++) {
 
			f(**i);
 
		}
 
	}
 
	
 
	// if the amount of cells might increase, during looping, use this template
 
	template<class Op> void LoopCurrentCells(Op f) {
 
		vector<Cell *> current_cells = cells;
 
		for (vector <Cell *>::iterator i=current_cells.begin();
 
			 i!=current_cells.end();
 
			 i++) {
 
			f(**i);
 
			
 
		}
 
		//for_each(cells.begin(),cells.end(),f);
 
	}
 
	
 
	template<class Op> void LoopNodes(Op f) {
 
		for (vector<Node *>::iterator i=nodes.begin();
 
			 i!=nodes.end();
 
			 i++) {
 
			f(**i); 
 
		}
 
	}
 
	
 
	template<class Op> void RandomlyLoopNodes(Op f) {
 
		
 
		MyUrand r(shuffled_nodes.size());
 
		random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r);
 
		
 
		for (vector<Node *>::const_iterator i=shuffled_nodes.begin();
 
			 i!=shuffled_nodes.end();
 
			 i++) {
 
			f(*shuffled_nodes[*i]);
 
		}
 
		
 
	}
 
	
 
	template<class Op> void RandomlyLoopCells(Op f) {
 
		
 
		MyUrand r(shuffled_cells.size());
 
		random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r);
 
		
 
		for (vector<Cell *>::const_iterator i=shuffled_cells.begin();
 
			 i!=shuffled_cells.end();
 
			 i++) {
 
			f(*shuffled_cells[*i]);
 
		}
 
		
 
		
 
	}
 
	
 
	template<class Op1, class Op2> void LoopCells(Op1 f, Op2 &g) {
 
		for (vector<Cell *>::iterator i=cells.begin();
 
			 i!=cells.end();
 
			 i++) {
 
			f(**i,g); 
 
		}
 
	}
 
	
 
	template<class Op1, class Op2, class Op3> void LoopCells(Op1 f, Op2 &g, Op3 &h) {
 
		for (vector<Cell *>::iterator i=cells.begin();
 
			 i!=cells.end();
 
			 i++) {
 
			f(**i,g,h); 
 
		}
 
	}
 
	
 
	void DoCellHouseKeeping(void) {
 
		vector<Cell *> current_cells = cells;
 
		for (vector<Cell *>::iterator i = current_cells.begin();
 
			 i != current_cells.end();
 
			 i ++) {
 
			plugin->CellHouseKeeping(**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;
 
			}
 
		}
 
	}
 
/*	template<class Op1, class Cont> void ExtractFromCells(Op1 f, Cont res) {
 
		for (vector<Cell>::iterator i=cells.begin();
 
			 i!=cells.end();
 
			 i++) {
 
			*(res++) = ( f(*i) );
 
		}
 
	}*/
 
	
 
	// 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<class Op> 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<Cell *>::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();
 
		}
 
		//copy (node_insertion_queue.begin(),node_insertion_queue.end(),ostream_iterator<Edge>(cerr, " "));
 
	}
 
	
 
	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(); 
 
	
 
	//  template<class ReactFunction> ReactDiffuse(const double D, ReactFunction& react) {
 
	void ReactDiffuse( double delta_t = 1 );
 
	//void Diffuse(const double D);
 
	double SumChemical(int ch);
 
	void SetChemical(int ch, double value) {
 
		for (vector<Cell *>::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;
 
	
 
#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<Wall *> *tmp_cells);
 
	void XMLReadWallsToCells(xmlNode *root, vector<Wall *> *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<double> &clean_chem, const vector<double> &clean_transporters);
 
	void RandomizeChemicals(const vector<double> &max_chem, const vector<double> &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<qreal> VertexAngles(void);
 
	QVector< QPair<qreal,int> > VertexAnglesValues(void);
 
	void SetSimPlugin(SimPluginInterface *new_plugin) {
 
		/* if (plugin) 
 
			delete plugin;*/
 
		plugin=new_plugin;
 
	}
 
	QString ModelID(void) { return plugin?plugin->ModelID():QString("undefined"); }
 
	void StandardInit(void);	
 

	
 
	Node* findNextBoundaryNode(Node*);
src/modelcatalogue.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 "modelcatalogue.h"
 
#include <QVariant>
 

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

	
 
void ModelCatalogue::LoadPlugins() {
 
	
 
	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";
 
#endif 
 
	pluginDir.setNameFilters(plugin_filters);
 

	
 
	if (!pluginDir.cd("models")) {
 
		MyWarning::error("Directory 'models' not found!");
 
	}
 
	
 
	
 
	//QVector<SimPluginInterface *> plugins;
 
	foreach (QString fileName, pluginDir.entryList(QDir::Files)){ 
 
		QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); 
 
		if (SimPluginInterface *plugin = 
 
			qobject_cast<SimPluginInterface *>(loader.instance())) {
 
			models.append(plugin); 
 
		} else {
 
			MyWarning::warning("Could not load plugin %s",fileName.toStdString().c_str());
 
			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") 
 
    pluginDir.cdUp(); 
 
  //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (pluginDir.dirName() =="MacOS"){ 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
  } 
 
  //plugin_filters << "*.dylib";
 
#endif
 
  plugin_filters << model;
 
  pluginDir.setNameFilters(plugin_filters);
 
	
 
  if (!pluginDir.cd("models")) {
 
    MyWarning::error("Directory 'models' not found!");
 
  }
 
	
 
	
 
  //QVector<SimPluginInterface *> plugins;
 
	
 
  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<SimPluginInterface *>(loader.instance())) {
 
      models.append(plugin); 
 
      //MyWarning::warning("Successfully loaded model %s",fileName.toStdString().c_str());
 
    } else {
 
      MyWarning::warning("Could not load plugin %s",fileName.toStdString().c_str());
 
    }
 
  }
 
}
 

	
 
void ModelCatalogue::InstallFirstModel() {
 
	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 *)) );
 
}	
 

	
 
void ModelCatalogue::InstallModel(QAction *modelaction) {
 
	QVariant data = modelaction->data();
 
	SimPluginInterface *model = data.value<SimPluginInterface *>();
 
	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);
 

	
 
  if (mainwin) {
 
    mainwin->RefreshInfoBar();
 
    mainwin->Init(0);
 
  }
 
  //	mesh->StandardInit();
 
	
 
}
src/simplugin.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 _SIMPLUGIN_H_
 
#define _SIMPLUGIN_H_
 

	
 
#include <QtPlugin>
 
#include <QMetaType>
 
#include "cellbase.h"
 
#include "wallbase.h"
 

	
 
class Parameter;
 

	
 
#include <QColor>
 
#include <QString>
 

	
 

	
 
class SimPluginInterface {
 

	
 
public:
 
	virtual QString ModelID(void) = 0; 
 
	
 
	virtual ~SimPluginInterface() { }
 

	
 
	// Executed after the cellular mechanics steps have equillibrized
 
	virtual void CellHouseKeeping(CellBase &c) = 0;
 
	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;
 

	
 
	// to be executed after a cell division
 
	virtual void OnDivide(ParentInfo &parent_info, CellBase &daughter1, CellBase &daughter2) = 0;
 
	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;
 
	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);
 

	
 
protected:
 
	class Parameter *par;
 
	
 
};
 

	
 
Q_DECLARE_INTERFACE(SimPluginInterface, 
 
                    "nl.cwi.VirtualLeaf.SimPluginInterface/1.1") 
 
                    "nl.cwi.VirtualLeaf.SimPluginInterface/1.2") 
 
Q_DECLARE_METATYPE(SimPluginInterface *)
 

	
 

	
 
#endif
 
\ No newline at end of file
0 comments (0 inline, 0 general)