diff --git a/src/cellbase.h b/src/cellbase.h
new file mode 100644
--- /dev/null
+++ b/src/cellbase.h
@@ -0,0 +1,473 @@
+/*
+ *
+ * $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 .
+ *
+ * Copyright 2010 Roeland Merks.
+ *
+ */
+
+// CellBase derives from Vector, where Vector is simply used as a Vertex
+
+#ifndef _CELLBASE_H_
+#define _CELLBASE_H_
+
+#include
+#include
+#include
+#include
+#include "vector.h"
+#include "parameter.h"
+#include "wall.h"
+#include "warning.h"
+
+extern Parameter par;
+using namespace std;
+
+class Mesh;
+class Node;
+class CellBase;
+class NodeSet;
+
+struct ParentInfo {
+
+ Vector polarization;
+ double PINmembrane;
+ double PINendosome;
+
+};
+
+// We need a little trick here, to make sure the plugin and the main application will see the same static datamembers
+// otherwise each have their own instantation.
+// My solution is as follow. I collect all original statics in a class. The main application instantiates it and
+// has a static pointer to it. After loading the plugin I set a static pointer to the same class
+class CellsStaticDatamembers {
+
+public:
+ CellsStaticDatamembers(void) {
+ ncells = 0;
+ nchem = 0;
+ base_area = 0.;
+ cerr << "Constructor of CellsStaticDatamembers\n";
+ }
+ ~CellsStaticDatamembers() {
+ cerr << "Oops! Desctructor of CellsStaticDatamembers called\n";
+ }
+ int ncells;
+ int nchem;
+ double base_area;
+
+
+};
+
+class CellBase : public QObject, public Vector
+{
+
+ Q_OBJECT
+
+
+ friend class Mesh;
+ friend class CellInfo;
+ friend class Node;
+ friend class WallBase;
+ friend class SimPluginInterface;
+
+ public:
+ CellBase(QObject *parent=0);
+ CellBase(double x,double y,double z=0); // constructor
+
+ virtual ~CellBase() {
+ delete[] chem;
+ delete[] new_chem;
+ //cerr << "CellBase " << index << " is dying. " << endl;
+ }
+
+ CellBase(const CellBase &src); // copy constructor
+ virtual bool BoundaryPolP(void) const { return false; }
+
+
+ // CellBase(const Vector &src); // not allowed (we cannot know to which mesh
+ /// the CellBase will belong...)
+ CellBase operator=(const CellBase &src); // assignment operator
+ CellBase operator=(const Vector &src);
+
+ void SetChemical(int chem, double conc);
+ inline void SetNewChem(int chem, double conc) {
+ new_chem[chem] = conc;
+ }
+ void SetSource(int chem, double conc) {
+ source=true;
+ source_chem = chem;
+ source_conc = conc;
+ }
+
+ void UnfixNodes(void);
+ void FixNodes(void);
+ void UnsetSource(void) {
+ source = false;
+ }
+
+ inline bool Source(void) { return source; }
+ enum boundary_type {None, Noflux, SourceSink, SAM};
+ static const char * boundary_type_names[4];
+
+ inline const char *BoundaryStr(void) { return boundary_type_names[boundary]; }
+
+ ostream &print(ostream &os) const;
+ inline double Chemical(int c) const { // returns the value of chemical c
+ return 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;
+ }
+ //Vector Strain(void) const;
+
+ inline double Circumference(void) const {
+ double sum=0.;
+ for (list::const_iterator w=walls.begin();
+ w!=walls.end();
+ w++) {
+ sum += (*w)->Length();
+ }
+
+ return sum;
+ }
+
+ QList getWalls(void) {
+ QList wall_list;
+ for (list::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::const_iterator w=walls.begin();
+ w!=walls.end();
+ w++) {
+ sum += (*w)->Length() * ( (*w)->c1!=this ? (*w)->c1->Chemical(chem) : (*w)->c2->Chemical(chem) );
+ }
+ return sum;
+ }
+
+ //! Generalization of the previous member function
+ template P ReduceNeighbors(Op f) {
+ P sum=0;
+ for (list::const_iterator w=walls.begin();
+ w!=walls.end();
+ w++) {
+ sum += (*w)->c1 != this ? f( *((*w)->c1) ) : f ( *((*w)->c2) );
+ }
+ return sum;
+ }
+
+ //! The same, but now for the walls
+ template P ReduceWalls(Op f, P sum) {
+ for (list::const_iterator w=walls.begin();
+ w!=walls.end();
+ w++) {
+ sum += f( **w );
+ }
+ return sum;
+ }
+
+
+
+
+ //! The same, but now for the walls AND neighbors
+ template P ReduceCellAndWalls(Op f) {
+ P sum = 0;
+ for (list::const_iterator w=walls.begin();
+ w!=walls.end();
+ w++) {
+ sum += (*w)->c1 == this ?
+ f( *((*w)->c1), *((*w)->c2), **w ) :
+ f( *((*w)->c2), *((*w)->c1), **w );
+ }
+ return sum;
+ }
+
+ /* template void LoopWalls(Op f) {
+ for (list::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::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::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::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::iterator > ItList;
+
+ int index;
+
+ inline void SetChemToNewchem(void) {
+ for (int c=0;c nodes;
+ void ConstructNeighborList(void);
+ long wall_list_index (Wall *elem) const;
+
+ // DATA MEMBERS
+
+ // list of nodes, in clockwise order
+
+ // a (non-ordered) list of neighboring cells (actually I think the
+ // introduction of ConstructWalls() has made these
+ // lists ordered (clockwise), but I am not yet 100% sure...).
+ list neighbors;
+
+ list walls;
+
+ 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;
+
+ 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);
+}
+
+
+#endif
+
+
+
+
+