diff --git a/arbor/cable_cell.cpp b/arbor/cable_cell.cpp
index dd831a11743225f78c866ddc1462b732a90ebb7e..7403dc1e7ab5f7e9aeb3dc066abf3bcc0d87b7be 100644
--- a/arbor/cable_cell.cpp
+++ b/arbor/cable_cell.cpp
@@ -57,6 +57,10 @@ segment* cable_cell::segment(index_type index) {
     assert_valid_segment(index);
     return segments_[index].get();
 }
+segment const* cable_cell::parent(index_type index) const {
+    assert_valid_segment(index);
+    return segments_[parents_[index]].get();
+}
 
 segment const* cable_cell::segment(index_type index) const {
     assert_valid_segment(index);
diff --git a/arbor/fvm_compartment.hpp b/arbor/fvm_compartment.hpp
index 0d626328764637a0ef36ba31190c08017d68aa49..4790f595e3f15d07fa192ccd870dda2a8ead0649 100644
--- a/arbor/fvm_compartment.hpp
+++ b/arbor/fvm_compartment.hpp
@@ -34,6 +34,16 @@ struct semi_compartment {
         return *this;
     }
 
+    static semi_compartment half_sphere(value_type r1) {
+        using namespace math;
+        return semi_compartment{
+            r1,
+            area_sphere(r1)/2,
+            volume_sphere(r1)/2,
+            {r1, r1}
+        };
+    }
+
     static semi_compartment frustrum(value_type l, value_type r1, value_type r2) {
         using namespace math;
         return semi_compartment{
@@ -111,15 +121,17 @@ public:
     // `lengths` must be a sequence of length at least one.
     // `radii` must be a sequence of length `size(lengths)+1`.
     template <typename Radii, typename Lengths>
-    div_compartment_sampler(size_type n, const Radii& radii, const Lengths& lengths) {
+    div_compartment_sampler(size_type n, const Radii& radii, const Lengths& lengths, bool with_soma = false) {
         // set up offset-to-subsegment lookup and interpolation
         using namespace util;
 
+        with_soma_ = with_soma;
         segs_ = make_partition(offsets_, lengths);
         compat::compiler_barrier_if_icc_leq(20160415u);
 
         nseg_ = size(segs_);
-        scale_ = segs_.bounds().second/n;
+        scale_ = with_soma_? (segs_.bounds().second - segs_.front().second)/(n-1): segs_.bounds().second/n;
+
         assign(radii_, radii);
         arb_assert(size(radii_)==size(offsets_));
     }
@@ -144,6 +156,8 @@ protected:
         size_type i;   // index
         value_type p;  // proportion [0,1] along sub-segment
 
+        sub_segment_index(): i(0), p(0) {}
+
         sub_segment_index(size_type i_, value_type p_): i(i_), p(p_) {}
         bool operator<(sub_segment_index x) const {
             return i<x.i || (i==x.i && p<x.p);
@@ -169,6 +183,7 @@ protected:
         return math::lerp(radii_[s.i], radii_[s.i+1], s.p);
     }
 
+    bool with_soma_ = false; //segment passed in includes the soma information in radii[0] and lengths[0]
     size_type nseg_ = 0;
     std::vector<value_type> offsets_;
     std::vector<value_type> radii_;
@@ -180,15 +195,33 @@ protected:
 class div_compartment_integrator: public div_compartment_sampler {
 public:
     template <typename Radii, typename Lengths>
-    div_compartment_integrator(size_type n, const Radii& radii, const Lengths& lengths):
-        div_compartment_sampler(n, radii, lengths) {}
+    div_compartment_integrator(size_type n, const Radii& radii, const Lengths& lengths, bool with_soma = false):
+        div_compartment_sampler(n, radii, lengths, with_soma) {}
 
     div_compartment operator()(size_type i) const {
         using namespace math;
-
-        auto sleft = locate(scale_*i);
-        auto scentre = locate(scale_*(i+0.5));
-        auto sright = locate(scale_*(i+1));
+        sub_segment_index sleft, scentre, sright;
+        // If segment includes the soma, divisions are specially calculated
+        if (with_soma_) {
+            auto soma_l = segs_.front().second;
+            if (i == 0) {
+                sleft   = locate(soma_l/2);
+                scentre = locate(soma_l);
+                sright  = locate(soma_l + scale_/4);
+            } else if (i == 1) {
+                sleft   = locate(soma_l + scale_/4);
+                scentre = locate(soma_l + scale_/2);
+                sright  = locate(soma_l + scale_);
+            } else {
+                sleft   = locate(soma_l + scale_ * (i-1));
+                scentre = locate(soma_l + scale_ * (i-0.5));
+                sright  = locate(soma_l + scale_ * i);
+            }
+        } else {
+            sleft   = locate(scale_ * i);
+            scentre = locate(scale_ * (i + 0.5));
+            sright  = locate(scale_ * (i + 1));
+        }
 
         return div_compartment(i, integrate(sleft, scentre), integrate(scentre, sright));
     }
@@ -199,6 +232,12 @@ protected:
 
         auto seg = segs_[a.i];
         auto l = (b.p-a.p)*(seg.second-seg.first);
+
+        // If segment includes the soma it will be at index 0
+        // The soma is represented as a sphere
+        if (with_soma_ && a.i==0) {
+            return semi_compartment::half_sphere(radii_.front());
+        }
         return semi_compartment::frustrum(l, radius_at(a), radius_at(b));
     }
 
@@ -206,6 +245,7 @@ protected:
         sub_segment_index x = std::min(b, sub_segment_index(a.i, 1));
 
         auto s = sub_segment_frustrum(a, x);
+
         while (a.i<b.i) {
             ++a.i;
             a.p = 0;
diff --git a/arbor/fvm_layout.cpp b/arbor/fvm_layout.cpp
index c350770a8b911b53bc2f2eebfd48b3f4936b2f55..dd4d5b51042516ff61153b06ccbe808ffaf4a07d 100644
--- a/arbor/fvm_layout.cpp
+++ b/arbor/fvm_layout.cpp
@@ -42,6 +42,11 @@ namespace {
         explicit compartment_model(const cable_cell& cell) {
             tree = arb::tree(cell.parents());
             auto counts = cell.compartment_counts();
+            for (unsigned i = 0; i < cell.segments().size(); i++) {
+                if (!cell.segment(i)->is_soma() && cell.parent(i)->is_soma()) {
+                    counts[i]++;
+                }
+            }
             parent_index = make_parent_index(tree, counts);
             segment_index = algorithms::make_index(counts);
         }
@@ -129,41 +134,55 @@ fvm_discretization fvm_discretize(const std::vector<cable_cell>& cells) {
     util::make_partition(D.cell_segment_bounds,
         transform_view(cells, [](const cable_cell& c) { return c.num_segments(); }));
 
-    std::vector<index_type> cell_comp_bounds;
-    auto cell_comp_part = make_partition(cell_comp_bounds,
-        transform_view(cells, [](const cable_cell& c) { return c.num_compartments(); }));
+    std::vector<index_type> cell_cv_bounds;
+    auto cell_cv_part = make_partition(cell_cv_bounds,
+        transform_view(cells, [](const cable_cell& c) {
+            unsigned ncv = 0;
+            for (unsigned i = 0; i < c.segments().size(); i++) {
+                ncv += c.segment(i)->num_compartments();
+                if (!c.segment(i)->is_soma() && c.parent(i)->is_soma()) {
+                    ncv++;
+                }
+            }
+            return ncv;
+        }));
 
     D.ncell = cells.size();
-    D.ncomp = cell_comp_part.bounds().second;
+    D.ncv = cell_cv_part.bounds().second;
 
-    D.face_conductance.assign(D.ncomp, 0.);
-    D.cv_area.assign(D.ncomp, 0.);
-    D.cv_capacitance.assign(D.ncomp, 0.);
-    D.parent_cv.assign(D.ncomp, index_type(-1));
-    D.cv_to_cell.resize(D.ncomp);
+    D.face_conductance.assign(D.ncv, 0.);
+    D.cv_area.assign(D.ncv, 0.);
+    D.cv_capacitance.assign(D.ncv, 0.);
+    D.parent_cv.assign(D.ncv, index_type(-1));
+    D.cv_to_cell.resize(D.ncv);
     for (auto i: make_span(0, D.ncell)) {
-        util::fill(subrange_view(D.cv_to_cell, cell_comp_part[i]), static_cast<index_type>(i));
+        util::fill(subrange_view(D.cv_to_cell, cell_cv_part[i]), static_cast<index_type>(i));
     }
 
-    std::vector<size_type> seg_comp_bounds;
+    std::vector<size_type> seg_cv_bounds;
     for (auto i: make_span(0, D.ncell)) {
         const auto& c = cells[i];
-        compartment_model cell_graph (c);
-        auto cell_comp_ival = cell_comp_part[i];
+        compartment_model cell_graph(c);
+        auto cell_cv_ival = cell_cv_part[i];
 
-        auto cell_comp_base = cell_comp_ival.first;
-        for (auto k: make_span(cell_comp_ival)) {
-            D.parent_cv[k] = cell_graph.parent_index[k-cell_comp_base]+cell_comp_base;
+        auto cell_cv_base = cell_cv_ival.first;
+        for (auto k: make_span(cell_cv_ival)) {
+            D.parent_cv[k] = cell_graph.parent_index[k-cell_cv_base]+cell_cv_base;
         }
 
         // Compartment index range for each segment in this cell.
-        seg_comp_bounds.clear();
-        auto seg_comp_part = make_partition(
-            seg_comp_bounds,
-            transform_view(c.segments(), [](const segment_ptr& s) { return s->num_compartments(); }),
-            cell_comp_base);
+        seg_cv_bounds.clear();
+        auto seg_cv_part = make_partition(
+            seg_cv_bounds,
+            transform_view(make_span(c.num_segments()), [&c](const unsigned s) {
+                if (!c.segment(s)->is_soma() && c.parent(s)->is_soma()) {
+                    return c.segment(s)->num_compartments() + 1;
+                }
+                return c.segment(s)->num_compartments();
+            }),
+            cell_cv_base);
 
-        const auto nseg = seg_comp_part.size();
+        const auto nseg = seg_cv_part.size();
         if (nseg==0) {
             throw arbor_internal_error("fvm_layout: cannot discretrize cell with no segments");
         }
@@ -179,12 +198,9 @@ fvm_discretization fvm_discretize(const std::vector<cable_cell>& cells) {
 
         segment_info soma_info;
 
-        size_type soma_cv = cell_comp_base;
+        size_type soma_cv = cell_cv_base;
         value_type soma_area = math::area_sphere(soma->radius());
 
-        D.cv_area[soma_cv] = soma_area;                  // [µm²]
-        D.cv_capacitance[soma_cv] = soma_area*soma->cm;  // [pF]
-
         soma_info.proximal_cv = soma_cv;
         soma_info.distal_cv = soma_cv;
         soma_info.distal_cv_area = soma_area;
@@ -192,8 +208,8 @@ fvm_discretization fvm_discretize(const std::vector<cable_cell>& cells) {
 
         // Other segments must all be cable segments.
         for (size_type j = 1; j<nseg; ++j) {
-            const auto& seg_comp_ival = seg_comp_part[j];
-            const auto ncomp = seg_comp_ival.second-seg_comp_ival.first;
+            const auto& seg_cv_ival = seg_cv_part[j];
+            const auto ncv = seg_cv_ival.second-seg_cv_ival.first;
 
             segment_info seg_info;
 
@@ -204,19 +220,31 @@ fvm_discretization fvm_discretize(const std::vector<cable_cell>& cells) {
             auto cm = cable->cm;    // [F/m²]
             auto rL = cable->rL;    // [Ω·cm]
 
-            auto divs = div_compartment_integrator(ncomp, cable->radii(), cable->lengths());
+            bool soma_parent = c.parent(j)->as_soma() ? true : false; //segment's parent is a soma
 
-            seg_info.parent_cv = D.parent_cv[seg_comp_ival.first];
-            seg_info.parent_cv_area = divs(0).left.area;
+            auto radii = cable->radii();
+            auto lengths = cable->lengths();
 
-            seg_info.proximal_cv = seg_comp_ival.first;
-            seg_info.distal_cv = seg_comp_ival.second-1;
-            seg_info.distal_cv_area = divs(ncomp-1).right.area;
+            // If segment has soma parent, send soma information to div_compartment_integrator
+            if(soma_parent) {
+                radii.insert(radii.begin(), soma->radius());
+                lengths.insert(lengths.begin(), soma->radius()*2);
+            }
+
+            auto divs = div_compartment_integrator(ncv, radii, lengths, soma_parent);
+
+            seg_info.parent_cv = soma_parent ? seg_cv_ival.first : D.parent_cv[seg_cv_ival.first];
+            seg_info.parent_cv_area = soma_parent ? divs(0).right.area + divs(1).left.area : divs(0).left.area;
+            seg_info.soma_parent = soma_parent;
+
+            seg_info.proximal_cv = soma_parent ? seg_cv_ival.first + 1 : seg_cv_ival.first;
+            seg_info.distal_cv = seg_cv_ival.second-1;
+            seg_info.distal_cv_area = divs(ncv-1).right.area;
 
             D.segments.push_back(seg_info);
 
-            for (auto i: make_span(seg_comp_ival)) {
-                const auto& div = divs(i-seg_comp_ival.first);
+            for (auto i: make_span(seg_cv_ival)) {
+                const auto& div = divs(i-seg_cv_ival.first);
                 auto j = D.parent_cv[i];
 
                 auto h1 = div.left.length;       // [µm]
@@ -238,10 +266,13 @@ fvm_discretization fvm_discretize(const std::vector<cable_cell>& cells) {
                 D.cv_capacitance[i] += ar * cm;  // [pF]
             }
         }
+
+        D.cv_area[soma_cv] = soma_area;                  // [µm²]
+        D.cv_capacitance[soma_cv] = soma_area*soma->cm;  // [pF]
     }
 
     // Number of CVs per cell is exactly number of compartments.
-    D.cell_cv_bounds = std::move(cell_comp_bounds);
+    D.cell_cv_bounds = std::move(cell_cv_bounds);
     return D;
 }
 
diff --git a/arbor/fvm_layout.hpp b/arbor/fvm_layout.hpp
index 90c202203e5fa696b781ada08b999fc1f8fc25c7..a87814ef9396dcdc901edc9f6503cde05f895495 100644
--- a/arbor/fvm_layout.hpp
+++ b/arbor/fvm_layout.hpp
@@ -18,6 +18,7 @@ struct segment_info {
     using value_type = fvm_value_type;
     using index_type = fvm_index_type;
 
+    bool soma_parent = false; // segments parent is soma
     value_type parent_cv_area = 0;
     value_type distal_cv_area = 0;
 
@@ -56,7 +57,7 @@ struct fvm_discretization {
     using index_type = fvm_index_type; // In particular, used for CV indices.
 
     size_type ncell;
-    size_type ncomp;
+    size_type ncv;
 
     // Note: if CV j has no parent, parent_cv[j] = j. TODO: confirm!
     std::vector<index_type> parent_cv;
diff --git a/arbor/fvm_lowered_cell_impl.hpp b/arbor/fvm_lowered_cell_impl.hpp
index 59400d301ea60b513a88608f90ef9ea5724f7cb5..b1b13406ca835ca02b6fe67a9964927d102979e3 100644
--- a/arbor/fvm_lowered_cell_impl.hpp
+++ b/arbor/fvm_lowered_cell_impl.hpp
@@ -375,7 +375,7 @@ void fvm_lowered_cell_impl<B>::initialize(
 
     fvm_discretization D = fvm_discretize(cells);
 
-    std::vector<index_type> cv_to_intdom(D.ncomp);
+    std::vector<index_type> cv_to_intdom(D.ncv);
     std::transform(D.cv_to_cell.begin(), D.cv_to_cell.end(), cv_to_intdom.begin(),
                    [&cell_to_intdom](index_type i){ return cell_to_intdom[i]; });
 
diff --git a/arbor/include/arbor/cable_cell.hpp b/arbor/include/arbor/cable_cell.hpp
index 14be4c2392c863126419f42b372cc60adf23843d..b91a6e11f2434c10535c620a72620c6d375dcbee 100644
--- a/arbor/include/arbor/cable_cell.hpp
+++ b/arbor/include/arbor/cable_cell.hpp
@@ -164,6 +164,7 @@ public:
     bool has_soma() const;
 
     class segment* segment(index_type index);
+    const class segment* parent(index_type index) const;
     const class segment* segment(index_type index) const;
 
     /// access pointer to the soma
diff --git a/test/unit/test_fvm_layout.cpp b/test/unit/test_fvm_layout.cpp
index a7f471c8638de0326767cd532d4ea8c6a301d87b..ae394dd5f0158f6c7f607bca015da74f44c12cb3 100644
--- a/test/unit/test_fvm_layout.cpp
+++ b/test/unit/test_fvm_layout.cpp
@@ -151,7 +151,7 @@ TEST(fvm_layout, topology) {
     //                                   | 14 | 15 | 16 | 17|
 
     EXPECT_EQ(2u, D.ncell);
-    EXPECT_EQ(18u, D.ncomp);
+    EXPECT_EQ(20u, D.ncv);
 
     unsigned nseg = 6;
     EXPECT_EQ(nseg, D.segments.size());
@@ -161,11 +161,11 @@ TEST(fvm_layout, topology) {
     ASSERT_EQ(D.ncell, D.cell_segment_part().size());
     ASSERT_EQ(D.ncell, D.cell_cv_part().size());
 
-    ASSERT_EQ(D.ncomp, D.parent_cv.size());
-    ASSERT_EQ(D.ncomp, D.cv_to_cell.size());
-    ASSERT_EQ(D.ncomp, D.face_conductance.size());
-    ASSERT_EQ(D.ncomp, D.cv_area.size());
-    ASSERT_EQ(D.ncomp, D.cv_capacitance.size());
+    ASSERT_EQ(D.ncv, D.parent_cv.size());
+    ASSERT_EQ(D.ncv, D.cv_to_cell.size());
+    ASSERT_EQ(D.ncv, D.face_conductance.size());
+    ASSERT_EQ(D.ncv, D.cv_area.size());
+    ASSERT_EQ(D.ncv, D.cv_capacitance.size());
 
     // Partitions of CVs and segments by cell:
 
@@ -175,31 +175,32 @@ TEST(fvm_layout, topology) {
     EXPECT_EQ(spair(0, 2),    D.cell_segment_part()[0]);
     EXPECT_EQ(spair(2, nseg), D.cell_segment_part()[1]);
 
-    EXPECT_EQ(ipair(0, 5),       D.cell_cv_part()[0]);
-    EXPECT_EQ(ipair(5, D.ncomp), D.cell_cv_part()[1]);
+    EXPECT_EQ(ipair(0, 6),       D.cell_cv_part()[0]);
+    EXPECT_EQ(ipair(6, D.ncv), D.cell_cv_part()[1]);
 
     // Segment and CV parent relationships:
 
     using ivec = std::vector<fvm_index_type>;
 
-    EXPECT_EQ(ivec({0,0,1,2,3,5,5,6,7,8,9,10,11,12,9,14,15,16}), D.parent_cv);
+    EXPECT_EQ(ivec({0,0,1,2,3,4,6,6,7,8,9,10,11,12,13,14,11,16,17,18}), D.parent_cv);
+
 
     EXPECT_FALSE(D.segments[0].has_parent());
-    EXPECT_EQ(0, D.segments[1].parent_cv);
+    EXPECT_EQ(1, D.segments[1].parent_cv);
 
     EXPECT_FALSE(D.segments[2].has_parent());
-    EXPECT_EQ(5, D.segments[3].parent_cv);
-    EXPECT_EQ(9, D.segments[4].parent_cv);
-    EXPECT_EQ(9, D.segments[5].parent_cv);
+    EXPECT_EQ(7, D.segments[3].parent_cv);
+    EXPECT_EQ(11, D.segments[4].parent_cv);
+    EXPECT_EQ(11, D.segments[5].parent_cv);
 
     // Segment CV ranges (half-open, exclusing parent):
 
     EXPECT_EQ(ipair(0,1), D.segments[0].cv_range());
-    EXPECT_EQ(ipair(1,5), D.segments[1].cv_range());
-    EXPECT_EQ(ipair(5,6), D.segments[2].cv_range());
-    EXPECT_EQ(ipair(6,10), D.segments[3].cv_range());
-    EXPECT_EQ(ipair(10,14), D.segments[4].cv_range());
-    EXPECT_EQ(ipair(14,18), D.segments[5].cv_range());
+    EXPECT_EQ(ipair(2,6), D.segments[1].cv_range());
+    EXPECT_EQ(ipair(6,7), D.segments[2].cv_range());
+    EXPECT_EQ(ipair(8,12), D.segments[3].cv_range());
+    EXPECT_EQ(ipair(12,16), D.segments[4].cv_range());
+    EXPECT_EQ(ipair(16,20), D.segments[5].cv_range());
 
     // CV to cell index:
 
@@ -227,25 +228,27 @@ TEST(fvm_layout, area) {
     }
 
     unsigned n = 4; // compartments per dendritic segment
-    EXPECT_FLOAT_EQ(A[0]+A[1]/(2*n), D.cv_area[0]);
-    EXPECT_FLOAT_EQ(A[1]/n,     D.cv_area[1]);
+    EXPECT_FLOAT_EQ(A[0],       D.cv_area[0]);
+    EXPECT_FLOAT_EQ(A[1]/(2*n), D.cv_area[1]);
     EXPECT_FLOAT_EQ(A[1]/n,     D.cv_area[2]);
     EXPECT_FLOAT_EQ(A[1]/n,     D.cv_area[3]);
-    EXPECT_FLOAT_EQ(A[1]/(2*n), D.cv_area[4]);
+    EXPECT_FLOAT_EQ(A[1]/n,     D.cv_area[4]);
+    EXPECT_FLOAT_EQ(A[1]/(2*n), D.cv_area[5]);
 
-    EXPECT_FLOAT_EQ(A[2]+A[3]/(2*n), D.cv_area[5]);
-    EXPECT_FLOAT_EQ(A[3]/n,     D.cv_area[6]);
-    EXPECT_FLOAT_EQ(A[3]/n,     D.cv_area[7]);
+    EXPECT_FLOAT_EQ(A[2],       D.cv_area[6]);
+    EXPECT_FLOAT_EQ(A[3]/(2*n),     D.cv_area[7]);
     EXPECT_FLOAT_EQ(A[3]/n,     D.cv_area[8]);
-    EXPECT_FLOAT_EQ((A[3]+A[4]+A[5])/(2*n), D.cv_area[9]);
-    EXPECT_FLOAT_EQ(A[4]/n,     D.cv_area[10]);
-    EXPECT_FLOAT_EQ(A[4]/n,     D.cv_area[11]);
+    EXPECT_FLOAT_EQ(A[3]/n,     D.cv_area[9]);
+    EXPECT_FLOAT_EQ(A[3]/n,     D.cv_area[10]);
+    EXPECT_FLOAT_EQ((A[3]+A[4]+A[5])/(2*n), D.cv_area[11]);
     EXPECT_FLOAT_EQ(A[4]/n,     D.cv_area[12]);
-    EXPECT_FLOAT_EQ(A[4]/(2*n), D.cv_area[13]);
-    EXPECT_FLOAT_EQ(A[5]/n,     D.cv_area[14]);
-    EXPECT_FLOAT_EQ(A[5]/n,     D.cv_area[15]);
+    EXPECT_FLOAT_EQ(A[4]/n,     D.cv_area[13]);
+    EXPECT_FLOAT_EQ(A[4]/n,     D.cv_area[14]);
+    EXPECT_FLOAT_EQ(A[4]/(2*n), D.cv_area[15]);
     EXPECT_FLOAT_EQ(A[5]/n,     D.cv_area[16]);
-    EXPECT_FLOAT_EQ(A[5]/(2*n), D.cv_area[17]);
+    EXPECT_FLOAT_EQ(A[5]/n,     D.cv_area[17]);
+    EXPECT_FLOAT_EQ(A[5]/n,     D.cv_area[18]);
+    EXPECT_FLOAT_EQ(A[5]/(2*n), D.cv_area[19]);
 
     // Confirm proportional allocation of surface capacitance:
 
@@ -258,14 +261,11 @@ TEST(fvm_layout, area) {
     double cm3 = cells[1].segment(3)->cm;
 
     double c = A[3]/(2*n)*cm1+A[4]/(2*n)*cm2+A[5]/(2*n)*cm3;
-    EXPECT_FLOAT_EQ(c, D.cv_capacitance[9]);
-
-    // CV 5 should be a weighted sum of soma and first segment
-    // capacitcance from cell 1.
+    EXPECT_FLOAT_EQ(c, D.cv_capacitance[11]);
 
     double cm0 = cells[1].soma()->cm;
-    c = A[2]*cm0+A[3]/(2*n)*cm1;
-    EXPECT_FLOAT_EQ(c, D.cv_capacitance[5]);
+    c = A[2]*cm0;
+    EXPECT_FLOAT_EQ(c, D.cv_capacitance[6]);
 
     // Confirm face conductance within a constant diameter
     // equals a/h·1/rL where a is the cross sectional
@@ -280,7 +280,7 @@ TEST(fvm_layout, area) {
     double g = a/h/cable->rL; // [µm·S/cm]
     g *= 100; // [µS]
 
-    EXPECT_FLOAT_EQ(g, D.face_conductance[11]);
+    EXPECT_FLOAT_EQ(g, D.face_conductance[13]);
 }
 
 TEST(fvm_layout, mech_index) {
@@ -308,20 +308,20 @@ TEST(fvm_layout, mech_index) {
     // Proportional area contrib: soma area/CV area.
 
     EXPECT_EQ(mechanismKind::density, hh_config.kind);
-    EXPECT_EQ(ivec({0,5}), hh_config.cv);
+    EXPECT_EQ(ivec({0,6}), hh_config.cv);
 
-    fvec norm_area({area(cells[0].soma())/D.cv_area[0], area(cells[1].soma())/D.cv_area[5]});
+    fvec norm_area({area(cells[0].soma())/D.cv_area[0], area(cells[1].soma())/D.cv_area[6]});
     EXPECT_TRUE(testing::seq_almost_eq<double>(norm_area, hh_config.norm_area));
 
     // Three expsyn synapses, two 0.4 along segment 1, and one 0.4 along segment 5.
     // These two synapses can be coalesced into 1 synapse
     // 0.4 along => second (non-parent) CV for segment.
 
-    EXPECT_EQ(ivec({2, 15}), expsyn_config.cv);
+    EXPECT_EQ(ivec({3, 17}), expsyn_config.cv);
 
     // One exp2syn synapse, 0.4 along segment 4.
 
-    EXPECT_EQ(ivec({11}), exp2syn_config.cv);
+    EXPECT_EQ(ivec({13}), exp2syn_config.cv);
 
     // There should be a K and Na ion channel associated with each
     // hh mechanism node.
@@ -330,8 +330,8 @@ TEST(fvm_layout, mech_index) {
     ASSERT_EQ(1u, M.ions.count("k"s));
     EXPECT_EQ(0u, M.ions.count("ca"s));
 
-    EXPECT_EQ(ivec({0,5}), M.ions.at("na"s).cv);
-    EXPECT_EQ(ivec({0,5}), M.ions.at("k"s).cv);
+    EXPECT_EQ(ivec({0,6}), M.ions.at("na"s).cv);
+    EXPECT_EQ(ivec({0,6}), M.ions.at("k"s).cv);
 }
 
 TEST(fvm_layout, coalescing_synapses) {
@@ -371,7 +371,7 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 2, 3, 4}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 3, 4, 5}), expsyn_config.cv);
         EXPECT_EQ(ivec({1, 1, 1, 1}), expsyn_config.multiplicity);
     }
     {
@@ -387,17 +387,16 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 3}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 4}), expsyn_config.cv);
         EXPECT_EQ(ivec({1, 1}), expsyn_config.multiplicity);
 
         auto &exp2syn_config = M.mechanisms.at("exp2syn");
-        EXPECT_EQ(ivec({2, 4}), exp2syn_config.cv);
+        EXPECT_EQ(ivec({3, 5}), exp2syn_config.cv);
         EXPECT_EQ(ivec({1, 1}), exp2syn_config.multiplicity);
     }
     {
         cable_cell cell = make_cell_ball_and_stick();
 
-        // Add synapses of two varieties.
         cell.add_synapse({1, 0.3}, "expsyn");
         cell.add_synapse({1, 0.5}, "expsyn");
         cell.add_synapse({1, 0.7}, "expsyn");
@@ -407,7 +406,7 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_no_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 2, 3, 4}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 3, 4, 5}), expsyn_config.cv);
         EXPECT_TRUE(expsyn_config.multiplicity.empty());
     }
     {
@@ -423,11 +422,11 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_no_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 3}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 4}), expsyn_config.cv);
         EXPECT_TRUE(expsyn_config.multiplicity.empty());
 
         auto &exp2syn_config = M.mechanisms.at("exp2syn");
-        EXPECT_EQ(ivec({2, 4}), exp2syn_config.cv);
+        EXPECT_EQ(ivec({3, 5}), exp2syn_config.cv);
         EXPECT_TRUE(exp2syn_config.multiplicity.empty());
     }
     {
@@ -443,7 +442,7 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 3}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 4}), expsyn_config.cv);
         EXPECT_EQ(ivec({2, 2}), expsyn_config.multiplicity);
     }
     {
@@ -459,7 +458,7 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 1, 3}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 2, 4}), expsyn_config.cv);
         EXPECT_EQ(ivec({2, 1, 1}), expsyn_config.multiplicity);
         EXPECT_EQ(fvec({0, 0.1, 0.1}), expsyn_config.param_values[0].second);
         EXPECT_EQ(fvec({0.2, 0.2, 0.2}), expsyn_config.param_values[1].second);
@@ -481,7 +480,7 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 1, 3, 3}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 2, 4, 4}), expsyn_config.cv);
         EXPECT_EQ(ivec({4, 6, 5, 7, 0, 2, 1, 3}), expsyn_config.target);
         EXPECT_EQ(ivec({2, 2, 2, 2}), expsyn_config.multiplicity);
         EXPECT_EQ(fvec({0, 1, 0, 1}), expsyn_config.param_values[0].second);
@@ -506,14 +505,14 @@ TEST(fvm_layout, coalescing_synapses) {
         fvm_mechanism_data M = fvm_build_mechanism_data(gprop_coalesce, {cell}, D);
 
         auto &expsyn_config = M.mechanisms.at("expsyn");
-        EXPECT_EQ(ivec({1, 1}), expsyn_config.cv);
+        EXPECT_EQ(ivec({2, 2}), expsyn_config.cv);
         EXPECT_EQ(ivec({0, 2, 5, 3}), expsyn_config.target);
         EXPECT_EQ(ivec({3, 1}), expsyn_config.multiplicity);
         EXPECT_EQ(fvec({1, 5}), expsyn_config.param_values[0].second);
         EXPECT_EQ(fvec({2, 1}), expsyn_config.param_values[1].second);
 
         auto &exp2syn_config = M.mechanisms.at("exp2syn");
-        EXPECT_EQ(ivec({1, 1, 3, 3}), exp2syn_config.cv);
+        EXPECT_EQ(ivec({2, 2, 4, 4}), exp2syn_config.cv);
         EXPECT_EQ(ivec({4, 1, 7, 8, 6, 9}), exp2syn_config.target);
         EXPECT_EQ(ivec({1, 1, 2, 2}), exp2syn_config.multiplicity);
         EXPECT_EQ(fvec({1, 4, 2, 2}), exp2syn_config.param_values[0].second);
@@ -671,7 +670,7 @@ TEST(fvm_layout, density_norm_area) {
         seg.add_mechanism(hh);
     }
 
-    int ncv = 10;
+    int ncv = 11; //ncomp + 1
     std::vector<double> expected_gkbar(ncv, dflt_gkbar);
     std::vector<double> expected_gl(ncv, dflt_gl);
 
@@ -683,28 +682,30 @@ TEST(fvm_layout, density_norm_area) {
     auto seg2_divs = div_by_ends(segs[2]->as_cable());
     auto seg3_divs = div_by_ends(segs[3]->as_cable());
 
-    // CV 0: mix of soma and left of segment 1
-    expected_gl[0] = wmean(soma_area, dflt_gl, seg1_divs(0).left.area, seg1_gl);
-
+    // CV 0: soma
+    // CV1: left of segment 1
+    expected_gl[0] = dflt_gl;
     expected_gl[1] = seg1_gl;
+
     expected_gl[2] = seg1_gl;
+    expected_gl[3] = seg1_gl;
 
-    // CV 3: mix of right of segment 1 and left of segments 2 and 3.
-    expected_gkbar[3] = wmean(seg1_divs(2).right.area, dflt_gkbar, seg2_divs(0).left.area, seg2_gkbar, seg3_divs(0).left.area, seg3_gkbar);
-    expected_gl[3] = wmean(seg1_divs(2).right.area, seg1_gl, seg2_divs(0).left.area, dflt_gl, seg3_divs(0).left.area, seg3_gl);
+    // CV 4: mix of right of segment 1 and left of segments 2 and 3.
+    expected_gkbar[4] = wmean(seg1_divs(2).right.area, dflt_gkbar, seg2_divs(0).left.area, seg2_gkbar, seg3_divs(0).left.area, seg3_gkbar);
+    expected_gl[4] = wmean(seg1_divs(2).right.area, seg1_gl, seg2_divs(0).left.area, dflt_gl, seg3_divs(0).left.area, seg3_gl);
 
-    // CV 4-6: just segment 2
-    expected_gkbar[4] = seg2_gkbar;
+    // CV 5-7: just segment 2
     expected_gkbar[5] = seg2_gkbar;
     expected_gkbar[6] = seg2_gkbar;
+    expected_gkbar[7] = seg2_gkbar;
 
-    // CV 7-9: just segment 3
-    expected_gkbar[7] = seg3_gkbar;
+    // CV 8-10: just segment 3
     expected_gkbar[8] = seg3_gkbar;
     expected_gkbar[9] = seg3_gkbar;
-    expected_gl[7] = seg3_gl;
+    expected_gkbar[10] = seg3_gkbar;
     expected_gl[8] = seg3_gl;
     expected_gl[9] = seg3_gl;
+    expected_gl[10] = seg3_gl;
 
     cable_cell_global_properties gprop;
     fvm_discretization D = fvm_discretize(cells);
@@ -717,12 +718,14 @@ TEST(fvm_layout, density_norm_area) {
 
     double area_relerr = 10*std::numeric_limits<double>::epsilon();
     EXPECT_TRUE(testing::near_relative(D.cv_area[0],
-        soma_area+seg1_divs(0).left.area, area_relerr));
+        soma_area, area_relerr));
     EXPECT_TRUE(testing::near_relative(D.cv_area[1],
+        seg1_divs(0).left.area, area_relerr));
+    EXPECT_TRUE(testing::near_relative(D.cv_area[2],
         seg1_divs(0).right.area+seg1_divs(1).left.area, area_relerr));
-    EXPECT_TRUE(testing::near_relative(D.cv_area[3],
+    EXPECT_TRUE(testing::near_relative(D.cv_area[4],
         seg1_divs(2).right.area+seg2_divs(0).left.area+seg3_divs(0).left.area, area_relerr));
-    EXPECT_TRUE(testing::near_relative(D.cv_area[6],
+    EXPECT_TRUE(testing::near_relative(D.cv_area[7],
         seg2_divs(2).right.area, area_relerr));
 
     // Grab the HH parameters from the mechanism.
@@ -803,11 +806,11 @@ TEST(fvm_layout, ion_weights) {
     };
 
     ivec expected_ion_cv[] = {
-        {0}, {0, 1, 2}, {1, 2, 3}, {0, 1, 2, 3}, {1, 3}
+        {0}, {0, 2, 3}, {2, 3, 4}, {0, 1, 2, 3, 4}, {2, 4}
     };
 
     fvec expected_iconc_norm_area[] = {
-        {1./3}, {1./3, 1./2, 0.}, {1./4, 0., 0.}, {0., 0., 0., 0.}, {3./4, 0.}
+        {0.}, {0., 1./2, 0.}, {1./4, 0., 0.}, {0., 0., 0., 0., 0.}, {3./4, 0.}
     };
 
     cable_cell_global_properties gprop;
@@ -828,6 +831,7 @@ TEST(fvm_layout, ion_weights) {
         auto& ca = M.ions.at("ca"s);
 
         EXPECT_EQ(expected_ion_cv[run], ca.cv);
+
         EXPECT_TRUE(testing::seq_almost_eq<fvm_value_type>(expected_iconc_norm_area[run], ca.iconc_norm_area));
 
         EXPECT_TRUE(util::all_of(ca.econc_norm_area, [](fvm_value_type v) { return v==1.; }));
diff --git a/test/unit/test_fvm_lowered.cpp b/test/unit/test_fvm_lowered.cpp
index e6d574630b1af13dfea47c414c1e2f9c91d77ad0..7bd1b18cea57dddbb1b5d188178ff9bf44244551 100644
--- a/test/unit/test_fvm_lowered.cpp
+++ b/test/unit/test_fvm_lowered.cpp
@@ -227,7 +227,7 @@ TEST(fvm_lowered, matrix_init)
     fvcell.initialize({0}, cable1d_recipe(cell), cell_to_intdom, targets, probe_map);
 
     auto& J = fvcell.*private_matrix_ptr;
-    EXPECT_EQ(J.size(), 11u);
+    EXPECT_EQ(J.size(), 12u);
 
     // Test that the matrix is initialized with sensible values
 
@@ -315,7 +315,7 @@ TEST(fvm_lowered, stimulus) {
     // delay     |   5  |    1
     // duration  |  80  |    2
     // amplitude | 0.3  |  0.1
-    // CV        |   4  |    0
+    // CV        |   5  |    0
 
     execution_context context;
 
@@ -326,7 +326,7 @@ TEST(fvm_lowered, stimulus) {
     cells[0].add_stimulus({0,0.5}, {1., 2.,  0.1});
 
     const fvm_size_type soma_cv = 0u;
-    const fvm_size_type tip_cv = 4u;
+    const fvm_size_type tip_cv = 5u;
 
     // now we have two stims :
     //
@@ -683,10 +683,10 @@ TEST(fvm_lowered, weighted_write_ion) {
     const double con_int = 80;
     const double con_ext = 120;
 
-    // Ca ion reader test_kinlva on CV 1 and 2 via segment 2:
+    // Ca ion reader test_kinlva on CV 2 and 3 via segment 2:
     c.segments()[2] ->add_mechanism("test_kinlva");
 
-    // Ca ion writer test_ca on CV 1 and 3 via segment 3:
+    // Ca ion writer test_ca on CV 2 and 4 via segment 3:
     c.segments()[3] ->add_mechanism("test_ca");
 
     std::vector<target_handle> targets;
@@ -703,7 +703,7 @@ TEST(fvm_lowered, weighted_write_ion) {
     ion.init_concentration();
 
     std::vector<unsigned> ion_nodes = util::assign_from(ion.node_index_);
-    std::vector<unsigned> expected_ion_nodes = {1, 2, 3};
+    std::vector<unsigned> expected_ion_nodes = {2, 3, 4};
     EXPECT_EQ(expected_ion_nodes, ion_nodes);
 
     std::vector<double> ion_iconc_weights = util::assign_from(ion.weight_Xi_);
@@ -785,11 +785,11 @@ TEST(fvm_lowered, gj_coords_simple) {
         return g * 1e3 / D.cv_area[i];
     };
 
-    EXPECT_EQ(pair({4,8}), GJ[0].loc);
-    EXPECT_EQ(weight(0.5, 4), GJ[0].weight);
+    EXPECT_EQ(pair({5,10}), GJ[0].loc);
+    EXPECT_EQ(weight(0.5, 5), GJ[0].weight);
 
-    EXPECT_EQ(pair({8,4}), GJ[1].loc);
-    EXPECT_EQ(weight(0.5, 8), GJ[1].weight);
+    EXPECT_EQ(pair({10,5}), GJ[1].loc);
+    EXPECT_EQ(weight(0.5, 10), GJ[1].weight);
 }
 
 TEST(fvm_lowered, gj_coords_complex) {
@@ -895,10 +895,10 @@ TEST(fvm_lowered, gj_coords_complex) {
         return g * 1e3 / D.cv_area[i];
     };
 
-    std::vector<pair> expected_loc = {{4, 14}, {4,11}, {2,21}, {14, 4}, {11,4} ,{8,28}, {6, 24}, {21,2}, {28,8}, {24, 6}};
+    std::vector<pair> expected_loc = {{5, 16}, {5,13}, {3,24}, {16, 5}, {13,5} ,{10,31}, {8, 27}, {24,3}, {31,10}, {27, 8}};
     std::vector<double> expected_weight = {
-            weight(0.03, 4), weight(0.04, 4), weight(0.01, 2), weight(0.03, 14), weight(0.04, 11),
-            weight(0.02, 8), weight(0.01, 6), weight(0.01, 21), weight(0.02, 28), weight(0.01, 24)
+            weight(0.03, 5), weight(0.04, 5), weight(0.01, 3), weight(0.03, 16), weight(0.04, 13),
+            weight(0.02, 10), weight(0.01, 8), weight(0.01, 24), weight(0.02, 31), weight(0.01, 27)
     };
 
     for (unsigned i = 0; i < GJ.size(); i++) {
@@ -912,7 +912,6 @@ TEST(fvm_lowered, gj_coords_complex) {
         }
         EXPECT_TRUE(found);
     }
-    std::cout << std::endl;
 }
 
 TEST(fvm_lowered, cell_group_gj) {